diff --git a/plinth/modules/network/network.py b/plinth/modules/network/network.py
index 2dd02c020..2ebe8f2a7 100644
--- a/plinth/modules/network/network.py
+++ b/plinth/modules/network/network.py
@@ -15,6 +15,7 @@
# along with this program. If not, see .
#
+from dbus.exceptions import DBusException
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse_lazy
@@ -51,6 +52,17 @@ def init():
def index(request):
"""Show connection list."""
connections = []
+ active = []
+
+ for conn in NetworkManager.NetworkManager.ActiveConnections:
+ try:
+ settings = conn.Connection.GetSettings()['connection']
+ except DBusException:
+ # DBusException can be thrown here if the index is quickly loaded
+ # after a connection is deactivated.
+ continue
+ active.append(settings['id'])
+
for conn in NetworkManager.Settings.ListConnections():
settings = conn.GetSettings()['connection']
# Display a friendly type name if known.
@@ -59,13 +71,75 @@ def index(request):
connections.append({
'name': settings['id'],
'id': urllib.parse.quote_plus(settings['id']),
- 'type': conn_type
+ 'type': conn_type,
+ 'is_active': settings['id'] in active,
})
+ connections.sort(key=lambda x: x['is_active'], reverse=True)
+
return TemplateResponse(request, 'connections_list.html',
{'title': _('Network Connections'),
'connections': connections})
+@login_required
+def activate(request, conn_id):
+ """Activate the connection."""
+ name = urllib.parse.unquote_plus(conn_id)
+
+ # Find the connection
+ connections = NetworkManager.Settings.ListConnections()
+ connections = dict([(x.GetSettings()['connection']['id'], x)
+ for x in connections])
+ conn = connections[name]
+
+ # Find a suitable device
+ ctype = conn.GetSettings()['connection']['type']
+ if ctype == 'vpn':
+ for dev in NetworkManager.NetworkManager.GetDevices():
+ if (dev.State == NetworkManager.NM_DEVICE_STATE_ACTIVATED
+ and dev.Managed):
+ break
+ else:
+ messages.error(
+ request,
+ _('Failed to activate connection: '
+ 'No active, managed device found'))
+ return redirect(reverse_lazy('network:index'))
+ else:
+ dtype = {
+ '802-11-wireless': NetworkManager.NM_DEVICE_TYPE_WIFI,
+ '802-3-ethernet': NetworkManager.NM_DEVICE_TYPE_ETHERNET,
+ 'gsm': NetworkManager.NM_DEVICE_TYPE_MODEM,
+ }.get(ctype, ctype)
+
+ for dev in NetworkManager.NetworkManager.GetDevices():
+ if (dev.DeviceType == dtype
+ and dev.State == NetworkManager.NM_DEVICE_STATE_DISCONNECTED):
+ break
+ else:
+ messages.error(
+ request,
+ _('Failed to activate connection: '
+ 'No suitable and available %s device found' % ctype))
+ return redirect(reverse_lazy('network:index'))
+
+ NetworkManager.NetworkManager.ActivateConnection(conn, dev, "/")
+ messages.success(request, _('Activated connection %s.') % name)
+ return redirect(reverse_lazy('network:index'))
+
+
+@login_required
+def deactivate(request, conn_id):
+ """Deactivate the connection."""
+ name = urllib.parse.unquote_plus(conn_id)
+ active = NetworkManager.NetworkManager.ActiveConnections
+ active = dict([(x.Connection.GetSettings()['connection']['id'], x)
+ for x in active])
+ NetworkManager.NetworkManager.DeactivateConnection(active[name])
+ messages.success(request, _('Deactivated connection %s.') % name)
+ return redirect(reverse_lazy('network:index'))
+
+
@login_required
def delete(request, conn_id):
"""Handle deleting connections, showing a confirmation dialog first.
@@ -81,7 +155,7 @@ def delete(request, conn_id):
conn.Delete()
messages.success(request, _('Connection %s deleted.') % name)
return redirect(reverse_lazy('network:index'))
- messages.failure(
+ messages.error(
request,
_('Failed to delete connection %s: not found.') % name)
return redirect(reverse_lazy('network:index'))
diff --git a/plinth/modules/network/templates/connections_list.html b/plinth/modules/network/templates/connections_list.html
index 5804b274c..d8ff4f7de 100644
--- a/plinth/modules/network/templates/connections_list.html
+++ b/plinth/modules/network/templates/connections_list.html
@@ -24,7 +24,11 @@