mirror of
https://github.com/gryf/wicd.git
synced 2026-02-28 21:35:53 +01:00
curses/wicd-curses.py: Added code to restore the console on all errors, and then print them, including KeyboardInterrupts.
curses/TODO: Removed the above from TODO
This commit is contained in:
@@ -9,8 +9,6 @@ Things to do (in no particular order):
|
|||||||
* Implement a keyhandler function for the overall frame
|
* Implement a keyhandler function for the overall frame
|
||||||
* Make keystrokes customizable
|
* Make keystrokes customizable
|
||||||
* Make color schemes customizable
|
* Make color schemes customizable
|
||||||
* Add code to restore the terminal if _anything_ bad happens. I have an idea about
|
|
||||||
how to do it. Ask me about it if you know some Python.
|
|
||||||
|
|
||||||
Oh, and most importantly:
|
Oh, and most importantly:
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,13 @@ import gobject
|
|||||||
|
|
||||||
# Other important wicd-related stuff
|
# Other important wicd-related stuff
|
||||||
import wicd.misc as misc
|
import wicd.misc as misc
|
||||||
#import sys
|
|
||||||
|
# Internal Python stuff
|
||||||
|
import sys
|
||||||
|
|
||||||
# Translations for the text that people will see... as of yet. This code is
|
# Translations for the text that people will see... as of yet. This code is
|
||||||
# already found in the gui.py file
|
# already found in the gui.py file
|
||||||
# Stick into own ui_common file?
|
# IN EXPERIMENTAL, THIS IS ALL IN wicd.misc
|
||||||
_ = misc.get_gettext()
|
_ = misc.get_gettext()
|
||||||
language = {}
|
language = {}
|
||||||
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
|
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
|
||||||
@@ -63,8 +65,42 @@ else:
|
|||||||
from dbus.mainloop.glib import DBusGMainLoop
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
DBusGMainLoop(set_as_default=True)
|
DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
|
# A hack to get any errors that pop out of the program to appear ***AFTER*** the
|
||||||
|
# program exits.
|
||||||
|
# I also may have been a bit overkill about using this too, I guess I'll find that out
|
||||||
|
# soon enough.
|
||||||
|
class wrap_exceptions:
|
||||||
|
def __call__(self, f):
|
||||||
|
def wrap_exceptions(*args, **kargs):
|
||||||
|
try:
|
||||||
|
return f(*args, **kargs)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
gobject.source_remove(redraw_tag)
|
||||||
|
loop.quit()
|
||||||
|
ui.stop()
|
||||||
|
print "Terminated by user."
|
||||||
|
raise
|
||||||
|
except :
|
||||||
|
# Remove update_ui from the event queue
|
||||||
|
gobject.source_remove(redraw_tag)
|
||||||
|
# Quit the loop
|
||||||
|
loop.quit()
|
||||||
|
# Zap the screen
|
||||||
|
ui.stop()
|
||||||
|
# Print out standard notification:
|
||||||
|
print "EXCEPTION!"
|
||||||
|
print "Please report this to the maintainer and/or file a bug report with the backtrace below:"
|
||||||
|
# Flush the buffer so that the notification is always above the
|
||||||
|
# backtrace
|
||||||
|
sys.stdout.flush()
|
||||||
|
# Raise the exception
|
||||||
|
raise
|
||||||
|
|
||||||
|
return wrap_exceptions
|
||||||
|
|
||||||
# Look familiar? These two functions are clones of functions found in wicd's
|
# Look familiar? These two functions are clones of functions found in wicd's
|
||||||
# gui.py file, except that now set_status is a function passed to them.
|
# gui.py file, except that now set_status is a function passed to them.
|
||||||
|
@wrap_exceptions()
|
||||||
def check_for_wired(wired_ip,set_status):
|
def check_for_wired(wired_ip,set_status):
|
||||||
""" Determine if wired is active, and if yes, set the status. """
|
""" Determine if wired is active, and if yes, set the status. """
|
||||||
if wired_ip and wired.CheckPluggedIn():
|
if wired_ip and wired.CheckPluggedIn():
|
||||||
@@ -73,6 +109,7 @@ def check_for_wired(wired_ip,set_status):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@wrap_exceptions()
|
||||||
def check_for_wireless(iwconfig, wireless_ip, set_status):
|
def check_for_wireless(iwconfig, wireless_ip, set_status):
|
||||||
""" Determine if wireless is active, and if yes, set the status. """
|
""" Determine if wireless is active, and if yes, set the status. """
|
||||||
if not wireless_ip:
|
if not wireless_ip:
|
||||||
@@ -107,6 +144,7 @@ def gen_list_header():
|
|||||||
# Generate the list of networks.
|
# Generate the list of networks.
|
||||||
# Mostly borrowed/stolen from wpa_cli, since I had no clue what all of those
|
# Mostly borrowed/stolen from wpa_cli, since I had no clue what all of those
|
||||||
# DBUS interfaces do. ^_^
|
# DBUS interfaces do. ^_^
|
||||||
|
@wrap_exceptions()
|
||||||
def gen_network_list():
|
def gen_network_list():
|
||||||
#theList = [urwid.Text(gen_list_header())]
|
#theList = [urwid.Text(gen_list_header())]
|
||||||
theList = []
|
theList = []
|
||||||
@@ -235,6 +273,7 @@ class NetList(urwid.WidgetWrap):
|
|||||||
# that one, then updates its selection status.
|
# that one, then updates its selection status.
|
||||||
# TODO: Pressing "Enter" would disconnect you from your current network, and
|
# TODO: Pressing "Enter" would disconnect you from your current network, and
|
||||||
# connect you to the selected one
|
# connect you to the selected one
|
||||||
|
#@wrap_exceptions()
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
#if key == 'down' or key == 'up':
|
#if key == 'down' or key == 'up':
|
||||||
self.update_selected(False)
|
self.update_selected(False)
|
||||||
@@ -249,6 +288,7 @@ class appGUI():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Happy screen saying that you can't do anything because we're scanning
|
# Happy screen saying that you can't do anything because we're scanning
|
||||||
# for networks. :-)
|
# for networks. :-)
|
||||||
|
# Will need a translation sooner or later
|
||||||
self.screen_locker = urwid.Filler(urwid.Text(('important',"Scanning networks... stand by..."), align='center'))
|
self.screen_locker = urwid.Filler(urwid.Text(('important',"Scanning networks... stand by..."), align='center'))
|
||||||
|
|
||||||
#self.update_ct = 0
|
#self.update_ct = 0
|
||||||
@@ -278,10 +318,14 @@ class appGUI():
|
|||||||
def unlock_screen(self):
|
def unlock_screen(self):
|
||||||
self.update_netlist(force_check=True)
|
self.update_netlist(force_check=True)
|
||||||
self.frame.set_body(self.netList)
|
self.frame.set_body(self.netList)
|
||||||
|
# I'm hoping that this will get rid of Adam's problem with the NetList not
|
||||||
|
# redisplaying itself immediately upon completion.
|
||||||
|
update_ui()
|
||||||
|
|
||||||
# Be clunky until I get to a later stage of development.
|
# Be clunky until I get to a later stage of development.
|
||||||
# Update the list of networks. Usually called by DBus.
|
# Update the list of networks. Usually called by DBus.
|
||||||
# TODO: Preserve current focus when updating the list.
|
# TODO: Preserve current focus when updating the list.
|
||||||
|
@wrap_exceptions()
|
||||||
def update_netlist(self,state=None, x=None, force_check=False):
|
def update_netlist(self,state=None, x=None, force_check=False):
|
||||||
""" Updates the overall network list."""
|
""" Updates the overall network list."""
|
||||||
if not state:
|
if not state:
|
||||||
@@ -294,6 +338,7 @@ class appGUI():
|
|||||||
self.prev_state = state
|
self.prev_state = state
|
||||||
|
|
||||||
# Update the footer/status bar
|
# Update the footer/status bar
|
||||||
|
@wrap_exceptions()
|
||||||
def update_status(self):
|
def update_status(self):
|
||||||
#self.update_ct += 1
|
#self.update_ct += 1
|
||||||
if check_for_wired(wired.GetWiredIP(),self.set_status):
|
if check_for_wired(wired.GetWiredIP(),self.set_status):
|
||||||
@@ -310,6 +355,7 @@ class appGUI():
|
|||||||
self.frame.set_footer(urwid.AttrWrap(urwid.Text(text),'important'))
|
self.frame.set_footer(urwid.AttrWrap(urwid.Text(text),'important'))
|
||||||
|
|
||||||
# Yeah, I'm copying code. Anything wrong with that?
|
# Yeah, I'm copying code. Anything wrong with that?
|
||||||
|
@wrap_exceptions()
|
||||||
def dbus_scan_finished(self):
|
def dbus_scan_finished(self):
|
||||||
# I'm pretty sure that I'll need this later.
|
# I'm pretty sure that I'll need this later.
|
||||||
#if not self.connecting:
|
#if not self.connecting:
|
||||||
@@ -321,6 +367,7 @@ class appGUI():
|
|||||||
self.update_ui()
|
self.update_ui()
|
||||||
|
|
||||||
# Same, same, same, same, same, same
|
# Same, same, same, same, same, same
|
||||||
|
@wrap_exceptions()
|
||||||
def dbus_scan_started(self):
|
def dbus_scan_started(self):
|
||||||
self.lock_screen()
|
self.lock_screen()
|
||||||
|
|
||||||
@@ -328,12 +375,13 @@ class appGUI():
|
|||||||
# Calls the main loop. This is how the thing should be started, at least
|
# Calls the main loop. This is how the thing should be started, at least
|
||||||
# until I decide to change it, whenever that is.
|
# until I decide to change it, whenever that is.
|
||||||
def main(self):
|
def main(self):
|
||||||
|
global ui
|
||||||
misc.RenameProcess('wicd-curses')
|
misc.RenameProcess('wicd-curses')
|
||||||
self.ui = urwid.curses_display.Screen()
|
ui = urwid.curses_display.Screen()
|
||||||
# Color scheme.
|
# Color scheme.
|
||||||
# Other potential color schemes can be found at:
|
# Other potential color schemes can be found at:
|
||||||
# http://excess.org/urwid/wiki/RecommendedPalette
|
# http://excess.org/urwid/wiki/RecommendedPalette
|
||||||
self.ui.register_palette([
|
ui.register_palette([
|
||||||
('body','light gray','black'),
|
('body','light gray','black'),
|
||||||
('selected','dark magenta','light gray'),
|
('selected','dark magenta','light gray'),
|
||||||
('header','light blue','black'),
|
('header','light blue','black'),
|
||||||
@@ -342,22 +390,24 @@ class appGUI():
|
|||||||
('connected_sel','black','dark green')])
|
('connected_sel','black','dark green')])
|
||||||
# This is a wrapper around a function that calls another a function that is a
|
# This is a wrapper around a function that calls another a function that is a
|
||||||
# wrapper around a infinite loop. Fun.
|
# wrapper around a infinite loop. Fun.
|
||||||
self.ui.run_wrapper(self.run)
|
ui.run_wrapper(self.run)
|
||||||
|
|
||||||
# Main program loop
|
# Main program loop
|
||||||
def run(self):
|
def run(self):
|
||||||
self.size = self.ui.get_cols_rows()
|
global loop,redraw_tag
|
||||||
|
self.size = ui.get_cols_rows()
|
||||||
|
|
||||||
# This actually makes some things easier to do, amusingly enough
|
# This actually makes some things easier to do, amusingly enough
|
||||||
self.loop = gobject.MainLoop()
|
loop = gobject.MainLoop()
|
||||||
# Update what the interface looks like every 0.5 ms
|
# Update what the interface looks like every 0.5 ms
|
||||||
# Apparently this is deprecated. May have to change this.
|
# Apparently this is use (with fractional seconds) is deprecated. May have to
|
||||||
gobject.timeout_add(0.5,self.update_ui)
|
# change this.
|
||||||
|
redraw_tag = gobject.timeout_add(0.5,self.update_ui)
|
||||||
# Update the connection status on the bottom every 2 s
|
# Update the connection status on the bottom every 2 s
|
||||||
gobject.timeout_add(2000,self.update_status)
|
gobject.timeout_add(2000,self.update_status)
|
||||||
# Terminate the loop if the UI is terminated.
|
# Terminate the loop if the UI is terminated.
|
||||||
gobject.idle_add(self.stop_loop)
|
gobject.idle_add(self.stop_loop)
|
||||||
self.loop.run()
|
loop.run()
|
||||||
|
|
||||||
# Redraw the screen
|
# Redraw the screen
|
||||||
# There exists a problem with this where any exceptions that occur (especially of
|
# There exists a problem with this where any exceptions that occur (especially of
|
||||||
@@ -365,16 +415,13 @@ class appGUI():
|
|||||||
# at all. Urwid and the glib main loop don't mix all too well. I may need to
|
# at all. Urwid and the glib main loop don't mix all too well. I may need to
|
||||||
# consult the Urwid maintainer about this.
|
# consult the Urwid maintainer about this.
|
||||||
#
|
#
|
||||||
# I believe that I have a fix for this. It just involves wrapping every single
|
# The implementation of this solution
|
||||||
# function that might throw an exception with a try-except block, using a function
|
@wrap_exceptions()
|
||||||
# wrapper. I have tested it, and it seems to work, but I'll save it until I can
|
|
||||||
# evaluate what I need to wrap. Probably a vast majority of stuff, until I am sure
|
|
||||||
# that this is stable.
|
|
||||||
def update_ui(self):
|
def update_ui(self):
|
||||||
#self.update_status()
|
#self.update_status()
|
||||||
canvas = self.frame.render( (self.size) )
|
canvas = self.frame.render( (self.size) )
|
||||||
self.ui.draw_screen((self.size),canvas)
|
ui.draw_screen((self.size),canvas)
|
||||||
keys = self.ui.get_input()
|
keys = ui.get_input()
|
||||||
# Should make a keyhandler method, but this will do until I get around to
|
# Should make a keyhandler method, but this will do until I get around to
|
||||||
# that stage
|
# that stage
|
||||||
if "f8" in keys:
|
if "f8" in keys:
|
||||||
@@ -383,14 +430,14 @@ class appGUI():
|
|||||||
wireless.Scan()
|
wireless.Scan()
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if k == "window resize":
|
if k == "window resize":
|
||||||
self.size = self.ui.get_cols_rows()
|
self.size = ui.get_cols_rows()
|
||||||
continue
|
continue
|
||||||
self.frame.keypress( self.size, k )
|
self.frame.keypress( self.size, k )
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Terminate the loop, used as the glib mainloop's idle function
|
# Terminate the loop, used as the glib mainloop's idle function
|
||||||
def stop_loop(self):
|
def stop_loop(self):
|
||||||
self.loop.quit()
|
loop.quit()
|
||||||
|
|
||||||
# Mostly borrowed from gui.py, but also with the "need daemon first" check
|
# Mostly borrowed from gui.py, but also with the "need daemon first" check
|
||||||
def setup_dbus():
|
def setup_dbus():
|
||||||
|
|||||||
Reference in New Issue
Block a user