1
0
mirror of https://github.com/gryf/wicd.git synced 2025-12-20 21:08:06 +01:00

- Make the GUI behave better when a disconnect button is pushed.

- Move some of the libnotify logic to guiutil.py and add support for displaying some error messages in a libnotify pop-up.
- Apply some patches provided by sunseraph.  Tweak to the channel regex and checking for a valid AP bssid when monitoring a wireless connection.  Set essid, bssid, and channel in separate calls to iwconfig.
- Add caching for ifconfig and iwconfig results in wnettools.py.  That way we're not needlessly calling the same command a bunch of times in a short period of time (2 seconds).  This removes the need for us to pass around iwconfig/ifconfig output elsewhere, though I've left it in for now.
- Remove unneeded BackendManager instance from networking.py
- Fix last used wired networking autoconnection method
This commit is contained in:
Dan O'Reilly
2009-05-22 15:40:35 -04:00
parent bb7563a4af
commit c334cac1c8
9 changed files with 134 additions and 56 deletions

View File

@@ -286,7 +286,11 @@ class appGui(object):
def disconnect_all(self, widget=None): def disconnect_all(self, widget=None):
""" Disconnects from any active network. """ """ Disconnects from any active network. """
daemon.Disconnect() def handler(*args):
gobject.idle_add(self.network_list.set_sensitive, True)
self.network_list.set_sensitive(False)
daemon.Disconnect(reply_handler=handler, error_handler=handler)
def about_dialog(self, widget, event=None): def about_dialog(self, widget, event=None):
""" Displays an about dialog. """ """ Displays an about dialog. """
@@ -649,19 +653,41 @@ class appGui(object):
return False return False
return True return True
def _wait_for_connect_thread_start(self):
self.wTree.get_widget("progressbar").pulse()
if not self._connect_thread_started:
return True
else:
misc.timeout_add(2, self.update_statusbar)
self.update_statusbar()
return False
def connect(self, widget, nettype, networkid, networkentry): def connect(self, widget, nettype, networkid, networkentry):
""" Initiates the connection process in the daemon. """ """ Initiates the connection process in the daemon. """
def handler(*args):
self._connect_thread_started = True
cancel_button = self.wTree.get_widget("cancel_button") cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(True) cancel_button.set_sensitive(True)
self.network_list.set_sensitive(False)
if self.statusID:
gobject.idle_add(self.status_bar.remove, 1, self.statusID)
gobject.idle_add(self.set_status, language["disconnecting_active"])
gobject.idle_add(self.status_area.show_all)
self.wait_for_events()
self._connect_thread_started = False
if nettype == "wireless": if nettype == "wireless":
if not self.check_encryption_valid(networkid, if not self.check_encryption_valid(networkid,
networkentry.advanced_dialog): networkentry.advanced_dialog):
self.edit_advanced(None, None, nettype, networkid, networkentry) self.edit_advanced(None, None, nettype, networkid, networkentry)
return False return False
wireless.ConnectWireless(networkid) wireless.ConnectWireless(networkid, reply_handler=handler,
error_handler=handler)
elif nettype == "wired": elif nettype == "wired":
wired.ConnectWired() wired.ConnectWired(reply_handler=handler, error_handler=handler)
self.update_statusbar()
gobject.source_remove(self.update_cb)
misc.timeout_add(100, self._wait_for_connect_thread_start, milli=True)
def disconnect(self, widget, nettype, networkid, networkentry): def disconnect(self, widget, nettype, networkid, networkentry):
""" Disconnects from the given network. """ Disconnects from the given network.
@@ -674,13 +700,18 @@ class appGui(object):
networkentry -- The NetworkEntry containing the disconnect button. networkentry -- The NetworkEntry containing the disconnect button.
""" """
def handler(*args):
gobject.idle_add(self.network_list.set_sensitive, True)
widget.hide() widget.hide()
networkentry.connect_button.show() networkentry.connect_button.show()
daemon.SetForcedDisconnect(True) daemon.SetForcedDisconnect(True)
self.network_list.set_sensitive(False)
if nettype == "wired": if nettype == "wired":
wired.DisconnectWired() wired.DisconnectWired(reply_handler=handler, error_handler=handler)
else: else:
wireless.DisconnectWireless() wireless.DisconnectWireless(reply_handler=handler,
error_handler=handler)
def wait_for_events(self, amt=0): def wait_for_events(self, amt=0):
""" Wait for any pending gtk events to finish before moving on. """ Wait for any pending gtk events to finish before moving on.

View File

@@ -17,11 +17,39 @@
# #
import gtk import gtk
import os.path
import wpath
HAS_NOTIFY = True
try:
import pynotify
if not pynotify.init("Wicd"):
print 'Could not initalize pynotify'
HAS_NOTIFY = False
except ImportError:
print "Importing pynotify failed, notifications disabled."
HAS_NOTIFY = False
print "Has notifications support", HAS_NOTIFY
if wpath.no_use_notifications:
print 'Notifications disabled during setup.py configure'
def can_use_notify():
use_notify = os.path.exists(os.path.join(os.path.expanduser('~/.wicd'),
'USE_NOTIFICATIONS')
)
return use_notify and HAS_NOTIFY and not wpath.no_use_notifications
def error(parent, message, block=True): def error(parent, message, block=True):
""" Shows an error dialog. """ """ Shows an error dialog. """
def delete_event(dialog, id): def delete_event(dialog, id):
dialog.destroy() dialog.destroy()
if can_use_notify() and not block:
notification = pynotify.Notification("ERROR", message, "error")
notification.show()
return
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK) gtk.BUTTONS_OK)
dialog.set_markup(message) dialog.set_markup(message)

View File

@@ -492,7 +492,7 @@ def stringToNone(text):
def checkboxTextboxToggle(checkbox, textboxes): def checkboxTextboxToggle(checkbox, textboxes):
for textbox in textboxes: for textbox in textboxes:
textbox.set_sensitive(checkbox.get_active()) textbox.set_sensitive(checkbox.get_active())
def threaded(f): def threaded(f):
""" A decorator that will make any function run in a new thread. """ """ A decorator that will make any function run in a new thread. """

View File

@@ -174,6 +174,9 @@ class ConnectionStatus(object):
self.iwconfig = '' self.iwconfig = ''
# Reset this, just in case. # Reset this, just in case.
self.tried_reconnect = False self.tried_reconnect = False
bssid = wireless.GetApBssid()
if not bssid:
return False
wifi_signal = self._get_printable_sig_strength() wifi_signal = self._get_printable_sig_strength()
if wifi_signal == 0: if wifi_signal == 0:

View File

@@ -154,7 +154,6 @@ class Controller(object):
self.disconnect_script = None self.disconnect_script = None
self.driver = None self.driver = None
self.iface = None self.iface = None
self.backend_manager = BackendManager()
def get_debug(self): return self._debug def get_debug(self): return self._debug
def set_debug(self, value): def set_debug(self, value):

View File

@@ -55,7 +55,7 @@ def get_gettext():
_ = lang.gettext _ = lang.gettext
return _ return _
# Generated automatically on Mon, 04 May 2009 23:56:04 CDT # Generated automatically on Sun, 17 May 2009 19:17:27 CDT
_ = get_gettext() _ = get_gettext()
language = {} language = {}
language['resetting_ip_address'] = _('''Resetting IP address...''') language['resetting_ip_address'] = _('''Resetting IP address...''')
@@ -215,3 +215,4 @@ language['disconnected'] = _('''Disconnected''')
language['establishing_connection'] = _('''Establishing connection...''') language['establishing_connection'] = _('''Establishing connection...''')
language['association_failed'] = _('''Connection failed: Could not contact the wireless access point.''') language['association_failed'] = _('''Connection failed: Could not contact the wireless access point.''')
language['access_denied'] = _('''Unable to contact the wicd dameon due to an access denied error from DBus. Please check your DBus configuration.''') language['access_denied'] = _('''Unable to contact the wicd dameon due to an access denied error from DBus. Please check your DBus configuration.''')
language['disconnecting_active'] = _('''Disconnecting active connections...''')

View File

@@ -43,16 +43,15 @@ import pango
import atexit import atexit
from dbus import DBusException from dbus import DBusException
import pygtk
pygtk.require('2.0')
HAS_NOTIFY = True HAS_NOTIFY = True
try: try:
import pygtk
pygtk.require('2.0')
import pynotify import pynotify
if not pynotify.init("Wicd"): if not pynotify.init("Wicd"):
print 'could not initalize pynotify'
HAS_NOTIFY = False HAS_NOTIFY = False
except ImportError: except ImportError:
print 'import failed'
HAS_NOTIFY = False HAS_NOTIFY = False
# Wicd specific imports # Wicd specific imports
@@ -60,7 +59,7 @@ from wicd import wpath
from wicd import misc from wicd import misc
from wicd import gui from wicd import gui
from wicd import dbusmanager from wicd import dbusmanager
from wicd.guiutil import error from wicd.guiutil import error, can_use_notify
from wicd.translations import language from wicd.translations import language
@@ -75,11 +74,6 @@ if not hasattr(gtk, "StatusIcon"):
print 'Unable to load tray icon: Missing both egg.trayicon and gtk.StatusIcon modules.' print 'Unable to load tray icon: Missing both egg.trayicon and gtk.StatusIcon modules.'
ICON_AVAIL = False ICON_AVAIL = False
print "Has notifications support", HAS_NOTIFY
if wpath.no_use_notifications:
print 'Notifications disabled during setup.py configure'
misc.RenameProcess("wicd-client") misc.RenameProcess("wicd-client")
if __name__ == '__main__': if __name__ == '__main__':
@@ -163,10 +157,6 @@ class TrayIcon(object):
self.last_state = None self.last_state = None
self.should_notify = True self.should_notify = True
self.use_notify = os.path.exists(os.path.join(
os.path.expanduser('~/.wicd'),
'USE_NOTIFICATIONS'))
if DBUS_AVAIL: if DBUS_AVAIL:
self.update_tray_icon() self.update_tray_icon()
else: else:
@@ -272,10 +262,8 @@ class TrayIcon(object):
[state, info] = daemon.GetConnectionStatus() [state, info] = daemon.GetConnectionStatus()
# should this state change display a notification? # should this state change display a notification?
self.should_notify = not wpath.no_use_notifications and \ self.should_notify = (can_use_notify() and
(self.last_state != state) and \ self.last_state != state)
HAS_NOTIFY and \
self.use_notify
self.last_state = state self.last_state = state

View File

@@ -1300,6 +1300,7 @@ class WiredDaemon(dbus.service.Object):
self.daemon = daemon self.daemon = daemon
self.wired = wired self.wired = wired
self._debug_mode = debug self._debug_mode = debug
self._cur_wired_prof_name = ""
self.WiredNetwork = {} self.WiredNetwork = {}
self.config = ConfigManager(os.path.join(wpath.etc, self.config = ConfigManager(os.path.join(wpath.etc,
"wired-settings.conf"), "wired-settings.conf"),
@@ -1413,6 +1414,8 @@ class WiredDaemon(dbus.service.Object):
self.wired.disconnect_script = self.GetWiredProperty("disconnectscript") self.wired.disconnect_script = self.GetWiredProperty("disconnectscript")
self.daemon.wireless_bus.wifi.Disconnect() self.daemon.wireless_bus.wifi.Disconnect()
self.daemon.SetForcedDisconnect(False) self.daemon.SetForcedDisconnect(False)
self.UnsetWiredLastUsed()
self.config.set(self._cur_wired_prof_name, "lastused", True, write=True)
self.wired.Connect(self.WiredNetwork, debug=self.debug_mode) self.wired.Connect(self.WiredNetwork, debug=self.debug_mode)
self.daemon.UpdateState() self.daemon.UpdateState()
@@ -1511,8 +1514,10 @@ class WiredDaemon(dbus.service.Object):
profile['use_global_dns'] = bool(profile.get('use_global_dns')) profile['use_global_dns'] = bool(profile.get('use_global_dns'))
profile['use_static_dns'] = bool(profile.get('use_static_dns')) profile['use_static_dns'] = bool(profile.get('use_static_dns'))
self.WiredNetwork = profile self.WiredNetwork = profile
self._cur_wired_prof_name = profilename
return "100: Loaded Profile" return "100: Loaded Profile"
else: else:
self._cur_wired_prof_name = ""
self.WiredNetwork = {} self.WiredNetwork = {}
return "500: Profile Not Found" return "500: Profile Not Found"

View File

@@ -44,7 +44,7 @@ from misc import find_path
_re_mode = (re.I | re.M | re.S) _re_mode = (re.I | re.M | re.S)
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', _re_mode) essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', _re_mode)
ap_mac_pattern = re.compile('.*Address: (.*?)\n', _re_mode) ap_mac_pattern = re.compile('.*Address: (.*?)\n', _re_mode)
channel_pattern = re.compile('.*Channel:? ?(\d\d?)', _re_mode) channel_pattern = re.compile('.*Channel:?=? ?(\d\d?)', _re_mode)
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode) strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode)
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode) altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode)
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', _re_mode) signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', _re_mode)
@@ -83,6 +83,31 @@ def _sanitize_string_strict(string):
return translate(str(string), blank_trans, blacklist_strict) return translate(str(string), blank_trans, blacklist_strict)
else: else:
return string return string
_cache = {}
def timedcache(duration=5):
""" A caching decorator for use with wnettools methods.
Caches the results of a function for a given number of
seconds (defaults to 5).
"""
def _timedcache(f):
def __timedcache(self, *args, **kwargs):
key = str(args) + str(kwargs) + str(f)
if hasattr(self, 'iface'):
key += self.iface
if (key in _cache and
(time.time() - _cache[key]['time']) < duration):
return _cache[key]['value']
else:
value = f(self, *args, **kwargs)
_cache[key] = { 'time' : time.time(), 'value' : value }
return value
return __timedcache
return _timedcache
def GetDefaultGateway(): def GetDefaultGateway():
""" Attempts to determine the default gateway by parsing route -n. """ """ Attempts to determine the default gateway by parsing route -n. """
@@ -349,6 +374,14 @@ class BaseInterface(object):
if self.verbose: print cmd if self.verbose: print cmd
misc.Run(cmd) misc.Run(cmd)
return True return True
@timedcache(2)
@neediface("")
def GetIfconfig(self):
""" Runs ifconfig and returns the output. """
cmd = "ifconfig %s" % self.iface
if self.verbose: print cmd
return misc.Run(cmd)
@neediface("") @neediface("")
def SetAddress(self, ip=None, netmask=None, broadcast=None): def SetAddress(self, ip=None, netmask=None, broadcast=None):
@@ -596,9 +629,7 @@ class BaseInterface(object):
""" """
if not ifconfig: if not ifconfig:
cmd = 'ifconfig ' + self.iface output = self.GetIfconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = ifconfig output = ifconfig
return misc.RunRegex(ip_pattern, output) return misc.RunRegex(ip_pattern, output)
@@ -635,9 +666,7 @@ class BaseInterface(object):
def _slow_is_up(self, ifconfig=None): def _slow_is_up(self, ifconfig=None):
""" Determine if an interface is up using ifconfig. """ """ Determine if an interface is up using ifconfig. """
if not ifconfig: if not ifconfig:
cmd = "ifconfig " + self.iface output = self.GetIfconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = ifconfig output = ifconfig
lines = output.split('\n') lines = output.split('\n')
@@ -800,6 +829,7 @@ class BaseWirelessInterface(BaseInterface):
return radiostatus return radiostatus
@timedcache(2)
@neediface(False) @neediface(False)
def GetIwconfig(self): def GetIwconfig(self):
""" Returns the output of iwconfig for this interface. """ """ Returns the output of iwconfig for this interface. """
@@ -965,12 +995,17 @@ class BaseWirelessInterface(BaseInterface):
""" """
cmd = ['iwconfig', self.iface, 'essid', essid] cmd = ['iwconfig', self.iface, 'essid', essid]
if channel and str(channel).isdigit():
cmd.extend(['channel', str(channel)])
if bssid:
cmd.extend(['ap', bssid])
if self.verbose: print str(cmd) if self.verbose: print str(cmd)
misc.Run(cmd) misc.Run(cmd)
base = "iwconfig %s" % self.iface
if channel and str(channel).isdigit():
cmd = "%s channel %s" % (base, str(channel))
if self.verbose: print cmd
misc.Run(cmd)
if bssid:
cmd = "%s ap %s" % (base, bssid)
if self.verbose: print cmd
misc.Run(cmd)
def GeneratePSK(self, network): def GeneratePSK(self, network):
""" Generate a PSK using wpa_passphrase. """ Generate a PSK using wpa_passphrase.
@@ -1237,9 +1272,7 @@ class BaseWirelessInterface(BaseInterface):
def GetBSSID(self, iwconfig=None): def GetBSSID(self, iwconfig=None):
""" Get the MAC address for the interface. """ """ Get the MAC address for the interface. """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
@@ -1250,9 +1283,7 @@ class BaseWirelessInterface(BaseInterface):
def GetCurrentBitrate(self, iwconfig=None): def GetCurrentBitrate(self, iwconfig=None):
""" Get the current bitrate for the interface. """ """ Get the current bitrate for the interface. """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
@@ -1263,9 +1294,7 @@ class BaseWirelessInterface(BaseInterface):
def GetOperationalMode(self, iwconfig=None): def GetOperationalMode(self, iwconfig=None):
""" Get the operational mode for the interface. """ """ Get the operational mode for the interface. """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
@@ -1313,9 +1342,7 @@ class BaseWirelessInterface(BaseInterface):
""" """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
return self._get_link_quality(output) return self._get_link_quality(output)
@@ -1329,9 +1356,7 @@ class BaseWirelessInterface(BaseInterface):
""" """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
@@ -1348,9 +1373,7 @@ class BaseWirelessInterface(BaseInterface):
""" """
if not iwconfig: if not iwconfig:
cmd = 'iwconfig ' + self.iface output = self.GetIwconfig()
if self.verbose: print cmd
output = misc.Run(cmd)
else: else:
output = iwconfig output = iwconfig
network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"', network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',