The unified diff between revisions [05448376..] and [aea25ad8..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "debian/control"
# from [effac33cf35748260669d0156d71229d2f6c9baa]
# to [4cf2ceb21877b0647eac61b1f3d270b8d797325f]
#
# patch "interapplet.py"
# from [9544599caa57f2b5853b7faa0b4b69feff12e0c6]
# to [c3907cff0e9d8395fae3790af1820d9cb9f2aca8]
#
============================================================
--- debian/control effac33cf35748260669d0156d71229d2f6c9baa
+++ debian/control 4cf2ceb21877b0647eac61b1f3d270b8d797325f
@@ -8,6 +8,7 @@ Depends: python-gtk2 (>= 2.6.0), python2
Package: interapplet
Architecture: all
Depends: python-gtk2 (>= 2.6.0), python2.4-gamin (>= 0.0.26),
- python-gnome2 (>= 2.10.0), python-gnome2-extras (>= 2.10.0), gksu
+ python-gnome2 (>= 2.10.0), python-gnome2-extras (>= 2.10.0),
+ python2.4-dbus (>= 0.23), gksu
Description: Interface configuration applet for GNOME
Written in Python and providing a GNOME panel applet.
============================================================
--- interapplet.py 9544599caa57f2b5853b7faa0b4b69feff12e0c6
+++ interapplet.py c3907cff0e9d8395fae3790af1820d9cb9f2aca8
@@ -27,6 +27,7 @@ import gamin
import gnomeapplet
import gobject
import gamin
+import dbus
import popen2
import fcntl
@@ -58,21 +59,12 @@ class InterfaceInfo:
self.mappings = set()
self.mappable = set()
- # FIXME this will never update, which is awful
- exclude = set(('gre0', 'lo', 'tunl0', 'dummy0'))
- for line in open('/proc/net/dev'):
- m = re.match(r' *([^:]+):', line)
- if m:
- ifname = m.groups()[0].strip()
- if ifname not in exclude: self.mappable.add(ifname)
-
- fd = open(file)
-
mapping = re.compile(r'^\s?mapping\s+([\w_:]+)')
map = re.compile(r'^\s?map\s+([\w_]+)\s+([\w_]+)')
auto = re.compile(r'^\s?auto[\s^]')
iface = re.compile(r'^\s?iface\s+([\w_]+)\s+([\w_]+)\s+([\w_]+)')
+ fd = open(file)
for line in fd:
m = mapping.match(line)
if m:
@@ -94,6 +86,53 @@ class InterfaceState:
m = mapping.match(line)
if m: self.state[m.groups()[0]] = m.groups()[1]
+class DeviceInfo:
+ def __init__(self, change_cb):
+ self.change_cb = change_cb
+ self.udi_to_device = {}
+
+ self.bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
+ self.hal_service = self.bus.get_service("org.freedesktop.Hal")
+ self.hal_manager = self.hal_service.get_object("/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager")
+ network_devices = self.hal_manager.FindDeviceByCapability('net')
+ for device_udi in network_devices:
+ self.add_by_udi(device_udi)
+ self.bus.add_signal_receiver(self.device_change_cb,
+ "DeviceAdded",
+ "org.freedesktop.Hal.Manager",
+ "org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager")
+ self.bus.add_signal_receiver(self.device_change_cb,
+ "DeviceRemoved",
+ "org.freedesktop.Hal.Manager",
+ "org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager")
+ def add_by_udi(self, udi):
+ if not self.udi_to_device.has_key(udi):
+ device = self.hal_service.get_object(udi, "org.freedesktop.Hal.Device")
+ category = device.GetProperty('info.category')
+ if not category.startswith('net.'): return
+ product = device.GetProperty('info.product')
+ interface = device.GetProperty('net.interface')
+ self.udi_to_device[udi] = ("%s: %s" % (interface, product), interface)
+ def remove_by_udi(self, udi):
+ if self.udi_to_device.has_key(udi):
+ self.udi_to_device.pop(udi)
+ def get_devices(self):
+ return self.udi_to_device.values()
+ def device_change_cb(self, dbus_if, dbus_member, dbus_svc, dbus_obj_path, dbus_message):
+ if dbus_member == "DeviceAdded":
+ [device_udi] = dbus_message.get_args_list()
+ print "DeviceAdded", device_udi
+ self.add_by_udi(device_udi)
+ self.change_cb()
+ elif dbus_member == "DeviceRemoved":
+ [device_udi] = dbus_message.get_args_list()
+ print "DeviceRemoved", device_udi
+ self.remove_by_udi(device_udi)
+ self.change_cb()
+
class InterfaceApplet(gnomeapplet.Applet):
def __init__(self, applet, iid):
self.run_queue = []
@@ -114,7 +153,7 @@ class InterfaceApplet(gnomeapplet.Applet
self.log_window = gtk.Window()
self.log_window.resize(600,150)
- self.log_window.set_title("Interface Applet Log")
+ self.log_window.set_title("InterApplet Log")
self.scrolled_window = gtk.ScrolledWindow()
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.text_view = gtk.TextView()
@@ -132,11 +171,8 @@ class InterfaceApplet(gnomeapplet.Applet
# load interface state and update it using gamin
self.if_info = InterfaceInfo(interfaces_file)
self.if_state = InterfaceState(ifstate_file)
+ self.device_info = DeviceInfo(self.devices_changed_cb)
self.menu = self.build_menu()
- # disabled by [GMB]
- # causes irrating prompt when first starting program, and is probably
- # not needed.
- #self.init_state_files()
self.mon = gamin.WatchMonitor()
self.mon.watch_file(ifstate_file, self.interfaces_changed_cb)
self.mon.watch_file(interfaces_file, self.interfaces_changed_cb)
@@ -241,13 +277,11 @@ class InterfaceApplet(gnomeapplet.Applet
command = '/sbin/ifup ' + pipes.quote(int)
if mapping != None: command += "=" + pipes.quote(mapping)
self.run_command("/usr/bin/gksudo %s" % (pipes.quote(command)))
- def init_state_files(self):
- for mapping in self.if_state.state:
- if not mapping in self.if_info.mappings: continue
- self.update_state(mapping, self.if_state.state[mapping])
def mon_cb(self, source, condition, user_data=None):
self.mon.handle_events()
return True
+ def devices_changed_cb(self):
+ self.menu = self.build_menu()
def interfaces_changed_cb(self, path, event):
# we only care about the file getting created, or the file
# being modified
@@ -336,17 +370,17 @@ class InterfaceApplet(gnomeapplet.Applet
return menu
def build_menu(self):
menu = gtk.Menu()
- mappings = list(self.if_info.mappable)
- mappings.sort()
+ mappings = list(self.device_info.get_devices())
+ mappings.sort(lambda x, y: cmp(x[0], y[0]))
nin = gtk.Image()
if len(mappings) == 0:
item = gtk.ImageMenuItem("No mapable interfaces found.")
item.set_sensitive(False)
item.show()
menu.append(item)
- for mapping in mappings:
+ for description, mapping in mappings:
self.build_mapping_menu(mapping)
- item = gtk.ImageMenuItem(mapping)
+ item = gtk.ImageMenuItem(description)
item.set_submenu(self.build_mapping_menu(mapping))
item.show()
menu.append(item)