1
# -*- coding: utf-8 -*-
3
# Network detection library for Python (NetworkManager implementation).
4
# Copyright (C) 2009, 2010 Mark Lee <avant-wn@lazymalevolence.com>
6
# This library is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU Lesser General Public
8
# License as published by the Free Software Foundation; either
9
# version 2.1 of the License, or (at your option) any later version.
11
# This library is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
# Lesser General Public License for more details.
16
# You should have received a copy of the GNU Lesser General Public
17
# License along with this library; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
from dbus.mainloop.glib import DBusGMainLoop
24
DBusGMainLoop(set_as_default=True)
26
HAS_WATCH_NAME_OWNER = (dbus.version >= (0, 81, 0))
28
if not HAS_WATCH_NAME_OWNER:
30
def timeout_add_seconds(interval, callback):
31
if hasattr(gobject, 'timeout_add_seconds'):
32
gobject.timeout_add_seconds(interval, callback)
34
gobject.timeout_add(interval * 1000, callback)
36
def watch_name_owner(bus, bus_name, callback):
38
if bus.name_has_owner(bus_name):
44
timeout_add_seconds(1, check_for_name)
45
dbus.SystemBus.watch_name_owner = watch_name_owner
47
NM_BUS_NAME = 'org.freedesktop.NetworkManager'
48
NM_OBJECT_PATH = '/org/freedesktop/NetworkManager'
49
DBUS_PROPS_IFACE_NAME = 'org.freedesktop.DBus.Properties'
50
NM_IFACE_NAME = 'org.freedesktop.NetworkManager'
51
NM_ACTIVE_CONNECTION_IFACE_NAME = \
52
'org.freedesktop.NetworkManager.Connection.Active'
56
NM_STATE_CONNECTING = 2
57
NM_STATE_CONNECTED = 3
58
NM_STATE_DISCONNECTED = 4
60
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
61
NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
62
NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
65
class DObject(object):
66
'''Wrapper for DBus object proxies.'''
68
def initialize(self, bus_name, object_path, iface_name):
69
self.proxy = self.bus.get_object(bus_name, object_path)
70
self.iface_name = iface_name
71
self.iface = dbus.Interface(self.proxy, dbus_interface=iface_name)
72
self.dbus_iface = dbus.Interface(self.proxy,
73
dbus_interface=DBUS_PROPS_IFACE_NAME)
75
def __getattr__(self, name):
76
return self.dbus_iface.Get(self.iface_name, name)
79
class ActiveConnection(DObject):
80
'''Wraps an active connection proxy object.'''
82
def __init__(self, bus, object_path):
84
self.initialize(NM_BUS_NAME, object_path,
85
NM_ACTIVE_CONNECTION_IFACE_NAME)
88
class Detector(DObject, gobject.GObject):
89
'''Detects that a network connection exists, according to NetworkManager.
93
'connected': (gobject.SIGNAL_RUN_FIRST, None, ()),
94
'disconnected': (gobject.SIGNAL_RUN_FIRST, None, ()),
95
'state_changed': (gobject.SIGNAL_RUN_FIRST, None, (int,)),
99
super(Detector, self).__init__()
100
self.__connection_state = None
101
self.bus = dbus.SystemBus()
102
if self.bus.name_has_owner(NM_BUS_NAME):
105
# requires dbus-python >= 0.81.0
110
self.bus.watch_name_owner(NM_BUS_NAME, on_watch)
112
def initialize(self):
113
super(Detector, self).initialize(NM_BUS_NAME, NM_OBJECT_PATH,
115
self.iface.connect_to_signal('StateChanged', self.__on_state_changed)
116
self.__on_state_changed(self.State)
118
def __getattr__(self, name):
119
value = super(Detector, self).__getattr__(name)
120
if name == 'ActiveConnections':
121
value = [ActiveConnection(self.bus, path) for path in value]
124
def __on_state_changed(self, state):
125
'''Determines the state of each "active" connection to determine if
126
the computer is connected to a network, as the state property is too
129
active_connections = self.ActiveConnections
130
real_conns = len([x for x in active_connections
131
if x.State == NM_ACTIVE_CONNECTION_STATE_ACTIVATED])
132
connected = real_conns > 0
133
if connected != self.__connection_state:
134
self.__connection_state = connected
136
self.emit('connected')
138
self.emit('disconnected')
139
self.emit('state_changed', state)
143
'''The way to determine whether the computer is connected to a
144
network, without having to deal with signals.
146
return self.__connection_state