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:
43
wicd/gui.py
43
wicd/gui.py
@@ -286,7 +286,11 @@ class appGui(object):
|
||||
|
||||
def disconnect_all(self, widget=None):
|
||||
""" 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):
|
||||
""" Displays an about dialog. """
|
||||
@@ -649,19 +653,41 @@ class appGui(object):
|
||||
return False
|
||||
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):
|
||||
""" 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.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 not self.check_encryption_valid(networkid,
|
||||
networkentry.advanced_dialog):
|
||||
self.edit_advanced(None, None, nettype, networkid, networkentry)
|
||||
return False
|
||||
wireless.ConnectWireless(networkid)
|
||||
wireless.ConnectWireless(networkid, reply_handler=handler,
|
||||
error_handler=handler)
|
||||
elif nettype == "wired":
|
||||
wired.ConnectWired()
|
||||
self.update_statusbar()
|
||||
wired.ConnectWired(reply_handler=handler, error_handler=handler)
|
||||
|
||||
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):
|
||||
""" Disconnects from the given network.
|
||||
@@ -674,13 +700,18 @@ class appGui(object):
|
||||
networkentry -- The NetworkEntry containing the disconnect button.
|
||||
|
||||
"""
|
||||
def handler(*args):
|
||||
gobject.idle_add(self.network_list.set_sensitive, True)
|
||||
|
||||
widget.hide()
|
||||
networkentry.connect_button.show()
|
||||
daemon.SetForcedDisconnect(True)
|
||||
self.network_list.set_sensitive(False)
|
||||
if nettype == "wired":
|
||||
wired.DisconnectWired()
|
||||
wired.DisconnectWired(reply_handler=handler, error_handler=handler)
|
||||
else:
|
||||
wireless.DisconnectWireless()
|
||||
wireless.DisconnectWireless(reply_handler=handler,
|
||||
error_handler=handler)
|
||||
|
||||
def wait_for_events(self, amt=0):
|
||||
""" Wait for any pending gtk events to finish before moving on.
|
||||
|
||||
@@ -17,11 +17,39 @@
|
||||
#
|
||||
|
||||
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):
|
||||
""" Shows an error dialog. """
|
||||
def delete_event(dialog, id):
|
||||
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,
|
||||
gtk.BUTTONS_OK)
|
||||
dialog.set_markup(message)
|
||||
|
||||
@@ -492,7 +492,7 @@ def stringToNone(text):
|
||||
def checkboxTextboxToggle(checkbox, textboxes):
|
||||
for textbox in textboxes:
|
||||
textbox.set_sensitive(checkbox.get_active())
|
||||
|
||||
|
||||
def threaded(f):
|
||||
""" A decorator that will make any function run in a new thread. """
|
||||
|
||||
|
||||
@@ -174,6 +174,9 @@ class ConnectionStatus(object):
|
||||
self.iwconfig = ''
|
||||
# Reset this, just in case.
|
||||
self.tried_reconnect = False
|
||||
bssid = wireless.GetApBssid()
|
||||
if not bssid:
|
||||
return False
|
||||
|
||||
wifi_signal = self._get_printable_sig_strength()
|
||||
if wifi_signal == 0:
|
||||
|
||||
@@ -154,7 +154,6 @@ class Controller(object):
|
||||
self.disconnect_script = None
|
||||
self.driver = None
|
||||
self.iface = None
|
||||
self.backend_manager = BackendManager()
|
||||
|
||||
def get_debug(self): return self._debug
|
||||
def set_debug(self, value):
|
||||
|
||||
@@ -55,7 +55,7 @@ def get_gettext():
|
||||
_ = lang.gettext
|
||||
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()
|
||||
language = {}
|
||||
language['resetting_ip_address'] = _('''Resetting IP address...''')
|
||||
@@ -215,3 +215,4 @@ language['disconnected'] = _('''Disconnected''')
|
||||
language['establishing_connection'] = _('''Establishing connection...''')
|
||||
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['disconnecting_active'] = _('''Disconnecting active connections...''')
|
||||
|
||||
@@ -43,16 +43,15 @@ import pango
|
||||
import atexit
|
||||
from dbus import DBusException
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
|
||||
HAS_NOTIFY = True
|
||||
try:
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import pynotify
|
||||
if not pynotify.init("Wicd"):
|
||||
print 'could not initalize pynotify'
|
||||
HAS_NOTIFY = False
|
||||
except ImportError:
|
||||
print 'import failed'
|
||||
HAS_NOTIFY = False
|
||||
|
||||
# Wicd specific imports
|
||||
@@ -60,7 +59,7 @@ from wicd import wpath
|
||||
from wicd import misc
|
||||
from wicd import gui
|
||||
from wicd import dbusmanager
|
||||
from wicd.guiutil import error
|
||||
from wicd.guiutil import error, can_use_notify
|
||||
|
||||
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.'
|
||||
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")
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -163,10 +157,6 @@ class TrayIcon(object):
|
||||
self.last_state = None
|
||||
self.should_notify = True
|
||||
|
||||
self.use_notify = os.path.exists(os.path.join(
|
||||
os.path.expanduser('~/.wicd'),
|
||||
'USE_NOTIFICATIONS'))
|
||||
|
||||
if DBUS_AVAIL:
|
||||
self.update_tray_icon()
|
||||
else:
|
||||
@@ -272,10 +262,8 @@ class TrayIcon(object):
|
||||
[state, info] = daemon.GetConnectionStatus()
|
||||
|
||||
# should this state change display a notification?
|
||||
self.should_notify = not wpath.no_use_notifications and \
|
||||
(self.last_state != state) and \
|
||||
HAS_NOTIFY and \
|
||||
self.use_notify
|
||||
self.should_notify = (can_use_notify() and
|
||||
self.last_state != state)
|
||||
|
||||
self.last_state = state
|
||||
|
||||
|
||||
@@ -1300,6 +1300,7 @@ class WiredDaemon(dbus.service.Object):
|
||||
self.daemon = daemon
|
||||
self.wired = wired
|
||||
self._debug_mode = debug
|
||||
self._cur_wired_prof_name = ""
|
||||
self.WiredNetwork = {}
|
||||
self.config = ConfigManager(os.path.join(wpath.etc,
|
||||
"wired-settings.conf"),
|
||||
@@ -1413,6 +1414,8 @@ class WiredDaemon(dbus.service.Object):
|
||||
self.wired.disconnect_script = self.GetWiredProperty("disconnectscript")
|
||||
self.daemon.wireless_bus.wifi.Disconnect()
|
||||
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.daemon.UpdateState()
|
||||
|
||||
@@ -1511,8 +1514,10 @@ class WiredDaemon(dbus.service.Object):
|
||||
profile['use_global_dns'] = bool(profile.get('use_global_dns'))
|
||||
profile['use_static_dns'] = bool(profile.get('use_static_dns'))
|
||||
self.WiredNetwork = profile
|
||||
self._cur_wired_prof_name = profilename
|
||||
return "100: Loaded Profile"
|
||||
else:
|
||||
self._cur_wired_prof_name = ""
|
||||
self.WiredNetwork = {}
|
||||
return "500: Profile Not Found"
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ from misc import find_path
|
||||
_re_mode = (re.I | re.M | re.S)
|
||||
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\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)
|
||||
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\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)
|
||||
else:
|
||||
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():
|
||||
""" Attempts to determine the default gateway by parsing route -n. """
|
||||
@@ -349,6 +374,14 @@ class BaseInterface(object):
|
||||
if self.verbose: print cmd
|
||||
misc.Run(cmd)
|
||||
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("")
|
||||
def SetAddress(self, ip=None, netmask=None, broadcast=None):
|
||||
@@ -596,9 +629,7 @@ class BaseInterface(object):
|
||||
|
||||
"""
|
||||
if not ifconfig:
|
||||
cmd = 'ifconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIfconfig()
|
||||
else:
|
||||
output = ifconfig
|
||||
return misc.RunRegex(ip_pattern, output)
|
||||
@@ -635,9 +666,7 @@ class BaseInterface(object):
|
||||
def _slow_is_up(self, ifconfig=None):
|
||||
""" Determine if an interface is up using ifconfig. """
|
||||
if not ifconfig:
|
||||
cmd = "ifconfig " + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIfconfig()
|
||||
else:
|
||||
output = ifconfig
|
||||
lines = output.split('\n')
|
||||
@@ -800,6 +829,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
|
||||
return radiostatus
|
||||
|
||||
@timedcache(2)
|
||||
@neediface(False)
|
||||
def GetIwconfig(self):
|
||||
""" Returns the output of iwconfig for this interface. """
|
||||
@@ -965,12 +995,17 @@ class BaseWirelessInterface(BaseInterface):
|
||||
|
||||
"""
|
||||
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)
|
||||
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):
|
||||
""" Generate a PSK using wpa_passphrase.
|
||||
@@ -1237,9 +1272,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
def GetBSSID(self, iwconfig=None):
|
||||
""" Get the MAC address for the interface. """
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
|
||||
@@ -1250,9 +1283,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
def GetCurrentBitrate(self, iwconfig=None):
|
||||
""" Get the current bitrate for the interface. """
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
|
||||
@@ -1263,9 +1294,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
def GetOperationalMode(self, iwconfig=None):
|
||||
""" Get the operational mode for the interface. """
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
|
||||
@@ -1313,9 +1342,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
|
||||
"""
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
return self._get_link_quality(output)
|
||||
@@ -1329,9 +1356,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
|
||||
"""
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
|
||||
@@ -1348,9 +1373,7 @@ class BaseWirelessInterface(BaseInterface):
|
||||
|
||||
"""
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
output = self.GetIwconfig()
|
||||
else:
|
||||
output = iwconfig
|
||||
network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',
|
||||
|
||||
Reference in New Issue
Block a user