Merge lp://staging/~oreilldf/wicd/1.6-dan into lp://staging/wicd/1.6
- 1.6-dan
- Merge into experimental
Proposed by
Dan O'Reilly
Status: | Merged |
---|---|
Approved by: | Adam Blackburn |
Approved revision: | 404 |
Merged at revision: | not available |
Proposed branch: | lp://staging/~oreilldf/wicd/1.6-dan |
Merge into: | lp://staging/wicd/1.6 |
Diff against target: | None lines |
To merge this branch: | bzr merge lp://staging/~oreilldf/wicd/1.6-dan |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Adam Blackburn | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dan O'Reilly (oreilldf) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Adam Blackburn (adamblackburn) wrote : | # |
Looks fine, runs fine here. I don't see any reason not to merge.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'wicd/gui.py' |
2 | --- wicd/gui.py 2009-05-22 03:29:12 +0000 |
3 | +++ wicd/gui.py 2009-05-22 19:43:14 +0000 |
4 | @@ -286,7 +286,11 @@ |
5 | |
6 | def disconnect_all(self, widget=None): |
7 | """ Disconnects from any active network. """ |
8 | - daemon.Disconnect() |
9 | + def handler(*args): |
10 | + gobject.idle_add(self.network_list.set_sensitive, True) |
11 | + |
12 | + self.network_list.set_sensitive(False) |
13 | + daemon.Disconnect(reply_handler=handler, error_handler=handler) |
14 | |
15 | def about_dialog(self, widget, event=None): |
16 | """ Displays an about dialog. """ |
17 | @@ -649,19 +653,41 @@ |
18 | return False |
19 | return True |
20 | |
21 | + def _wait_for_connect_thread_start(self): |
22 | + self.wTree.get_widget("progressbar").pulse() |
23 | + if not self._connect_thread_started: |
24 | + return True |
25 | + else: |
26 | + misc.timeout_add(2, self.update_statusbar) |
27 | + self.update_statusbar() |
28 | + return False |
29 | + |
30 | def connect(self, widget, nettype, networkid, networkentry): |
31 | """ Initiates the connection process in the daemon. """ |
32 | + def handler(*args): |
33 | + self._connect_thread_started = True |
34 | + |
35 | cancel_button = self.wTree.get_widget("cancel_button") |
36 | cancel_button.set_sensitive(True) |
37 | + self.network_list.set_sensitive(False) |
38 | + if self.statusID: |
39 | + gobject.idle_add(self.status_bar.remove, 1, self.statusID) |
40 | + gobject.idle_add(self.set_status, language["disconnecting_active"]) |
41 | + gobject.idle_add(self.status_area.show_all) |
42 | + self.wait_for_events() |
43 | + self._connect_thread_started = False |
44 | if nettype == "wireless": |
45 | if not self.check_encryption_valid(networkid, |
46 | networkentry.advanced_dialog): |
47 | self.edit_advanced(None, None, nettype, networkid, networkentry) |
48 | return False |
49 | - wireless.ConnectWireless(networkid) |
50 | + wireless.ConnectWireless(networkid, reply_handler=handler, |
51 | + error_handler=handler) |
52 | elif nettype == "wired": |
53 | - wired.ConnectWired() |
54 | - self.update_statusbar() |
55 | + wired.ConnectWired(reply_handler=handler, error_handler=handler) |
56 | + |
57 | + gobject.source_remove(self.update_cb) |
58 | + misc.timeout_add(100, self._wait_for_connect_thread_start, milli=True) |
59 | |
60 | def disconnect(self, widget, nettype, networkid, networkentry): |
61 | """ Disconnects from the given network. |
62 | @@ -674,13 +700,18 @@ |
63 | networkentry -- The NetworkEntry containing the disconnect button. |
64 | |
65 | """ |
66 | + def handler(*args): |
67 | + gobject.idle_add(self.network_list.set_sensitive, True) |
68 | + |
69 | widget.hide() |
70 | networkentry.connect_button.show() |
71 | daemon.SetForcedDisconnect(True) |
72 | + self.network_list.set_sensitive(False) |
73 | if nettype == "wired": |
74 | - wired.DisconnectWired() |
75 | + wired.DisconnectWired(reply_handler=handler, error_handler=handler) |
76 | else: |
77 | - wireless.DisconnectWireless() |
78 | + wireless.DisconnectWireless(reply_handler=handler, |
79 | + error_handler=handler) |
80 | |
81 | def wait_for_events(self, amt=0): |
82 | """ Wait for any pending gtk events to finish before moving on. |
83 | |
84 | === modified file 'wicd/guiutil.py' |
85 | --- wicd/guiutil.py 2009-05-10 14:51:49 +0000 |
86 | +++ wicd/guiutil.py 2009-05-22 19:43:14 +0000 |
87 | @@ -17,11 +17,39 @@ |
88 | # |
89 | |
90 | import gtk |
91 | - |
92 | +import os.path |
93 | + |
94 | +import wpath |
95 | + |
96 | +HAS_NOTIFY = True |
97 | +try: |
98 | + import pynotify |
99 | + if not pynotify.init("Wicd"): |
100 | + print 'Could not initalize pynotify' |
101 | + HAS_NOTIFY = False |
102 | +except ImportError: |
103 | + print "Importing pynotify failed, notifications disabled." |
104 | + HAS_NOTIFY = False |
105 | + |
106 | +print "Has notifications support", HAS_NOTIFY |
107 | + |
108 | +if wpath.no_use_notifications: |
109 | + print 'Notifications disabled during setup.py configure' |
110 | + |
111 | +def can_use_notify(): |
112 | + use_notify = os.path.exists(os.path.join(os.path.expanduser('~/.wicd'), |
113 | + 'USE_NOTIFICATIONS') |
114 | + ) |
115 | + return use_notify and HAS_NOTIFY and not wpath.no_use_notifications |
116 | + |
117 | def error(parent, message, block=True): |
118 | """ Shows an error dialog. """ |
119 | def delete_event(dialog, id): |
120 | dialog.destroy() |
121 | + if can_use_notify() and not block: |
122 | + notification = pynotify.Notification("ERROR", message, "error") |
123 | + notification.show() |
124 | + return |
125 | dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, |
126 | gtk.BUTTONS_OK) |
127 | dialog.set_markup(message) |
128 | |
129 | === modified file 'wicd/misc.py' |
130 | --- wicd/misc.py 2009-04-12 02:41:34 +0000 |
131 | +++ wicd/misc.py 2009-05-22 19:43:14 +0000 |
132 | @@ -492,7 +492,7 @@ |
133 | def checkboxTextboxToggle(checkbox, textboxes): |
134 | for textbox in textboxes: |
135 | textbox.set_sensitive(checkbox.get_active()) |
136 | - |
137 | + |
138 | def threaded(f): |
139 | """ A decorator that will make any function run in a new thread. """ |
140 | |
141 | |
142 | === modified file 'wicd/monitor.py' |
143 | --- wicd/monitor.py 2009-04-27 23:17:01 +0000 |
144 | +++ wicd/monitor.py 2009-05-22 19:43:14 +0000 |
145 | @@ -174,6 +174,9 @@ |
146 | self.iwconfig = '' |
147 | # Reset this, just in case. |
148 | self.tried_reconnect = False |
149 | + bssid = wireless.GetApBssid() |
150 | + if not bssid: |
151 | + return False |
152 | |
153 | wifi_signal = self._get_printable_sig_strength() |
154 | if wifi_signal == 0: |
155 | |
156 | === modified file 'wicd/networking.py' |
157 | --- wicd/networking.py 2009-04-20 01:13:58 +0000 |
158 | +++ wicd/networking.py 2009-05-22 19:43:14 +0000 |
159 | @@ -154,7 +154,6 @@ |
160 | self.disconnect_script = None |
161 | self.driver = None |
162 | self.iface = None |
163 | - self.backend_manager = BackendManager() |
164 | |
165 | def get_debug(self): return self._debug |
166 | def set_debug(self, value): |
167 | |
168 | === modified file 'wicd/translations.py' |
169 | --- wicd/translations.py 2009-05-05 04:56:09 +0000 |
170 | +++ wicd/translations.py 2009-05-22 19:43:14 +0000 |
171 | @@ -55,7 +55,7 @@ |
172 | _ = lang.gettext |
173 | return _ |
174 | |
175 | -# Generated automatically on Mon, 04 May 2009 23:56:04 CDT |
176 | +# Generated automatically on Sun, 17 May 2009 19:17:27 CDT |
177 | _ = get_gettext() |
178 | language = {} |
179 | language['resetting_ip_address'] = _('''Resetting IP address...''') |
180 | @@ -215,3 +215,4 @@ |
181 | language['establishing_connection'] = _('''Establishing connection...''') |
182 | language['association_failed'] = _('''Connection failed: Could not contact the wireless access point.''') |
183 | language['access_denied'] = _('''Unable to contact the wicd dameon due to an access denied error from DBus. Please check your DBus configuration.''') |
184 | +language['disconnecting_active'] = _('''Disconnecting active connections...''') |
185 | |
186 | === modified file 'wicd/wicd-client.py' |
187 | --- wicd/wicd-client.py 2009-05-10 17:53:54 +0000 |
188 | +++ wicd/wicd-client.py 2009-05-22 19:43:14 +0000 |
189 | @@ -43,16 +43,15 @@ |
190 | import atexit |
191 | from dbus import DBusException |
192 | |
193 | +import pygtk |
194 | +pygtk.require('2.0') |
195 | + |
196 | HAS_NOTIFY = True |
197 | try: |
198 | - import pygtk |
199 | - pygtk.require('2.0') |
200 | import pynotify |
201 | if not pynotify.init("Wicd"): |
202 | - print 'could not initalize pynotify' |
203 | HAS_NOTIFY = False |
204 | except ImportError: |
205 | - print 'import failed' |
206 | HAS_NOTIFY = False |
207 | |
208 | # Wicd specific imports |
209 | @@ -60,7 +59,7 @@ |
210 | from wicd import misc |
211 | from wicd import gui |
212 | from wicd import dbusmanager |
213 | -from wicd.guiutil import error |
214 | +from wicd.guiutil import error, can_use_notify |
215 | |
216 | from wicd.translations import language |
217 | |
218 | @@ -75,11 +74,6 @@ |
219 | print 'Unable to load tray icon: Missing both egg.trayicon and gtk.StatusIcon modules.' |
220 | ICON_AVAIL = False |
221 | |
222 | -print "Has notifications support", HAS_NOTIFY |
223 | - |
224 | -if wpath.no_use_notifications: |
225 | - print 'Notifications disabled during setup.py configure' |
226 | - |
227 | misc.RenameProcess("wicd-client") |
228 | |
229 | if __name__ == '__main__': |
230 | @@ -163,10 +157,6 @@ |
231 | self.last_state = None |
232 | self.should_notify = True |
233 | |
234 | - self.use_notify = os.path.exists(os.path.join( |
235 | - os.path.expanduser('~/.wicd'), |
236 | - 'USE_NOTIFICATIONS')) |
237 | - |
238 | if DBUS_AVAIL: |
239 | self.update_tray_icon() |
240 | else: |
241 | @@ -272,10 +262,8 @@ |
242 | [state, info] = daemon.GetConnectionStatus() |
243 | |
244 | # should this state change display a notification? |
245 | - self.should_notify = not wpath.no_use_notifications and \ |
246 | - (self.last_state != state) and \ |
247 | - HAS_NOTIFY and \ |
248 | - self.use_notify |
249 | + self.should_notify = (can_use_notify() and |
250 | + self.last_state != state) |
251 | |
252 | self.last_state = state |
253 | |
254 | |
255 | === modified file 'wicd/wicd-daemon.py' |
256 | --- wicd/wicd-daemon.py 2009-05-03 13:58:11 +0000 |
257 | +++ wicd/wicd-daemon.py 2009-05-24 21:11:14 +0000 |
258 | @@ -203,6 +203,16 @@ |
259 | def SetBackend(self, backend): |
260 | """ Sets a new backend. """ |
261 | print "setting backend to %s" % backend |
262 | + backends = networking.BACKEND_MGR.get_available_backends() |
263 | + if backend not in backends: |
264 | + print "backend %s not available, trying to fallback to another" % backend |
265 | + try: |
266 | + backend = backends[0] |
267 | + except IndexError: |
268 | + print "ERROR: no backends available!" |
269 | + return |
270 | + else: |
271 | + print "Fell back to backend %s" % backend |
272 | self.config.set("Settings", "backend", backend, write=True) |
273 | if backend != self.GetCurrentBackend(): |
274 | self.suspended = True |
275 | @@ -1300,6 +1310,7 @@ |
276 | self.daemon = daemon |
277 | self.wired = wired |
278 | self._debug_mode = debug |
279 | + self._cur_wired_prof_name = "" |
280 | self.WiredNetwork = {} |
281 | self.config = ConfigManager(os.path.join(wpath.etc, |
282 | "wired-settings.conf"), |
283 | @@ -1413,6 +1424,8 @@ |
284 | self.wired.disconnect_script = self.GetWiredProperty("disconnectscript") |
285 | self.daemon.wireless_bus.wifi.Disconnect() |
286 | self.daemon.SetForcedDisconnect(False) |
287 | + self.UnsetWiredLastUsed() |
288 | + self.config.set(self._cur_wired_prof_name, "lastused", True, write=True) |
289 | self.wired.Connect(self.WiredNetwork, debug=self.debug_mode) |
290 | self.daemon.UpdateState() |
291 | |
292 | @@ -1511,8 +1524,10 @@ |
293 | profile['use_global_dns'] = bool(profile.get('use_global_dns')) |
294 | profile['use_static_dns'] = bool(profile.get('use_static_dns')) |
295 | self.WiredNetwork = profile |
296 | + self._cur_wired_prof_name = profilename |
297 | return "100: Loaded Profile" |
298 | else: |
299 | + self._cur_wired_prof_name = "" |
300 | self.WiredNetwork = {} |
301 | return "500: Profile Not Found" |
302 | |
303 | |
304 | === modified file 'wicd/wnettools.py' |
305 | --- wicd/wnettools.py 2009-05-19 23:12:58 +0000 |
306 | +++ wicd/wnettools.py 2009-05-22 19:43:14 +0000 |
307 | @@ -44,7 +44,7 @@ |
308 | _re_mode = (re.I | re.M | re.S) |
309 | essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', _re_mode) |
310 | ap_mac_pattern = re.compile('.*Address: (.*?)\n', _re_mode) |
311 | -channel_pattern = re.compile('.*Channel:? ?(\d\d?)', _re_mode) |
312 | +channel_pattern = re.compile('.*Channel:?=? ?(\d\d?)', _re_mode) |
313 | strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode) |
314 | altstrength_pattern = re.compile('.*Signal level:?=? ?(\d+)\s*/?\s*(\d*)', _re_mode) |
315 | signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', _re_mode) |
316 | @@ -83,6 +83,31 @@ |
317 | return translate(str(string), blank_trans, blacklist_strict) |
318 | else: |
319 | return string |
320 | + |
321 | +_cache = {} |
322 | +def timedcache(duration=5): |
323 | + """ A caching decorator for use with wnettools methods. |
324 | + |
325 | + Caches the results of a function for a given number of |
326 | + seconds (defaults to 5). |
327 | + |
328 | + """ |
329 | + def _timedcache(f): |
330 | + def __timedcache(self, *args, **kwargs): |
331 | + key = str(args) + str(kwargs) + str(f) |
332 | + if hasattr(self, 'iface'): |
333 | + key += self.iface |
334 | + if (key in _cache and |
335 | + (time.time() - _cache[key]['time']) < duration): |
336 | + return _cache[key]['value'] |
337 | + else: |
338 | + value = f(self, *args, **kwargs) |
339 | + _cache[key] = { 'time' : time.time(), 'value' : value } |
340 | + return value |
341 | + |
342 | + return __timedcache |
343 | + |
344 | + return _timedcache |
345 | |
346 | def GetDefaultGateway(): |
347 | """ Attempts to determine the default gateway by parsing route -n. """ |
348 | @@ -349,6 +374,14 @@ |
349 | if self.verbose: print cmd |
350 | misc.Run(cmd) |
351 | return True |
352 | + |
353 | + @timedcache(2) |
354 | + @neediface("") |
355 | + def GetIfconfig(self): |
356 | + """ Runs ifconfig and returns the output. """ |
357 | + cmd = "ifconfig %s" % self.iface |
358 | + if self.verbose: print cmd |
359 | + return misc.Run(cmd) |
360 | |
361 | @neediface("") |
362 | def SetAddress(self, ip=None, netmask=None, broadcast=None): |
363 | @@ -596,9 +629,7 @@ |
364 | |
365 | """ |
366 | if not ifconfig: |
367 | - cmd = 'ifconfig ' + self.iface |
368 | - if self.verbose: print cmd |
369 | - output = misc.Run(cmd) |
370 | + output = self.GetIfconfig() |
371 | else: |
372 | output = ifconfig |
373 | return misc.RunRegex(ip_pattern, output) |
374 | @@ -635,9 +666,7 @@ |
375 | def _slow_is_up(self, ifconfig=None): |
376 | """ Determine if an interface is up using ifconfig. """ |
377 | if not ifconfig: |
378 | - cmd = "ifconfig " + self.iface |
379 | - if self.verbose: print cmd |
380 | - output = misc.Run(cmd) |
381 | + output = self.GetIfconfig() |
382 | else: |
383 | output = ifconfig |
384 | lines = output.split('\n') |
385 | @@ -800,6 +829,7 @@ |
386 | |
387 | return radiostatus |
388 | |
389 | + @timedcache(2) |
390 | @neediface(False) |
391 | def GetIwconfig(self): |
392 | """ Returns the output of iwconfig for this interface. """ |
393 | @@ -965,12 +995,17 @@ |
394 | |
395 | """ |
396 | cmd = ['iwconfig', self.iface, 'essid', essid] |
397 | + if self.verbose: print str(cmd) |
398 | + misc.Run(cmd) |
399 | + base = "iwconfig %s" % self.iface |
400 | if channel and str(channel).isdigit(): |
401 | - cmd.extend(['channel', str(channel)]) |
402 | + cmd = "%s channel %s" % (base, str(channel)) |
403 | + if self.verbose: print cmd |
404 | + misc.Run(cmd) |
405 | if bssid: |
406 | - cmd.extend(['ap', bssid]) |
407 | - if self.verbose: print str(cmd) |
408 | - misc.Run(cmd) |
409 | + cmd = "%s ap %s" % (base, bssid) |
410 | + if self.verbose: print cmd |
411 | + misc.Run(cmd) |
412 | |
413 | def GeneratePSK(self, network): |
414 | """ Generate a PSK using wpa_passphrase. |
415 | @@ -1237,9 +1272,7 @@ |
416 | def GetBSSID(self, iwconfig=None): |
417 | """ Get the MAC address for the interface. """ |
418 | if not iwconfig: |
419 | - cmd = 'iwconfig ' + self.iface |
420 | - if self.verbose: print cmd |
421 | - output = misc.Run(cmd) |
422 | + output = self.GetIwconfig() |
423 | else: |
424 | output = iwconfig |
425 | |
426 | @@ -1250,9 +1283,7 @@ |
427 | def GetCurrentBitrate(self, iwconfig=None): |
428 | """ Get the current bitrate for the interface. """ |
429 | if not iwconfig: |
430 | - cmd = 'iwconfig ' + self.iface |
431 | - if self.verbose: print cmd |
432 | - output = misc.Run(cmd) |
433 | + output = self.GetIwconfig() |
434 | else: |
435 | output = iwconfig |
436 | |
437 | @@ -1263,9 +1294,7 @@ |
438 | def GetOperationalMode(self, iwconfig=None): |
439 | """ Get the operational mode for the interface. """ |
440 | if not iwconfig: |
441 | - cmd = 'iwconfig ' + self.iface |
442 | - if self.verbose: print cmd |
443 | - output = misc.Run(cmd) |
444 | + output = self.GetIwconfig() |
445 | else: |
446 | output = iwconfig |
447 | |
448 | @@ -1313,9 +1342,7 @@ |
449 | |
450 | """ |
451 | if not iwconfig: |
452 | - cmd = 'iwconfig ' + self.iface |
453 | - if self.verbose: print cmd |
454 | - output = misc.Run(cmd) |
455 | + output = self.GetIwconfig() |
456 | else: |
457 | output = iwconfig |
458 | return self._get_link_quality(output) |
459 | @@ -1329,9 +1356,7 @@ |
460 | |
461 | """ |
462 | if not iwconfig: |
463 | - cmd = 'iwconfig ' + self.iface |
464 | - if self.verbose: print cmd |
465 | - output = misc.Run(cmd) |
466 | + output = self.GetIwconfig() |
467 | else: |
468 | output = iwconfig |
469 | signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', |
470 | @@ -1348,9 +1373,7 @@ |
471 | |
472 | """ |
473 | if not iwconfig: |
474 | - cmd = 'iwconfig ' + self.iface |
475 | - if self.verbose: print cmd |
476 | - output = misc.Run(cmd) |
477 | + output = self.GetIwconfig() |
478 | else: |
479 | output = iwconfig |
480 | network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"', |
- 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
- Try to recover if we load an invalid/nonexistent backend.