1
0
mirror of https://github.com/gryf/wicd.git synced 2025-12-24 07:02:29 +01:00

initial merge, probably doesn't work yet

This commit is contained in:
Adam Blackburn
2009-08-12 23:03:16 -05:00
46 changed files with 9046 additions and 1450 deletions

6813
CHANGES

File diff suppressed because it is too large Load Diff

12
INSTALL
View File

@@ -1,18 +1,22 @@
Installation of Wicd should be done using your distribution package if one
exists. If not, the installation is relatively straightforward, but there
are a few dependencies:
1. python (obviously) and pygtk
1. python (>=2.4, <3.0)
2. pygtk (>=2.10)
2. dbus and its glib and python bindings
3. a dhcp client (dhclient, dhcpcd, and pump are supported)
4. wireless-tools (iwlist, iwconfig, etcetera)
5. net-tools (ip, route, etcetera)
6. a graphical sudo application (gksu, kdesu, and ktsuss are supported),
while optional, is strongly recommended
7. urwid (if you want to use the curses client)
8. pm-utils (optional for suspend/resume integration - needs version 1.2.4+)
7. urwid (if you want to use the curses client - needs version >=0.9.8.3)
8. pm-utils (optional for suspend/resume integration)
Wicd supports using versions >=1.2.4 -- earlier versions may work just
fine, but they are completely unsupported here.
If you are installing from a bzr pull or beta/rc tarball and you want
If you are installing from a bzr pull and you want
the native language translations, first run this:
python setup.py update_translations_py
python setup.py get_translations
You will not need to do this if you're installing from a release tarball.

49
NEWS Normal file
View File

@@ -0,0 +1,49 @@
Wicd 1.6.0 Branch
1.6.2:
Minor Changes:
- Now deals better if the interface disappears while running
- Will now start if the global script directories don't exist
- Adhoc window will now work correctly
- PSK can be generated from non-ASCII characters
- Fix a minor wicd-curses crash while connecting during a scan
1.6.1:
Minor Changes:
- User is told if the lack permission to access the daemon
- Support for wireless cards that don't report signal strength added
- Enhanced network configuration dialog title
1.6.0:
Major Changes:
- Improved tray icon and GUI images (thanks to Martin Sagastume)
- Reorganized network list in the GUI for easier navigation
- New experimental ioctl backend, which is more cpu-friendly than the
previous one
- Added a curses client (thanks to Andrew Psaltis)
- Added a right-click connection menu to the tray icon
- Added options to specify a DNS domain and search domain for static networks
- Reworked the Preferences menu to be more in line with GNOME standards
- Added support for global scripts
- Made it possible to have optional entries in encryption templates
- Added ability to show libnotify notifications on status change
Minor Changes and Other Enhancements:
- Better autoconnection behavior
- Tray/GUI will survive the daemon being killed
- Reasons for connection failures will now bubble back to the GUI
- Add/remove wired profile system is now more user-friendly
- Support for using resolvconf instead of directly editing /etc/resolv.conf
- Wicd won't blindly kill dhcp clients / wpa_supplicant any more
- Added an option to automatically switch from a wireless network to a wired
one as soon as a cable is plugged in
- Moved scanning to its own thread, which makes GUI and daemon more responsive
during scans
- Made it possible to specify macros in script entries
- The GUI will now display the encryption entry dialog if you attempt to
connect to an encrypted network without entering a password
- Static gateway entry is now optional
- Passwords with leading or trailing whitespace are now stored properly
- Many init/config script, man page, and setup.py fixes/updates, including
better autodetection of file placement with regard to sleep hooks and
KDE autostart files (thanks to Robby Workman)

View File

@@ -14,15 +14,15 @@ All features that I plan on implementing (that are not mentioned above) are
listed the TODO file in this same directory. If you want any other features,
ask me. I try to be on the #wicd Freenode IRC channel most of the time.
Controls:
Controls (most of these should be viewable in wicd-curses itself):
F5 : refresh wireless networks
F8 or Q or q: quit
F8 Q q : quit
D : disconnect from all active networks
ESC : if connecting to a network, stop doing so
ENTER : Attempt connection to selected network
ENTER C : Attempt connection to selected network
P : Display preferences dialog
C : Display network configuration for selected network
right arrow : Display network configuration for selected network
A : Display "About" dialog
I : Raise the "Scan for hidden networks" dialog
H or h or ? : Raise help dialog
@@ -32,8 +32,8 @@ F2 : Rename selected wired network profile (from the wired ComboBox)
O : Raise ad-hoc network dialog
IN DIALOGS (Meta usually is "Alt"):
ESC or Q: Quit dialog without saving information (if present)
Meta+Left/Right: Change tabs Left/Right (if tabs present)
ESC or Q or q: Quit dialog without saving information (if present)
Meta+[ / Meta+]: Change tabs Left/Right (if tabs present)
Meta+Enter : Quit dialog and save information
FAQ (WIP):

View File

@@ -1,6 +1,5 @@
Things to do (in no particular order):
* Implement a keyhandler function for the overall frame
* Make keystrokes customizable
* Make keystrokes customizable (Probably not going to happen)
* Make color schemes customizable
* Perform a mass code cleanup

View File

@@ -38,7 +38,8 @@ language = {}
language['configure_scripts'] = _("Configure Scripts")
language['before_script'] = _("Pre-connection Script")
language['after_script'] = _("Post-connection Script")
language['disconnect_script'] = _("Disconnection Script")
language['pre_disconnect_script'] = _("Pre-disconnection Script")
language['post_disconnect_script'] = _("Post-disconnection Script")
def main(argv):
global ui,frame
@@ -62,16 +63,19 @@ def main(argv):
blank = urwid.Text('')
pre_entry_t = ('body',language['before_script']+': ')
post_entry_t = ('body',language['after_script']+': ')
disconnect_entry_t = ('body',language['disconnect_script']+': ')
pre_disconnect_entry_t = ('body',language['pre_disconnect_script']+': ')
post_disconnect_entry_t = ('body',language['post_disconnect_script']+': ')
global pre_entry,post_entry,disconnect_entry
global pre_entry,post_entry,pre_disconnect_entry,post_disconnect_entry
pre_entry = urwid.AttrWrap(urwid.Edit(pre_entry_t,
none_to_blank(script_info.get('pre_entry'))),'editbx','editfc' )
post_entry = urwid.AttrWrap(urwid.Edit(post_entry_t,
none_to_blank(script_info.get('post_entry'))),'editbx','editfc' )
disconnect_entry = urwid.AttrWrap(urwid.Edit(disconnect_entry_t,
none_to_blank(script_info.get('disconnect_entry'))),'editbx','editfc' )
pre_disconnect_entry = urwid.AttrWrap(urwid.Edit(pre_disconnect_entry_t,
none_to_blank(script_info.get('pre_disconnect_entry'))),'editbx','editfc' )
post_disconnect_entry = urwid.AttrWrap(urwid.Edit(post_disconnect_entry_t,
none_to_blank(script_info.get('post_disconnect_entry'))),'editbx','editfc' )
# The buttons
ok_button = urwid.AttrWrap(urwid.Button('OK',ok_callback),'body','focus')
@@ -82,7 +86,8 @@ def main(argv):
lbox = urwid.Pile([('fixed',2,urwid.Filler(pre_entry)),
#('fixed',urwid.Filler(blank),1),
('fixed',2,urwid.Filler(post_entry)),
('fixed',2,urwid.Filler(disconnect_entry)),
('fixed',2,urwid.Filler(pre_disconnect_entry)),
('fixed',2,urwid.Filler(post_disconnect_entry)),
#blank,blank,blank,blank,blank,
urwid.Filler(button_cols,'bottom')
])
@@ -92,7 +97,8 @@ def main(argv):
if result == True:
script_info["pre_entry"] = blank_to_none(pre_entry.get_edit_text())
script_info["post_entry"] = blank_to_none(post_entry.get_edit_text())
script_info["disconnect_entry"] = blank_to_none(disconnect_entry.get_edit_text())
script_info["pre_disconnect_entry"] = blank_to_none(pre_disconnect_entry.get_edit_text())
script_info["post_disconnect_entry"] = blank_to_none(post_disconnect_entry.get_edit_text())
write_scripts(network, network_type, script_info)
OK_PRESSED = False

View File

@@ -33,10 +33,6 @@ def error(ui,parent,message):
dialog = TextDialog(message,6,40,('important',"ERROR"))
return dialog.run(ui,parent)
# My savior. :-)
# Although I could have made this myself pretty easily, just want to give credit
# where it's due.
# http://excess.org/urwid/browser/contrib/trunk/rbreu_filechooser.py
class SelText(urwid.Text):
"""A selectable text widget. See urwid.Text."""
@@ -49,7 +45,12 @@ class SelText(urwid.Text):
"""Don't handle any keys."""
return key
# This class is annoying. ^_^
# ListBox that can't be selected.
class NSelListBox(urwid.ListBox):
def selectable(self):
return False
# This class is annoying. :/
class DynWrap(urwid.AttrWrap):
"""
Makes an object have mutable selectivity. Attributes will change like
@@ -102,6 +103,12 @@ class DynIntEdit(DynWrap):
edit = urwid.IntEdit(caption,edit_text)
self.__super.__init__(edit,sensitive,attrs,focus_attr)
class DynRadioButton(DynWrap):
def __init__(self,group,label,state='first True',on_state_change=None, user_data=None, sensitive=True, attrs=('body','editnfc'),focus_attr='body'):
#caption = ('editcp',caption + ':')
button = urwid.RadioButton(group,label,state,on_state_change,user_data)
self.__super.__init__(button,sensitive,attrs,focus_attr)
class MaskingEditException(Exception):
pass
@@ -123,6 +130,8 @@ class MaskingEdit(urwid.Edit):
self.mask_char = mask_char
self.__super.__init__(caption,edit_text,multiline,align,wrap,allow_tab,edit_pos,layout)
def get_caption(self):
return self.caption
def get_mask_mode(self):
return self.mask_mode
def set_mask_mode(self,mode):
@@ -136,7 +145,8 @@ class MaskingEdit(urwid.Edit):
Render edit widget and return canvas. Include cursor when in
focus.
"""
# If we aren't masking anything ATM, then act like an Edit. No problems.
# If we aren't masking anything ATM, then act like an Edit.
# No problems.
if self.mask_mode == "off" or (self.mask_mode == 'no_focus' and focus == True):
canv = self.__super.render((maxcol,),focus)
# The cache messes this thing up, because I am totally changing what
@@ -165,9 +175,10 @@ class TabColumns(urwid.WidgetWrap):
attr = normal attributes
attrsel = attribute when active
"""
def __init__(self,tab_str,tab_wid,title,bottom_part,attr=('body','focus'),
# FIXME Make the bottom_part optional
def __init__(self,tab_str,tab_wid,title,bottom_part=None,attr=('body','focus'),
attrsel='tab active', attrtitle='header'):
self.bottom_part = bottom_part
#self.bottom_part = bottom_part
#title_wid = urwid.Text((attrtitle,title),align='right')
column_list = []
for w in tab_str:
@@ -189,7 +200,7 @@ class TabColumns(urwid.WidgetWrap):
self.pile = urwid.Pile([
('fixed',1,urwid.Filler(self.columns,'top')),
urwid.Filler(lbox,'top',height=('relative',99)),
('fixed',1,urwid.Filler(self.bottom_part,'bottom'))
#('fixed',1,urwid.Filler(self.bottom_part,'bottom'))
])
if not firstrun:
self.frame.set_body(self.pile)
@@ -199,12 +210,13 @@ class TabColumns(urwid.WidgetWrap):
return True
def keypress(self,size,key):
self._w.keypress(size,key)
if key == "meta left" or key == "meta right":
if key == "meta [" or key == "meta ]":
self._w.get_body().set_focus(0)
self.keypress(size,key[5:])
newK = 'left' if key[-1] == '[' else 'right'
self.keypress(size,newK)
self._w.get_body().set_focus(1)
else:
key = self._w.keypress(size,key)
wid = self.pile.get_focus().get_body()
if wid == self.columns:
# lw = self.listbox.body
@@ -213,8 +225,20 @@ class TabColumns(urwid.WidgetWrap):
self.columns.get_focus().set_attr('tab active')
self.active_tab = self.columns.get_focus()
self.gen_pile(self.tab_map[self.active_tab])
return key
return key
# self.listbox.body = lw
def mouse_event(self,size,event,button,x,y,focus):
wid = self.pile.get_focus().get_body()
if wid == self.columns:
self.active_tab.set_attr('body')
self._w.mouse_event(size,event,button,x,y,focus)
if wid == self.columns:
self.active_tab.set_attr('body')
self.columns.get_focus().set_attr('tab active')
self.active_tab = self.columns.get_focus()
self.gen_pile(self.tab_map[self.active_tab])
### Combo box code begins here
@@ -225,7 +249,7 @@ class ComboBoxException(Exception):
# I based this off of the code found here:
# http://excess.org/urwid/browser/contrib/trunk/rbreu_menus.py
# This is a hack/kludge. It isn't without quirks, but it more or less works.
# We need to wait for changes in urwid's Canvas controls before we can actually
# We need to wait for changes in urwid's Canvas API before we can actually
# make a real ComboBox.
class ComboBox(urwid.WidgetWrap):
"""A ComboBox of text objects"""
@@ -296,6 +320,7 @@ class ComboBox(urwid.WidgetWrap):
user_args : user_args in the callback
"""
self.DOWN_ARROW = ' vvv'
self.label = urwid.Text(label)
self.attrs = attrs
self.focus_attr = focus_attr
@@ -304,9 +329,8 @@ class ComboBox(urwid.WidgetWrap):
str,trash = self.label.get_text()
self.overlay = None
#w,sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc')
self.cbox = DynWrap(SelText(' vvv'),attrs=attrs,focus_attr=focus_attr)
# Unicode will kill me sooner or later. ^_^
self.cbox = DynWrap(SelText(self.DOWN_ARROW),attrs=attrs,focus_attr=focus_attr)
# Unicode will kill me sooner or later.
if label != '':
w = urwid.Columns([('fixed',len(str),self.label),self.cbox],dividechars=1)
else:
@@ -315,10 +339,9 @@ class ComboBox(urwid.WidgetWrap):
# We need this to pick our keypresses
self.use_enter = use_enter
# The Focus
self.focus = focus
# The callback and friends
self.callback = callback
self.user_args = user_args
@@ -331,7 +354,7 @@ class ComboBox(urwid.WidgetWrap):
def set_focus(self,index):
self.focus = index
self.cbox.set_w(SelText(self.list[index]+' vvv'))
self.cbox.set_w(SelText(self.list[index]+self.DOWN_ARROW))
if self.overlay:
self.overlay._listbox.set_focus(index)
@@ -340,8 +363,7 @@ class ComboBox(urwid.WidgetWrap):
def build_combobox(self,parent,ui,row):
str,trash = self.label.get_text()
self.cbox = DynWrap(SelText([self.list[self.focus]+' vvv']),
self.cbox = DynWrap(SelText([self.list[self.focus]+self.DOWN_ARROW]),
attrs=self.attrs,focus_attr=self.focus_attr)
if str != '':
w = urwid.Columns([('fixed',len(str),self.label),self.cbox],
@@ -414,11 +436,6 @@ class Dialog2(urwid.WidgetWrap):
urwid.Divider()] )
w = self.frame
self.view = w
# pad area around listbox
#w = urwid.Padding(w, ('fixed left',2), ('fixed right',2))
#w = urwid.Filler(w, ('fixed top',1), ('fixed bottom',1))
#w = urwid.AttrWrap(w, 'body')
# buttons: tuple of name,exitcode
def add_buttons(self, buttons):
@@ -438,7 +455,8 @@ class Dialog2(urwid.WidgetWrap):
def run(self,ui,parent):
ui.set_mouse_tracking()
size = ui.get_cols_rows()
overlay = urwid.Overlay(urwid.LineBox(self.view), parent, 'center', self.width,
overlay = urwid.Overlay(urwid.LineBox(self.view),
parent, 'center', self.width,
'middle', self.height)
try:
while True:
@@ -474,8 +492,6 @@ class Dialog2(urwid.WidgetWrap):
class TextDialog(Dialog2):
def __init__(self, text, height, width, header=None,align='left'):
l = [urwid.Text(text)]
#for line in text:
# l.append( urwid.Text( line,align=align))
body = urwid.ListBox(l)
body = urwid.AttrWrap(body, 'body')
@@ -512,3 +528,83 @@ class InputDialog(Dialog2):
def on_exit(self, exitcode):
return exitcode, self.edit.get_edit_text()
class ClickCols(urwid.WidgetWrap):
def __init__(self,items,callback=None,args=None):
cols = urwid.Columns(items)
self.__super.__init__(cols)
self.callback = callback
self.args = args
def mouse_event(self,size,event,button,x,y,focus):
if event == "mouse press":
# The keypress dealie in wicd-curses.py expects a list of keystrokes
self.callback([self.args])
# htop-style menu menu-bar on the bottom of the screen
class OptCols(urwid.WidgetWrap):
# tuples = [(key,desc)], on_event gets passed a key
# attrs = (attr_key,attr_desc)
# handler = function passed the key of the "button" pressed
# mentions of 'left' and right will be converted to <- and -> respectively
def __init__(self,tuples,handler,attrs=('body','infobar'),debug=False):
# Find the longest string. Keys for this bar should be no greater than
# 2 characters long (e.g., -> for left)
#maxlen = 6
#for i in tuples:
# newmax = len(i[0])+len(i[1])
# if newmax > maxlen:
# maxlen = newmax
# Construct the texts
textList = []
i = 0
# callbacks map the text contents to its assigned callback.
self.callbacks = []
for cmd in tuples:
splitcmd = cmd[0].split()
key = ''
for part in splitcmd:
if part == 'ctrl':
key+='Ctrl+'
elif part == 'meta':
# If anyone has a problem with this, they can bother me
# about it.
key+='Alt+'
else:
if part == 'left':
key += '<-'
elif part == 'right':
key += '->'
elif part == 'esc':
key += 'ESC'
elif part == 'enter':
key += 'Enter'
else:
key += part
if debug:
callback = self.debugClick
args = cmd[1]
else:
callback = handler
args = cmd[0]
#self.callbacks.append(cmd[2])
col = ClickCols([
('fixed',len(key)+1,urwid.Text((attrs[0],key+':')) ),
urwid.AttrWrap(urwid.Text(cmd[1]),attrs[1])],
callback,args)
textList.append(col)
i+=1
if debug:
self.debug = urwid.Text("DEBUG_MODE")
textList.append(('fixed',10,self.debug))
cols = urwid.Columns(textList)
self.__super.__init__(cols)
def debugClick(self,args):
self.debug.set_text(args)
def mouse_event(self,size,event,button,x,y,focus):
# Widgets are evenly long (as of current), so...
return self._w.mouse_event(size,event,button,x,y,focus)

View File

@@ -62,17 +62,17 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
ok_t = 'OK'
self.static_ip_cb = urwid.CheckBox(static_ip_t,
on_state_change=self.static_ip_set_state)
on_state_change=self.static_ip_toggle)
self.ip_edit =DynWrap(urwid.Edit(ip_t),False)
self.netmask_edit=DynWrap(urwid.Edit(netmask_t),False)
self.gateway_edit=DynWrap(urwid.Edit(gateway_t),False)
self.static_dns_cb = urwid.CheckBox(use_static_dns_t,
on_state_change=self.dns_toggle)
self.static_dns_cb = DynWrap(urwid.CheckBox(use_static_dns_t,
on_state_change=self.dns_toggle),True,('body','editnfc'),None)
self.global_dns_cb = DynWrap(urwid.CheckBox(use_global_dns_t,
on_state_change=self.dns_toggle),False,('body','editnfc'),None)
checkb_cols = urwid.Columns([self.static_dns_cb,
self.checkb_cols = urwid.Columns([self.static_dns_cb,
self.global_dns_cb])
self.dns_dom_edit = DynWrap(urwid.Edit(dns_dom_t) ,False)
self.search_dom_edit = DynWrap(urwid.Edit(search_dom_t),False)
@@ -82,19 +82,12 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
_blank = urwid.Text('')
# Buttons. These need to be added to the list in superclasses.
self.OK_PRESSED= False
self.CANCEL_PRESSED = False
self.ok_button = urwid.AttrWrap(urwid.Button('OK',self.ok_callback),'body','focus')
self.cancel_button = urwid.AttrWrap(urwid.Button('Cancel',self.cancel_callback),'body','focus')
self.button_cols = urwid.Columns([self.ok_button,self.cancel_button])
walker = urwid.SimpleListWalker([self.static_ip_cb,
self.ip_edit,
self.netmask_edit,
self.gateway_edit,
_blank,
checkb_cols,
self.checkb_cols,
self.dns_dom_edit,self.search_dom_edit,
self.dns1,self.dns2,self.dns3
])
@@ -103,22 +96,22 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
self._listbox = urwid.ListBox(walker)
#self._frame = urwid.Frame(self._listbox)
self._frame = urwid.Frame(self._listbox,footer=self.button_cols)
self._frame = urwid.Frame(self._listbox)
self.__super.__init__(self._frame)
# Button callbacks
def ok_callback(self,button_object,user_data=None):
self.OK_PRESSED = True
def cancel_callback(self,button_object,user_data=None):
self.CANCEL_PRESSED = True
def static_ip_set_state(self,checkb,new_state,user_data=None):
def static_ip_toggle(self,checkb,new_state,user_data=None):
for w in [ self.ip_edit,self.netmask_edit,self.gateway_edit ]:
w.set_sensitive(new_state)
self.static_dns_cb.set_state(new_state)
self.static_dns_cb.set_sensitive(not new_state)
if new_state:
self.checkb_cols.set_focus(self.global_dns_cb)
else:
self.checkb_cols.set_focus(self.static_dns_cb)
def dns_toggle(self,checkb,new_state,user_data=None):
if checkb == self.static_dns_cb:
if checkb == self.static_dns_cb.get_w():
for w in [ self.dns_dom_edit,self.search_dom_edit,
self.dns1,self.dns2,self.dns3 ]:
w.set_sensitive(new_state)
@@ -147,11 +140,11 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
not self.global_dns_cb.get_state():
self.set_net_prop('use_static_dns', True)
self.set_net_prop('use_global_dns', False)
self.set_net_prop('dns_domain', noneToString(self.dns_dom_edit.get_text()))
self.set_net_prop("search_domain", noneToString(self.search_dom_edit.get_text()))
self.set_net_prop("dns1", noneToString(self.dns1.get_text()))
self.set_net_prop("dns2", noneToString(self.dns2.get_text()))
self.set_net_prop("dns3", noneToString(self.dns3.get_text()))
self.set_net_prop('dns_domain', noneToString(self.dns_dom_edit.get_edit_text()))
self.set_net_prop("search_domain", noneToString(self.search_dom_edit.get_edit_text()))
self.set_net_prop("dns1", noneToString(self.dns1.get_edit_text()))
self.set_net_prop("dns2", noneToString(self.dns2.get_edit_text()))
self.set_net_prop("dns3", noneToString(self.dns3.get_edit_text()))
elif self.static_dns_cb.get_state() and \
self.global_dns_cb.get_state():
self.set_net_prop('use_static_dns', True)
@@ -164,54 +157,9 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
self.set_net_prop("dns1", '')
self.set_net_prop("dns2", '')
self.set_net_prop("dns3", '')
def prerun(self,ui,dim,display):
# Prevent comboboxes from dying.
def ready_widgets(self,ui,body):
pass
def run(self,ui,dim,display):
self.ui = ui
self.parent = display
width,height = ui.get_cols_rows()
self.overlay = urwid.Overlay(self, display, ('fixed left', 0),width
, ('fixed top',1), height-3)
self.prerun(ui,dim,display)
#self.ready_comboboxes(ui,overlay)
keys = True
while True:
if keys:
ui.draw_screen(dim, self.overlay.render(dim, True))
keys = ui.get_input()
for k in keys:
#Send key to underlying widget:
if urwid.is_mouse_event(k):
event, button, col, row = k
self.overlay.mouse_event( dim,
event, button, col, row,
focus=True)
else:
k = self.overlay.keypress(dim, k)
if k in ('up','page up'):
self._w.set_focus('body')
# Until I figure out a better way to do this, then this will
# have to do.
self._w.body.get_focus()[0].get_focus()._invalidate()
#self._w.body.keypress(dim,'down')
elif k in ('down','page down'):
self._w.set_focus('footer')
if "window resize" in keys:
dim = ui.get_cols_rows()
if "esc" in keys or 'Q' in keys:
return False
if "meta enter" in keys or self.OK_PRESSED:
self.OK_PRESSED = False
if self.save_settings():
return True
if self.CANCEL_PRESSED:
return False
class WiredSettingsDialog(AdvancedSettingsDialog):
def __init__(self,name):
@@ -223,7 +171,7 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
self._w.body.body.append(self.set_default)
self.prof_name = name
title = ">"+language['configuring_wired'].replace('$A',self.prof_name)
title = language['configuring_wired'].replace('$A',self.prof_name)
self._w.header = urwid.Text( ('header',title),align='right' )
self.set_values()
@@ -237,6 +185,9 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
self.global_dns_cb.set_state(bool(wired.GetWiredProperty('use_global_dns')))
self.static_dns_cb.set_state(bool(wired.GetWiredProperty('use_static_dns')))
# Set static ip checkbox. Forgot to do this the first time.
if stringToNone(self.ip_edit.get_edit_text()):
self.static_ip_cb.set_state(True)
self.dns1.set_edit_text(self.format_entry( "dns1"))
self.dns2.set_edit_text(self.format_entry( "dns2"))
self.dns3.set_edit_text(self.format_entry( "dns3"))
@@ -267,10 +218,11 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
########################################
class WirelessSettingsDialog(AdvancedSettingsDialog):
def __init__(self,networkID):
def __init__(self,networkID,parent):
global wireless, daemon
AdvancedSettingsDialog.__init__(self)
self.networkid = networkID
self.parent = parent
global_settings_t = language['global_settings']
encryption_t = language['use_encryption']
autoconnect_t = language['automatic_connect']
@@ -289,7 +241,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
self.encrypt_types = misc.LoadEncryptionMethods()
self.set_values()
title = ">"+language['configuring_wireless'].replace('$A',wireless.GetWirelessProperty(networkID,'essid')).replace('$B',wireless.GetWirelessProperty(networkID,'bssid'))
title = language['configuring_wireless'].replace('$A',wireless.GetWirelessProperty(networkID,'essid')).replace('$B',wireless.GetWirelessProperty(networkID,'bssid'))
self._w.header = urwid.Text(('header',title),align='right' )
def encryption_toggle(self,chkbox,new_state,user_data=None):
@@ -311,6 +263,8 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
self.static_dns_cb.set_state(bool(wireless.GetWirelessProperty(networkID,
'use_static_dns')))
if stringToNone(self.ip_edit.get_edit_text()):
self.static_ip_cb.set_state(True)
self.dns1.set_edit_text(self.format_entry(networkID, "dns1"))
self.dns2.set_edit_text(self.format_entry(networkID, "dns2"))
self.dns3.set_edit_text(self.format_entry(networkID, "dns3"))
@@ -366,9 +320,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
for entry_info in encrypt_info.itervalues():
if entry_info[0].get_edit_text() == "" \
and entry_info[1] == 'required':
error(self.ui, self.overlay,"%s (%s)" \
error(self.ui, self.parent,"%s (%s)" \
% (language['encrypt_info_missing'],
entry_info[0].get_captionabel() )
entry_info[0].get_caption()[0:-2] )
)
return False
@@ -378,12 +332,10 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
elif not self.encryption_chkbox.get_state() and \
wireless.GetWirelessProperty(self.networkid, "encryption"):
# Encrypt checkbox is off, but the network needs it.
error(self.ui, self.overlay, language['enable_encryption'])
error(self.ui, self.parent, language['enable_encryption'])
return False
else:
self.set_net_prop("enctype", "None")
for entry in encrypt_info.iterkeys():
self.set_net_prop(entry[0].entry, "")
AdvancedSettingsDialog.save_settings(self)
# Save the autoconnect setting. This is not where it originally was
@@ -402,9 +354,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
# More or less ripped from netentry.py
def change_encrypt_method(self):
#self.lbox_encrypt = urwid.ListBox()
self.encryption_info = {}
wid,ID = self.encryption_combo.get_focus()
methods = misc.LoadEncryptionMethods()
self.encryption_info = {}
if self._w.body.body.__contains__(self.pile_encrypt):
self._w.body.body.pop(self._w.body.body.__len__()-1)
@@ -438,6 +390,8 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
self._w.body.body.insert(self._w.body.body.__len__(),self.pile_encrypt)
#self._w.body.body.append(self.pile_encrypt)
def prerun(self,ui,dim,display):
self.encryption_combo.build_combobox(self.overlay,ui,14)
def ready_widgets(self,ui,body):
self.ui = ui
self.body = body
self.encryption_combo.build_combobox(body,ui,14)
self.change_encrypt_method()

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env python
"""prefs_curses.py -- Pretty, tabbable, console preferences dialog"""
# Copyright (C) 2008-2009 Andrew Psaltis
# This program is free software; you can redistribute it and/or modify
@@ -22,7 +24,7 @@ import urwid.curses_display
from wicd import misc
from wicd import dbusmanager
from curses_misc import SelText,DynWrap,ComboBox,TabColumns
from curses_misc import SelText,DynWrap,DynRadioButton,ComboBox,TabColumns
daemon = None
wireless = None
@@ -68,8 +70,8 @@ class PrefsDialog(urwid.WidgetWrap):
global_dns_cat_t = ('header',language['global_dns_servers'])
global_dns_t = ('editcp',language['use_global_dns'])
dns_dom_t = ('editcp',' DNS Domain: ')
search_dom_t = ('editcp',' Search domain:')
dns_dom_t = ('editcp',' '+language['dns_domain']+': ')
search_dom_t = ('editcp',' '+language['search_domain']+':')
dns1_t = ('editcp',' DNS server 1: ')
dns2_t = ('editcp',' DNS server 2: ')
dns3_t = ('editcp',' DNS server 3: ')
@@ -91,6 +93,7 @@ class PrefsDialog(urwid.WidgetWrap):
dhcp1_t = 'dhclient'
dhcp2_t = 'dhcpcd'
dhcp3_t = 'pump'
dhcp4_t = 'udhcpc'
wired_detect_header_t = ('header',language["wired_detect"])
wired1_t = 'ethtool'
@@ -175,26 +178,33 @@ class PrefsDialog(urwid.WidgetWrap):
self.dhcp_header = urwid.Text(dhcp_header_t)
self.dhcp_l = []
# Automatic
# Order of these is flipped in the actual interface,
# (2,3,1 -> dhcpcd, pump, dhclient), because dhclient often doesn't like
# to work on several distros.
self.dhcp0 = urwid.RadioButton(self.dhcp_l,automatic_t)
self.dhcp1 = urwid.RadioButton(self.dhcp_l,dhcp1_t)
self.dhcp2 = urwid.RadioButton(self.dhcp_l,dhcp2_t)
self.dhcp3 = urwid.RadioButton(self.dhcp_l,dhcp3_t)
self.dhcp1 = DynRadioButton(self.dhcp_l,dhcp1_t)
self.dhcp2 = DynRadioButton(self.dhcp_l,dhcp2_t)
self.dhcp3 = DynRadioButton(self.dhcp_l,dhcp3_t)
self.dhcp4 = DynRadioButton(self.dhcp_l,dhcp4_t)
self.dhcp_l = [self.dhcp0,self.dhcp1,self.dhcp2,self.dhcp3,self.dhcp4]
self.wired_l = []
self.wired_detect_header = urwid.Text(wired_detect_header_t)
self.wired0 = urwid.RadioButton(self.wired_l,automatic_t)
self.wired1 = urwid.RadioButton(self.wired_l,wired1_t)
self.wired2 = urwid.RadioButton(self.wired_l,wired2_t)
self.wired1 = DynRadioButton(self.wired_l,wired1_t)
self.wired2 = DynRadioButton(self.wired_l,wired2_t)
self.wired_l = [self.wired0,self.wired1,self.wired2]
self.flush_l = []
self.flush_header = urwid.Text(flush_header_t)
self.flush0 = urwid.RadioButton(self.flush_l,automatic_t)
self.flush1 = urwid.RadioButton(self.flush_l,flush1_t)
self.flush2 = urwid.RadioButton(self.flush_l,flush2_t)
self.flush1 = DynRadioButton(self.flush_l,flush1_t)
self.flush2 = DynRadioButton(self.flush_l,flush2_t)
self.flush_l = [self.flush0,self.flush1,self.flush2]
externalLB = urwid.ListBox([self.dhcp_header,
self.dhcp0,self.dhcp1,self.dhcp2,self.dhcp3,
self.dhcp0,self.dhcp2,self.dhcp3,self.dhcp1,self.dhcp4,
_blank,
self.wired_detect_header,
self.wired0,self.wired1,self.wired2,
@@ -237,27 +247,10 @@ class PrefsDialog(urwid.WidgetWrap):
self.header2 : advancedLB}
#self.load_settings()
# Now for the buttons:
ok_t = 'OK'
cancel_t = 'Cancel'
ok_button = urwid.AttrWrap(urwid.Button('OK',self.ok_callback),'body','focus')
cancel_button = urwid.AttrWrap(urwid.Button('Cancel',self.cancel_callback),'body','focus')
# Variables set by the buttons' callback functions
self.CANCEL_PRESSED = False
self.OK_PRESSED = False
self.button_cols = urwid.Columns([ok_button,cancel_button],
dividechars=1)
self.tabs = TabColumns(headerList,lbList,language['preferences'],self.button_cols)
self.tabs = TabColumns(headerList,lbList,language['preferences'])
self.__super.__init__(self.tabs)
def load_settings(self):
# Reset the buttons
self.CANCEL_PRESSED = False
self.OK_PRESSED = False
### General Settings
# ComboBox does not like dbus.Strings as text markups. My fault. :/
@@ -282,13 +275,20 @@ class PrefsDialog(urwid.WidgetWrap):
self.wired_auto_l[daemon.GetWiredAutoConnectMethod()-1]
self.auto_reconn_checkb.set_state(daemon.GetAutoReconnect())
def find_avail(apps):
for app in apps[1:]:
app.set_sensitive(daemon.GetAppAvailable(app.get_label()))
### External Programs
find_avail(self.dhcp_l)
dhcp_method = daemon.GetDHCPClient()
self.dhcp_l[dhcp_method].set_state(True)
find_avail(self.wired_l)
wired_link_method = daemon.GetLinkDetectionTool()
self.wired_l[wired_link_method].set_state(True)
find_avail(self.flush_l)
flush_method = daemon.GetFlushTool()
self.flush_l[flush_method].set_state(True)
@@ -322,7 +322,7 @@ class PrefsDialog(urwid.WidgetWrap):
self.debug_mode_checkb.set_state(daemon.GetDebugMode())
self.use_dbm_checkb.set_state(daemon.GetSignalDisplayType())
def save_results(self):
def save_settings(self):
""" Pushes the selected settings to the daemon.
This exact order is found in prefs.py"""
daemon.SetUseGlobalDNS(self.global_dns_checkb.get_state())
@@ -353,8 +353,10 @@ class PrefsDialog(urwid.WidgetWrap):
dhcp_client = misc.DHCLIENT
elif self.dhcp2.get_state():
dhcp_client = misc.DHCPCD
else:
elif self.dhcp3.get_state():
dhcp_client = misc.PUMP
else:
dhcp_client = misc.UDHCPC
daemon.SetDHCPClient(dhcp_client)
if self.wired0.get_state():
@@ -378,45 +380,6 @@ class PrefsDialog(urwid.WidgetWrap):
for w in self.dns1,self.dns2,self.dns3,self.dns_dom,self.search_dom:
w.set_sensitive(new_state)
# Button callbacks
def ok_callback(self,button_object,user_data=None):
self.OK_PRESSED = True
def cancel_callback(self,button_object,user_data=None):
self.CANCEL_PRESSED = True
def ready_comboboxes(self,ui,body):
def ready_widgets(self,ui,body):
self.wpa_cbox.build_combobox(body,ui,4)
self.backend_cbox.build_combobox(body,ui,8)
# Put the widget into an overlay, and run!
def run(self,ui, dim, display):
width,height = ui.get_cols_rows()
self.load_settings()
overlay = urwid.Overlay(self.tabs, display, ('fixed left', 0),width
, ('fixed top',1), height-3)
self.ready_comboboxes(ui,overlay)
keys = True
while True:
if keys:
ui.draw_screen(dim, overlay.render(dim, True))
keys = ui.get_input()
if "window resize" in keys:
dim = ui.get_cols_rows()
if "esc" in keys or 'Q' in keys:
return False
for k in keys:
#Send key to underlying widget:
overlay.keypress(dim, k)
if urwid.is_mouse_event(k):
event, button, col, row = k
overlay.mouse_event( dim,
event, button, col, row,
focus=True)
# Check if buttons are pressed.
if self.CANCEL_PRESSED:
return False
if self.OK_PRESSED or 'meta enter' in keys:
return True

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Sun Feb 1 21:38:09 2009 -->
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkWindow" id="window1">
<property name="width_request">450</property>
<property name="height_request">400</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Wicd Network Manager</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="window_position">center</property>
<property name="default_width">550</property>
<property name="gravity">GDK_GRAVITY_CENTER</property>
<signal name="destroy" handler="exit"/>
<signal name="delete_event" handler="exit"/>
<property name="gravity">center</property>
<child>
<widget class="GtkVBox" id="background_vbox">
<property name="visible">True</property>
<child>
<widget class="GtkToolbar" id="toolbar">
<property name="visible">True</property>
<property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
<property name="icon_size">GTK_ICON_SIZE_MENU</property>
<property name="toolbar_style">both-horiz</property>
<property name="icon_size">0</property>
<property name="icon_size_set">True</property>
<child>
<widget class="GtkToolItem" id="menubar">
@@ -31,8 +29,8 @@
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="network_menu">
<property name="label">gtk-network</property>
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-network</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<child>
@@ -40,12 +38,12 @@
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="create_ad_hoc_button">
<property name="label">Create an ad-hoc network</property>
<property name="visible">True</property>
<property name="label" translatable="yes">Create an ad-hoc network</property>
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="create_adhoc_clicked"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image10">
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
</widget>
@@ -54,15 +52,15 @@
</child>
<child>
<widget class="GtkImageMenuItem" id="find_hidden_button">
<property name="label">Find a hidden network</property>
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Enter a hidden network to try to locate.</property>
<property name="label" translatable="yes">Find a hidden network</property>
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="hidden_clicked"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image9">
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="icon_name">network-wireless</property>
<property name="stock">gtk-find</property>
</widget>
</child>
</widget>
@@ -74,6 +72,9 @@
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="disconnect_button">
@@ -86,6 +87,7 @@
<signal name="clicked" handler="disconnect_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
@@ -99,6 +101,7 @@
<signal name="clicked" handler="refresh_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
@@ -112,6 +115,7 @@
<signal name="clicked" handler="preferences_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
@@ -125,6 +129,7 @@
<signal name="clicked" handler="about_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
@@ -139,12 +144,14 @@
<signal name="clicked" handler="quit_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
@@ -165,12 +172,12 @@
<widget class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<widget class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="shadow_type">none</property>
<child>
<widget class="GtkVBox" id="network_list_vbox">
<property name="visible">True</property>
@@ -198,15 +205,17 @@
</widget>
<packing>
<property name="padding">3</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Cancel the current connection attempt</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="tooltip" translatable="yes">Cancel the current connection attempt</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="cancel_clicked"/>
</widget>
<packing>
@@ -238,8 +247,8 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Configure Scripts</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
@@ -259,6 +268,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
@@ -272,6 +282,9 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Pre-connection Script:</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="pre_entry">
@@ -302,6 +315,9 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Post-connection Script:</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="post_entry">
@@ -326,15 +342,18 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkLabel" id="disconnect_label">
<widget class="GtkLabel" id="pre_disconnect_label">
<property name="width_request">150</property>
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Disconnection Script:</property>
<property name="label" translatable="yes">Pre-disconnection Script:</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="disconnect_entry">
<widget class="GtkEntry" id="pre_disconnect_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -351,6 +370,39 @@
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox10">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkLabel" id="post_disconnect_label">
<property name="width_request">150</property>
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Post-disconnection Script:</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="post_disconnect_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">4</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
@@ -359,32 +411,41 @@
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="button3">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button4">
<property name="label">gtk-ok</property>
<property name="response_id">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>
@@ -392,8 +453,8 @@
</widget>
<widget class="GtkDialog" id="pref_dialog">
<property name="border_width">5</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox5">
@@ -414,17 +475,17 @@
<widget class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<widget class="GtkViewport" id="viewport3">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="resize_mode">queue</property>
<property name="shadow_type">none</property>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">18</property>
<property name="n_rows">20</property>
<property name="n_columns">2</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
@@ -433,14 +494,14 @@
<property name="visible">True</property>
<child>
<widget class="GtkCheckButton" id="pref_prefer_wired_check">
<property name="label" translatable="yes">Always switch to a wired connection when available</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="has_tooltip">True</property>
<property name="tooltip" translatable="yes">If selected, wicd will automatically connect to a wired network
as soon as a cable is plugged in, even if a wireless connection
is already active.</property>
<property name="label" translatable="yes">Always switch to a wired connection when available</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -490,10 +551,10 @@ is already active.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkCheckButton" id="pref_auto_check">
<property name="label" translatable="yes">Automatically reconnect on network connection loss</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Automatically reconnect on network connection loss</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -525,10 +586,10 @@ is already active.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkRadioButton" id="pref_use_last_radio">
<property name="label" translatable="yes">Use last wired network profile</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use last wired network profile</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
@@ -547,10 +608,10 @@ is already active.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkRadioButton" id="pref_prompt_radio">
<property name="label" translatable="yes">Prompt for wired network profile</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Prompt for wired network profile</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">pref_use_last_radio</property>
@@ -570,10 +631,10 @@ is already active.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkRadioButton" id="pref_use_def_radio">
<property name="label" translatable="yes">Use default wired network profile</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use default wired network profile</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">pref_use_last_radio</property>
@@ -766,10 +827,10 @@ is already active.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkCheckButton" id="pref_global_check">
<property name="label" translatable="yes">Use global DNS servers</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use global DNS servers</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -840,11 +901,11 @@ is already active.</property>
<property name="left_padding">24</property>
<child>
<widget class="GtkCheckButton" id="pref_always_check">
<property name="label" translatable="yes">Always show wired interface</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip" translatable="yes">If enabled, the wired network interface will always be displayed in the main window. This can be useful if your wired network card does not detect when the interface is connected to a cable.</property>
<property name="label" translatable="yes">Always show wired interface</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -856,6 +917,41 @@ is already active.</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Notifications&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">18</property>
<property name="bottom_attach">19</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment26">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkCheckButton" id="pref_use_libnotify">
<property name="label" translatable="yes">Display notifications about connection status</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">19</property>
<property name="bottom_attach">20</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
@@ -870,8 +966,8 @@ is already active.</property>
<property name="label" translatable="yes">General Settings</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_fill">False</property>
<property name="type">tab</property>
</packing>
</child>
<child>
@@ -885,13 +981,13 @@ is already active.</property>
<widget class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<widget class="GtkViewport" id="viewport4">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="resize_mode">queue</property>
<property name="shadow_type">none</property>
<child>
<widget class="GtkTable" id="table2">
<property name="visible">True</property>
@@ -931,23 +1027,24 @@ is already active.</property>
<property name="visible">True</property>
<child>
<widget class="GtkRadioButton" id="flush_auto_radio">
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="ip_flush_radio">
<property name="label" translatable="yes">ip</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">ip</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">flush_auto_radio</property>
@@ -959,10 +1056,10 @@ is already active.</property>
</child>
<child>
<widget class="GtkRadioButton" id="route_flush_radio">
<property name="label" translatable="yes">route</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">route</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">flush_auto_radio</property>
@@ -990,23 +1087,24 @@ is already active.</property>
<property name="visible">True</property>
<child>
<widget class="GtkRadioButton" id="link_auto_radio">
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="ethtool_radio">
<property name="label" translatable="yes">ethtool</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">ethtool</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">link_auto_radio</property>
@@ -1018,10 +1116,10 @@ is already active.</property>
</child>
<child>
<widget class="GtkRadioButton" id="miitool_radio">
<property name="label" translatable="yes">mii-tool</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">mii-tool</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">link_auto_radio</property>
@@ -1049,38 +1147,54 @@ is already active.</property>
<property name="visible">True</property>
<child>
<widget class="GtkRadioButton" id="dhcp_auto_radio">
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">dhclient_radio</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="dhclient_radio">
<property name="label" translatable="yes">dhclient</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">dhclient</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="dhcpcd_radio">
<property name="label" translatable="yes">dhcpcd</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">dhclient_radio</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="dhcpcd_radio">
<widget class="GtkRadioButton" id="pump_radio">
<property name="label" translatable="yes">pump</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">dhcpcd</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">dhclient_radio</property>
@@ -1091,18 +1205,18 @@ is already active.</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="pump_radio">
<widget class="GtkRadioButton" id="udhcpc_radio">
<property name="label" translatable="yes">udhcpc</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">pump</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">dhclient_radio</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
</widget>
@@ -1147,23 +1261,24 @@ is already active.</property>
<property name="visible">True</property>
<child>
<widget class="GtkRadioButton" id="sudo_auto_radio">
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Automatic (recommended)</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="gksudo_radio">
<property name="label" translatable="yes">gksudo</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">gksudo</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">sudo_auto_radio</property>
@@ -1175,10 +1290,10 @@ is already active.</property>
</child>
<child>
<widget class="GtkRadioButton" id="kdesu_radio">
<property name="label" translatable="yes">kdesu</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">kdesu</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">sudo_auto_radio</property>
@@ -1190,10 +1305,10 @@ is already active.</property>
</child>
<child>
<widget class="GtkRadioButton" id="ktsuss_radio">
<property name="label" translatable="yes">ktsuss</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">ktsuss</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">sudo_auto_radio</property>
@@ -1228,9 +1343,9 @@ is already active.</property>
<property name="label" translatable="yes">External Programs</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="position">1</property>
<property name="tab_fill">False</property>
<property name="type">tab</property>
</packing>
</child>
<child>
@@ -1270,6 +1385,7 @@ to read its description.</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</widget>
@@ -1316,10 +1432,10 @@ to read its description.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkCheckButton" id="pref_dbm_check">
<property name="label" translatable="yes">Use dBm to measure signal strength</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use dBm to measure signal strength</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -1337,10 +1453,10 @@ to read its description.</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkCheckButton" id="pref_debug_check">
<property name="label" translatable="yes">Enable debug mode</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Enable debug mode</property>
<property name="response_id">0</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
@@ -1477,9 +1593,9 @@ WPA supplicant driver.</property>
<property name="label" translatable="yes">Advanced Settings</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="position">2</property>
<property name="tab_fill">False</property>
<property name="type">tab</property>
</packing>
</child>
</widget>
@@ -1490,34 +1606,41 @@ WPA supplicant driver.</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area5">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="button2">
<property name="label" translatable="yes">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="label" translatable="yes">gtk-ok</property>
<property name="response_id">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>

View File

@@ -153,9 +153,12 @@ case "$1" in
;;
esac
;;
status)
status_of_proc -p $PIDFILE $DAEMON $NAME
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2
exit 3
;;
esac

View File

@@ -16,8 +16,8 @@ wicd_start() {
echo "$PIDFILE and try again..."
exit 1
else
echo "Starting wicd daemon: $DAEMON"
wicd 2>/dev/null 1>&2
echo "Starting wicd daemon: $DAEMON &"
wicd 2>/dev/null 1>&2 &
fi
}

View File

@@ -3,7 +3,7 @@
### BEGIN INIT INFO
# Provides: wicd-daemon
# Required-Start: dbus
# Required-Stop:
# Required-Stop: $null
# Default-Start: 3 4 5
# Default-Stop:
# Description: wicd, a wired and wireless connection manager.

View File

@@ -1,5 +1,5 @@
.\" First revision was r203
.TH WICD-CURSES "8" "February 2009" "wicd-curses-%CURSES_REVNO%"
.TH WICD-CURSES "8" "April 2009" "wicd-curses-%CURSES_REVNO%"
.SH NAME
.B wicd-curses
\- curses-based wicd(8) controller
@@ -23,7 +23,7 @@ language of choice only uses Latin characters.
.SH CONTROLS
All of these are case sensitive.
.TP
.BR enter
.BR "C " or " enter"
Connect to selected network
.TP
.BR "F8 " or " Q " or " q"
@@ -52,7 +52,7 @@ Raise the "About wicd-curses" dialog
.\".PP
.\"The following is a work in progress and might not be fully functional as of yet.
.TP
.BR C
.BR "right-arrow"
Bring up network configuration controller for the selected network
.TP
.BR delete

View File

@@ -33,8 +33,12 @@ The script should be a Bourne-compatible script and should be executable.
IMPORTANT - scripts should ONLY be writable by root and located in a
directory that is only writable by root.
.TP
.BI "disconnectscript = " <None|arbitrary_script>
This defines a script to run when Wicd disconnects the interface.
.BI "predisconnectscript = " <None|arbitrary_script>
This defines a script to run before Wicd disconnects the interface.
The script should be a Bourne-compatible script and should be executable.
.TP
.BI "postdisconnectscript = " <None|arbitrary_script>
This defines a script to run after Wicd disconnects the interface.
The script should be a Bourne-compatible script and should be executable.
.br
IMPORTANT - scripts should ONLY be writable by root and located in a

View File

@@ -99,8 +99,11 @@ This defines a script to run after Wicd brings up the connection.
IMPORTANT - scripts should ONLY be writable by root and located
in a directory that is writable by only root.
.TP
.BI "disconnectscript = " <None|arbitrary_script>
This defines a script to run when Wicd disconnects the interface.
.BI "predisconnectscript = " <None|arbitrary_script>
This defines a script to run before Wicd disconnects the interface.
.TP
.BI "postdisconnectscript = " <None|arbitrary_script>
This defines a script to run after Wicd disconnects the interface.
.br
IMPORTANT - scripts should ONLY be writable by root and located
in a directory that is writable by only root.

View File

@@ -11,20 +11,6 @@
<allow send_interface="org.wicd.daemon.wireless"/>
<allow send_destination="org.wicd.daemon.wired"/>
<allow send_interface="org.wicd.daemon.wired"/>
<allow send_destination="org.wicd.daemon.config"/>
<allow send_interface="org.wicd.daemon.config"/>
</policy>
<policy at_console="true">
<allow send_destination="org.wicd.daemon"/>
<allow send_interface="org.wicd.daemon"/>
<allow send_destination="org.wicd.daemon.wireless"/>
<allow send_interface="org.wicd.daemon.wireless"/>
<allow send_destination="org.wicd.daemon.wired"/>
<allow send_interface="org.wicd.daemon.wired"/>
<allow send_destination="org.wicd.daemon.config"/>
<allow send_interface="org.wicd.daemon.config"/>
<allow send_interface="org.freedesktop.DBus.Introspectable"/>
</policy>
<policy context="default">
@@ -33,9 +19,29 @@
<!-- This Unix group will have permission to use Wicd's gui -->
<policy group="%WICDGROUP%">
<allow send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.wicd.daemon"/>
<allow send_interface="org.wicd.daemon"/>
<allow send_interface="org.freedesktop.DBus.Introspectable"/>
<!-- The Introspectable allow shouldn't be needed here, but
it seems that a few distributions aren't yet allowing
it in their hal configs, and we need it here, so... -->
</policy>
<!-- Comment the block below if you do not want all users logged in
locally to have permission to use wicd-client. This ignores the
group based permission model defined above for the "%WICDGROUP%"
group. Note that this only applies if you are using ConsoleKit -
if you do not have ConsoleKit installed and in use, then this
block makes no difference either way. -->
<policy at_console="true">
<allow send_destination="org.wicd.daemon"/>
<allow send_interface="org.wicd.daemon"/>
<allow send_destination="org.wicd.daemon.wireless"/>
<allow send_interface="org.wicd.daemon.wireless"/>
<allow send_destination="org.wicd.daemon.wired"/>
<allow send_interface="org.wicd.daemon.wired"/>
<allow send_interface="org.freedesktop.DBus.Introspectable"/>
</policy>
</busconfig>

View File

@@ -27,7 +27,8 @@ lib = '%LIB%'
share = '%SHARE%'
etc = '%ETC%'
scripts = '%SCRIPTS%'
disconnectscripts = '%SCRIPTS%disconnect'
predisconnectscripts = '%SCRIPTS%predisconnect'
postdisconnectscripts = '%SCRIPTS%postdisconnect'
preconnectscripts = '%SCRIPTS%preconnect'
postconnectscripts = '%SCRIPTS%postconnect'
images = '%IMAGES%'
@@ -62,6 +63,8 @@ initfile = '%INITFILE%'
# stores only the file name, i.e. wicd
initfilename = '%INITFILENAME%'
wicd_group = '%WICDGROUP%'
log_group = '%LOGGROUP%'
log_perms = '%LOGPERMS%'
# BOOLEANS
no_install_pmutils = %NO_INSTALL_PMUTILS%
@@ -71,6 +74,7 @@ no_install_kde = %NO_INSTALL_KDE%
no_install_acpi = %NO_INSTALL_ACPI%
no_install_docs = %NO_INSTALL_DOCS%
no_install_ncurses = %NO_INSTALL_NCURSES%
no_use_notifications = %NO_USE_NOTIFICATIONS%
def chdir(file):
"""Change directory to the location of the specified file.

View File

@@ -1 +0,0 @@
wicd=wpath.py.in

View File

@@ -1,6 +1,6 @@
.TH WICD-CLIENT "1" "September 2008" "wicd-client " "User Commands"
.TH WICD-CLIENT "1" "June 2009" "wicd-client " "User Commands"
.SH NAME
wicd-client \- manual page for wicd-client
wicd-client \- frontend to the WICD daemon
.SH DESCRIPTION
wireless (and wired) connection daemon front\-end.

View File

@@ -1,6 +1,5 @@
[Desktop Entry]
Categories=Application;Network;
Encoding=UTF-8
Exec=wicd-client
GenericName=Network Manager
Icon=wicd-client

View File

@@ -1,6 +1,5 @@
[Desktop Entry]
Categories=Application;Network;
Encoding=UTF-8
Exec=wicd-client --no-tray
GenericName=Network Manager
Icon=wicd-client

View File

@@ -1,2 +1,4 @@
[install]
record = install.log
[bdist_rpm]
group = Productivity/Networking/System

212
setup.py
View File

@@ -2,6 +2,7 @@
#
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
# Copyright (C) 2009 Andrew Psaltis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -19,19 +20,22 @@
from distutils.core import setup, Command
from distutils.extension import Extension
import os
import shutil
import sys
import shutil
import subprocess
# Be sure to keep this updated!
# VERSIONNUMBER
VERSION_NUM = '1.6.0a1'
VERSION_NUM = '1.6.2'
# REVISION_NUM is automatically updated
REVISION_NUM = 'unknown'
CURSES_REVNO = 'r279'
CURSES_REVNO = 'uimod'
# change to the directory setup.py is contained in
os.chdir(os.path.abspath(os.path.split(__file__)[0]))
try:
if not os.path.exists('vcsinfo.py'):
if os.path.exists('.bzr') and os.system('bzr > /dev/null 2>&1') == 0:
try:
os.system('bzr version-info --python > vcsinfo.py')
except:
@@ -42,7 +46,6 @@ except Exception, e:
print 'failed to find revision number:'
print e
class configure(Command):
description = "configure the paths that Wicd will be installed to"
@@ -83,6 +86,9 @@ class configure(Command):
('initfile=', None, 'set the init file to use'),
('initfilename=', None, "set the name of the init file (don't use)"),
('wicdgroup=', None, "set the name of the group used for wicd"),
('distro=', None, 'set the distribution for which wicd will be installed'),
('loggroup=', None, 'the group the log file belongs to'),
('logperms=', None, 'the log file permissions'),
# Configure switches
('no-install-init', None, "do not install the init file"),
@@ -91,7 +97,8 @@ class configure(Command):
('no-install-acpi', None, 'do not install the suspend.d and resume.d acpi scripts'),
('no-install-pmutils', None, 'do not install the pm-utils hooks'),
('no-install-docs', None, 'do not install the auxiliary documentation'),
('no-install-ncurses', None, 'do not install the ncurses client')
('no-install-ncurses', None, 'do not install the ncurses client'),
('no-use-notifications', None, 'do not ever allow the use of libnotify notifications')
]
def initialize_options(self):
@@ -118,6 +125,7 @@ class configure(Command):
self.docdir = '/usr/share/doc/wicd/'
self.mandir = '/usr/share/man/'
self.kdedir = '/usr/share/autostart/'
self.distro = 'auto'
self.no_install_init = False
self.no_install_man = False
@@ -126,51 +134,41 @@ class configure(Command):
self.no_install_pmutils = False
self.no_install_docs = False
self.no_install_ncurses = False
self.no_use_notifications = False
# Determine the default init file location on several different distros
self.distro_detect_failed = False
self.initfile = 'init/default/wicd'
# ddistro is the detected distro
if os.path.exists('/etc/redhat-release'):
self.init = '/etc/rc.d/init.d/'
self.initfile = 'init/redhat/wicd'
self.ddistro = 'redhat'
elif os.path.exists('/etc/SuSE-release'):
self.init = '/etc/init.d/'
self.initfile = 'init/suse/wicd'
self.ddistro = 'suse'
elif os.path.exists('/etc/fedora-release'):
self.init = '/etc/rc.d/init.d/'
self.initfile = 'init/redhat/wicd'
self.ddistro = 'redhat'
elif os.path.exists('/etc/gentoo-release'):
self.init = '/etc/init.d/'
self.initfile = 'init/gentoo/wicd'
self.ddistro = 'gentoo'
elif os.path.exists('/etc/debian_version'):
self.init = '/etc/init.d/'
self.initfile = 'init/debian/wicd'
self.ddistro = 'debian'
elif os.path.exists('/etc/arch-release'):
self.init = '/etc/rc.d/'
self.initfile = 'init/arch/wicd'
self.ddistro = 'arch'
elif os.path.exists('/etc/slackware-version') or \
os.path.exists('/etc/slamd64-version'):
self.init = '/etc/rc.d/'
self.initfile = 'init/slackware/rc.wicd'
self.docdir = '/usr/doc/wicd-%s' % VERSION_NUM
self.mandir = '/usr/man/'
self.no_install_acpi = True
os.path.exists('/etc/slamd64-version') or \
os.path.exists('/etc/bluewhite64-version'):
self.ddistro = 'slackware'
elif os.path.exists('/etc/pld-release'):
self.init = '/etc/rc.d/init.d/'
self.initfile = 'init/pld/wicd'
self.ddistro = 'pld'
elif os.path.exists('/usr/bin/crux'):
self.init = '/etc/rc.d/'
self.ddistro = 'crux'
elif os.path.exists('/etc/lunar.release'):
self.init='/etc/init.d/'
self.initfile = 'init/lunar/wicd'
self.distro = 'lunar'
else:
self.init = 'FAIL'
self.no_install_init = True
self.distro_detect_failed = True
self.ddistro = 'FAIL'
#self.no_install_init = True
#self.distro_detect_failed = True
print 'WARNING: Unable to detect the distribution in use. ' + \
'If you have specified --init and --initfile, configure will continue. ' + \
'If you have specified --distro or --init and --initfile, configure will continue. ' + \
'Please report this warning, along with the name of your ' + \
'distribution, to the wicd developers.'
@@ -225,8 +223,58 @@ class configure(Command):
self.pidfile = '/var/run/wicd/wicd.pid'
self.initfilename = os.path.basename(self.initfile)
self.wicdgroup = 'users'
self.loggroup = ''
self.logperms = '0600'
def distro_check(self):
print "Distro is: "+self.distro
if self.distro in ['sles','suse']:
self.init = '/etc/init.d/'
self.initfile = 'init/suse/wicd'
elif self.distro in ['redhat','centos','fedora']:
self.init = '/etc/rc.d/init.d/'
self.initfile = 'init/redhat/wicd'
elif self.distro in ['slackware','slamd64','bluewhite64']:
self.init = '/etc/rc.d/'
self.initfile = 'init/slackware/rc.wicd'
self.docdir = '/usr/doc/wicd-%s' % VERSION_NUM
self.mandir = '/usr/man/'
self.no_install_acpi = True
elif self.distro in ['debian']:
self.wicdgroup = "netdev"
self.loggroup = "adm"
self.logperms = "0640"
self.init = '/etc/init.d/'
self.initfile = 'init/debian/wicd'
elif self.distro in ['arch']:
self.init = '/etc/rc.d/'
self.initfile = 'init/arch/wicd'
elif self.distro in ['gentoo']:
self.init = '/etc/init.d/'
self.initfile = 'init/gentoo/wicd'
elif self.distro in ['pld']:
self.init = '/etc/rc.d/init.d/'
self.initfile = 'init/pld/wicd'
elif self.distro in ['crux']:
self.init = '/etc/rc.d/'
elif self.distro in ['lunar']:
self.init='/etc/init.d/'
self.initfile = 'init/lunar/wicd'
else :
if self.distro == 'auto':
print "NOTICE: Automatic distro detection found: "+self.ddistro+", retrying with that..."
self.distro = self.ddistro
self.distro_check()
else:
print "WARNING: Distro detection failed!"
self.init='init/default/wicd'
self.no_install_init = True
self.distro_detect_failed = True
def finalize_options(self):
self.distro_check()
if self.distro_detect_failed and not self.no_install_init and \
'FAIL' in [self.init, self.initfile]:
print 'ERROR: Failed to detect distro. Configure cannot continue. ' + \
@@ -331,6 +379,26 @@ class test(Command):
print 'running tests'
tests.run_tests()
class update_translations_py(Command):
description = "download new translations.py from the online translator"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
import urllib, shutil
# grab translations.py
filename, headers = urllib.urlretrieve('http://wicd.net/translator/generate/translations.py/')
# copy it into the right location
shutil.copyfile(filename,
os.path.join(os.path.dirname(os.path.realpath(__file__)),
'wicd/translations.py'))
class get_translations(Command):
description = "download the translations from the online translator"
@@ -344,30 +412,29 @@ class get_translations(Command):
def run(self):
import urllib, shutil
shutil.rmtree('translations/')
if os.path.exists('translations'):
shutil.rmtree('translations/')
os.makedirs('translations')
filename, headers = urllib.urlretrieve('http://wicd.net/translator/idlist')
filename, headers = urllib.urlretrieve('http://wicd.sourceforge.net/translator/idlist/')
id_file = open(filename, 'r')
lines = id_file.readlines()
# remove the \n from the end of lines, and remove blank entries
lines = [ x.strip() for x in lines if not x.strip() is '' ]
for id in lines:
# http://wicd.net/translator/download_po.php?language=11
pofile, poheaders = urllib.urlretrieve('http://wicd.net/translator/download/'+str(id))
#for i in `cat ids`; do
#wget "http://wicd.sourceforge.net/translator/download_po.php?language=$i&version=$1" -O "language_$i"
#iden=`python -c "import sys; print open('language_$i','r').readlines()[1].strip()[2:]"`
#mv "language_$i" po/$iden.po
#mkdir -p $iden/LC_MESSAGES/
#msgfmt --output-file=$iden/LC_MESSAGES/wicd.mo po/$iden.po
lang_identifier = open(pofile,'r').readlines()[0].strip()
lang_identifier = lang_identifier[lang_identifier.rindex('(')+1:lang_identifier.rindex(')')]
shutil.move(pofile, lang_identifier+'.po')
print 'Got',lang_identifier
os.makedirs('translations/'+lang_identifier+'/LC_MESSAGES')
os.system('msgfmt --output-file=translations/' + lang_identifier +
'/LC_MESSAGES/wicd.mo ' + lang_identifier + '.po')
os.remove(lang_identifier+'.po')
pofile, poheaders = urllib.urlretrieve('http://wicd.sourceforge.net/translator/download/'+str(id)+'/')
try:
lang_identifier = open(pofile,'r').readlines()[0].strip()
first_line = lang_identifier
lang_identifier = lang_identifier[lang_identifier.rindex('(')+1:lang_identifier.rindex(')')]
print first_line
except:
print >> sys.stderr, 'error downloading language %s' % id
else:
shutil.move(pofile, lang_identifier+'.po')
os.makedirs('translations/'+lang_identifier+'/LC_MESSAGES')
os.system('msgfmt --output-file=translations/' + lang_identifier +
'/LC_MESSAGES/wicd.mo ' + lang_identifier + '.po')
os.remove(lang_identifier+'.po')
class uninstall(Command):
@@ -383,7 +450,6 @@ class uninstall(Command):
def run(self):
os.system("./uninstall.sh")
try:
import wpath
except ImportError:
@@ -425,7 +491,8 @@ try:
(wpath.backends, ['wicd/backends/be-external.py', 'wicd/backends/be-ioctl.py']),
(wpath.autostart, ['other/wicd-tray.desktop', ]),
(wpath.scripts, []),
(wpath.disconnectscripts, []),
(wpath.predisconnectscripts, []),
(wpath.postdisconnectscripts, []),
(wpath.preconnectscripts, []),
(wpath.postconnectscripts, []),
]
@@ -459,34 +526,32 @@ try:
data.append((wpath.resume, ['other/80-wicd-connect.sh' ]))
data.append((wpath.suspend, ['other/50-wicd-suspend.sh' ]))
if not wpath.no_install_pmutils:
data.append((wpath.pmutils, ['other/55wicd' ]))
data.append((wpath.pmutils, ['other/91wicd' ]))
print 'Using pid path', os.path.basename(wpath.pidfile)
print 'Language support for',
for language in os.listdir('translations/'):
if not language.startswith('.'):
codes = language.split('_')
short_language = language
if codes[0].lower() == codes[1].lower():
short_language = codes[0].lower()
print short_language,
data.append((wpath.translations + short_language + '/LC_MESSAGES/',
['translations/' + language + '/LC_MESSAGES/wicd.mo']))
print language,
data.append((wpath.translations + language + '/LC_MESSAGES/',
['translations/' + language + '/LC_MESSAGES/wicd.mo']))
print
except Exception, e:
print str(e)
print '''Error setting up data array. This is normal if
python setup.py configure has not yet been run.'''
wpactrl_ext = Extension(name = 'wpactrl',
sources = ['depends/python-wpactrl/wpa_ctrl.c',
'depends/python-wpactrl/wpactrl.c'],
extra_compile_args = ["-fno-strict-aliasing"])
wpactrl_ext = Extension(name='wpactrl',
sources=['depends/python-wpactrl/wpa_ctrl.c',
'depends/python-wpactrl/wpactrl.c'],
extra_compile_args=["-fno-strict-aliasing"])
iwscan_ext = Extension(name = 'iwscan', libraries = ['iw'],
sources = ['depends/python-iwscan/pyiwscan.c'])
iwscan_ext = Extension(name='iwscan', libraries=['iw'],
sources=['depends/python-iwscan/pyiwscan.c'])
setup(cmdclass={'configure' : configure, 'get_translations' : get_translations,
'uninstall' : uninstall, 'test' : test, 'clear_generated' : clear_generated},
'uninstall' : uninstall, 'test' : test, 'clear_generated' :
clear_generated, 'update_translations_py' :
update_translations_py},
name="Wicd",
version=VERSION_NUM,
description="A wireless and wired network manager",
@@ -495,17 +560,16 @@ Wicd supports wired and wireless networks, and capable of
creating and tracking profiles for both. It has a
template-based wireless encryption system, which allows the user
to easily add encryption methods used. It ships with some common
encryption types, such as WPA and WEP. Wicdl will automatically
encryption types, such as WPA and WEP. Wicd will automatically
connect at startup to any preferred network within range.
""",
author="Adam Blackburn, Dan O'Reilly",
author_email="compwiz18@gmail.com, oreilldf@gmail.com",
author="Adam Blackburn, Dan O'Reilly, Andrew Psaltis",
author_email="compwiz18@gmail.com, oreilldf@gmail.com, ampsaltis@gmail.com",
url="http://wicd.net",
license="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html",
py_modules=['wicd.networking','wicd.misc','wicd.gui','wicd.wnettools',
'wicd.wpath','wicd.prefs','wicd.netentry','wicd.dbusmanager',
'wicd.logfile','wicd.backend','wicd.configmanager',
'wicd.guiutil','wicd.translations'],
ext_modules=[iwscan_ext, wpactrl_ext],
data_files=data
)

View File

@@ -1,8 +1,10 @@
#!/usr/bin/python
""" autoconnect -- Triggers an automatic connection attempt. """
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -21,7 +23,6 @@ from wicd import dbusmanager
import dbus
import time
import gobject
import sys
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):

View File

@@ -7,8 +7,8 @@ Manages and loads the pluggable backends for wicd.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as

View File

@@ -13,8 +13,8 @@ class WirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -29,15 +29,10 @@ class WirelessInterface() -- Control a wireless network interface.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from wicd import misc
from wicd import wnettools
from wicd.wnettools import *
import re
import os
import os.path
from wicd.wnettools import GetDefaultGateway, GetWiredInterfaces, \
GetWirelessInterfaces, IsValidWpaSuppDriver, BaseWirelessInterface, \
BaseWiredInterface, BaseInterface
# Regular expressions for wpa_cli output
auth_patten = re.compile('.*wpa_state=(.*?)\n', wnettools.__re_mode)
NAME = "external"
UPDATE_INTERVAL = 5
DESCRIPTION = """External app (original) backend
@@ -49,15 +44,13 @@ it doesn't require any third party libraries and may be
more stable for some set ups.
"""
RALINK_DRIVER = 'ralink legacy'
def NeedsExternalCalls(*args, **kargs):
""" Return True, since this backend using iwconfig/ifconfig. """
""" Return True, since this backend uses iwconfig/ifconfig. """
return True
class Interface(wnettools.BaseInterface):
class Interface(BaseInterface):
""" Control a network interface. """
def __init__(self, iface, verbose=False):
""" Initialize the object.
@@ -67,11 +60,11 @@ class Interface(wnettools.BaseInterface):
verbose -- whether to print every command run
"""
wnettools.BaseInterface.__init__(self, iface, verbose)
BaseInterface.__init__(self, iface, verbose)
self.Check()
class WiredInterface(Interface, wnettools.BaseWiredInterface):
class WiredInterface(Interface, BaseWiredInterface):
""" Control a wired network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the wired network interface class.
@@ -81,11 +74,11 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
verbose -- print all commands
"""
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
BaseWiredInterface.__init__(self, iface, verbose)
Interface.__init__(self, iface, verbose)
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
class WirelessInterface(Interface, BaseWirelessInterface):
""" Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'):
""" Initialise the wireless network interface class.
@@ -95,7 +88,5 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
verbose -- print all commands
"""
wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
wpa_driver)
BaseWirelessInterface.__init__(self, iface, verbose, wpa_driver)
Interface.__init__(self, iface, verbose)

View File

@@ -14,8 +14,8 @@ class WirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -31,13 +31,23 @@ class WirelessInterface() -- Control a wireless network interface.
#
from wicd import misc
from wicd import wnettools
from wicd import wpath
from wicd.wnettools import *
from wicd.wnettools import wep_pattern, signaldbm_pattern, neediface
from wicd.wnettools import GetDefaultGateway, GetWiredInterfaces, \
GetWirelessInterfaces, IsValidWpaSuppDriver, BaseWirelessInterface, \
BaseWiredInterface, BaseInterface, wep_pattern, signaldbm_pattern, neediface
import iwscan
import wpactrl
try:
import iwscan
IWSCAN_AVAIL = True
except ImportError:
print "WARNING: python-iwscan not found, falling back to using iwlist scan."
IWSCAN_AVAIL = False
try:
import wpactrl
WPACTRL_AVAIL = True
except ImportError:
print "WARNING: python-wpactrl not found, falling back to using wpa_cli."
WPACTRL_AVAIL = False
import re
import os
@@ -56,7 +66,7 @@ This backend uses IOCTL calls and python libraries to query
network information whenever possible. This makes it fast,
but it may not work properly on all systems.
Dependencies:
(Optional) Dependencies:
python-wpactrl (http://projects.otaku42.de/wiki/PythonWpaCtrl)
python-iwscan (http://projects.otaku42.de/browser/python-iwscan/)"""
@@ -105,7 +115,7 @@ def NeedsExternalCalls(*args, **kargs):
return False
class Interface(wnettools.BaseInterface):
class Interface(BaseInterface):
""" Control a network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the object.
@@ -115,14 +125,14 @@ class Interface(wnettools.BaseInterface):
verbose -- whether to print every command run
"""
wnettools.BaseInterface.__init__(self, iface, verbose)
BaseInterface.__init__(self, iface, verbose)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.Check()
def CheckWirelessTools(self):
""" Check for the existence needed wireless tools """
# We don't need any external apps so just return
pass
if not WPACTRL_AVAIL:
BaseInterface.CheckWirelessTools(self)
@neediface("")
def GetIP(self, ifconfig=""):
@@ -162,7 +172,7 @@ class Interface(wnettools.BaseInterface):
return bool(flags & 1)
class WiredInterface(Interface, wnettools.BaseWiredInterface):
class WiredInterface(Interface, BaseWiredInterface):
""" Control a wired network interface. """
def __init__(self, iface, verbose=False):
""" Initialise the wired network interface class.
@@ -172,7 +182,7 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
verbose -- print all commands
"""
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
BaseWiredInterface.__init__(self, iface, verbose)
Interface.__init__(self, iface, verbose)
@neediface(False)
@@ -240,7 +250,7 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
return bool(reg & 0x0004)
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
class WirelessInterface(Interface, BaseWirelessInterface):
""" Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'):
""" Initialise the wireless network interface class.
@@ -250,10 +260,11 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
verbose -- print all commands
"""
wnettools.BaseWirelessInterface.__init__(self, iface, verbose,
BaseWirelessInterface.__init__(self, iface, verbose,
wpa_driver)
Interface.__init__(self, iface, verbose)
self.scan_iface = None
self.CheckWirelessTools()
@neediface([])
def GetNetworks(self):
@@ -263,6 +274,10 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
A list containing available wireless networks.
"""
if not IWSCAN_AVAIL:
# Use the slow version if python-iwscan isn't available.
return BaseWirelessInterface.GetNetworks(self)
if not self.scan_iface:
try:
self.scan_iface = iwscan.WirelessInterface(self.iface)
@@ -273,7 +288,7 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
try:
results = self.scan_iface.Scan()
except iwscan.error, e:
print "ERROR: %s"
print "ERROR: %s" % e
return []
return filter(None, [self._parse_ap(cell) for cell in results])
@@ -361,9 +376,10 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
False otherwise.
"""
error= "Unable to find ctrl_interface for wpa_supplicant. " + \
"Could not validate authentication."
if not WPACTRL_AVAIL:
# If we don't have python-wpactrl, use the slow version.
return BaseWirelessInterface.ValidateAuthentication(self, auth_time)
# Right now there's no way to do this for ralink drivers
if self.wpa_driver == RALINK_DRIVER:
return True
@@ -391,7 +407,6 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
except ValueError:
return False
result = result
if result.endswith("COMPLETED"):
return True
elif result.endswith("DISCONNECTED"):
@@ -410,6 +425,8 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
@neediface(False)
def StopWPA(self):
""" Terminates wpa_supplicant using its ctrl interface. """
if not WPACTRL_AVAIL:
return BaseWirelessInterface.StopWPA(self)
wpa = self._connect_to_wpa_ctrl_iface()
if not wpa:
return

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
""" Wicd Configuration Manager
""" configmanager -- Wicd configuration file manager
Wrapper around ConfigParser for wicd, though it should be
reusable for other purposes as well.
@@ -8,8 +8,8 @@ reusable for other purposes as well.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -28,6 +28,7 @@ from ConfigParser import RawConfigParser
from wicd.misc import Noneify, to_unicode
from dbus import Int32
class ConfigManager(RawConfigParser):
""" A class that can be used to manage a given configuration file. """
@@ -105,10 +106,17 @@ class ConfigManager(RawConfigParser):
# Try to intelligently handle the type of the return value.
try:
ret = int(ret)
except (ValueError, TypeError):
if not ret.startswith('0') or len(ret) == 1:
ret = int(ret)
except (ValueError, TypeError, AttributeError):
ret = Noneify(ret)
return ret
# This is a workaround for a python-dbus issue on 64-bit systems.
if isinstance(ret, (int, long)):
try:
Int32(ret)
except OverflowError:
ret = str(ret)
return to_unicode(ret)
def get(self, *args, **kargs):
""" Calls the get_option method """

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
""" Configure the scripts for a particular network.
""" configscript -- Configure the scripts for a particular network.
Script for configuring the scripts for a network passed in as a
command line argument. This needs to run a separate process because
@@ -10,8 +10,8 @@ run as the current user.
"""
#
# Copyright (C) 2007-2008 Adam Blackburn
# Copyright (C) 2007-2008 Dan O'Reilly
# Copyright (C) 2007-2009 Adam Blackburn
# Copyright (C) 2007-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -33,16 +33,17 @@ import ConfigParser
import gtk.glade
from wicd import wpath
from wicd import misc
from wicd import translations
from wicd import dbusmanager
_ = misc.get_gettext()
_ = translations.get_gettext()
language = {}
language['configure_scripts'] = _("Configure Scripts")
language['before_script'] = _("Pre-connection Script")
language['after_script'] = _("Post-connection Script")
language['disconnect_script'] = _("Disconnection Script")
language['pre_disconnect_script'] = _("Pre-disconnection Script")
language['post_disconnect_script'] = _("Post-disconnection Script")
dbus = dbusmanager.DBusManager()
dbus.connect_to_dbus()
@@ -100,14 +101,16 @@ def get_script_info(network, network_type):
if con.has_section(network):
info["pre_entry"] = get_val(con, network, "beforescript")
info["post_entry"] = get_val(con, network, "afterscript")
info["disconnect_entry"] = get_val(con, network, "disconnectscript")
info["pre_disconnect_entry"] = get_val(con, network, "predisconnectscript")
info["post_disconnect_entry"] = get_val(con, network, "postdisconnectscript")
else:
bssid = wireless.GetWirelessProperty(int(network), "bssid")
con.read(wireless_conf)
if con.has_section(bssid):
info["pre_entry"] = get_val(con, bssid, "beforescript")
info["post_entry"] = get_val(con, bssid, "afterscript")
info["disconnect_entry"] = get_val(con, bssid, "disconnectscript")
info["pre_disconnect_entry"] = get_val(con, bssid, "predisconnectscript")
info["post_disconnect_entry"] = get_val(con, bssid, "postdisconnectscript")
return info
def write_scripts(network, network_type, script_info):
@@ -120,7 +123,8 @@ def write_scripts(network, network_type, script_info):
con.add_section(network)
con.set(network, "beforescript", script_info["pre_entry"])
con.set(network, "afterscript", script_info["post_entry"])
con.set(network, "disconnectscript", script_info["disconnect_entry"])
con.set(network, "predisconnectscript", script_info["pre_disconnect_entry"])
con.set(network, "postdisconnectscript", script_info["post_disconnect_entry"])
con.write(open(wired_conf, "w"))
wired.ReloadConfig()
wired.ReadWiredNetworkProfile(network)
@@ -132,7 +136,8 @@ def write_scripts(network, network_type, script_info):
con.add_section(bssid)
con.set(bssid, "beforescript", script_info["pre_entry"])
con.set(bssid, "afterscript", script_info["post_entry"])
con.set(bssid, "disconnectscript", script_info["disconnect_entry"])
con.set(bssid, "predisconnectscript", script_info["pre_disconnect_entry"])
con.set(bssid, "postdisconnectscript", script_info["post_disconnect_entry"])
con.write(open(wireless_conf, "w"))
wireless.ReloadConfig()
wireless.ReadWirelessNetworkProfile(int(network))
@@ -155,25 +160,30 @@ def main (argv):
dialog = wTree.get_widget("configure_script_dialog")
wTree.get_widget("pre_label").set_label(language['before_script'] + ":")
wTree.get_widget("post_label").set_label(language['after_script'] + ":")
wTree.get_widget("disconnect_label").set_label(language['disconnect_script']
wTree.get_widget("pre_disconnect_label").set_label(language['pre_disconnect_script']
+ ":")
wTree.get_widget("post_disconnect_label").set_label(language['post_disconnect_script']
+ ":")
wTree.get_widget("window1").hide()
pre_entry = wTree.get_widget("pre_entry")
post_entry = wTree.get_widget("post_entry")
disconnect_entry = wTree.get_widget("disconnect_entry")
pre_disconnect_entry = wTree.get_widget("pre_disconnect_entry")
post_disconnect_entry = wTree.get_widget("post_disconnect_entry")
pre_entry.set_text(none_to_blank(script_info.get("pre_entry")))
post_entry.set_text(none_to_blank(script_info.get("post_entry")))
disconnect_entry.set_text(none_to_blank(script_info.get("disconnect_entry")))
pre_disconnect_entry.set_text(none_to_blank(script_info.get("pre_disconnect_entry")))
post_disconnect_entry.set_text(none_to_blank(script_info.get("post_disconnect_entry")))
dialog.show_all()
result = dialog.run()
if result == 1:
script_info["pre_entry"] = blank_to_none(pre_entry.get_text())
script_info["post_entry"] = blank_to_none(post_entry.get_text())
script_info["disconnect_entry"] = blank_to_none(disconnect_entry.get_text())
script_info["pre_disconnect_entry"] = blank_to_none(pre_disconnect_entry.get_text())
script_info["post_disconnect_entry"] = blank_to_none(post_disconnect_entry.get_text())
write_scripts(network, network_type, script_info)
dialog.destroy()

View File

@@ -7,8 +7,8 @@ A module for managing wicd's dbus interfaces.
"""
#
# Copyright (C) 2008 Adam Blackburn
# Copyright (C) 2008 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -24,7 +24,6 @@ A module for managing wicd's dbus interfaces.
#
import dbus
from dbus import DBusException
if getattr(dbus, "version", (0, 0, 0)) < (0, 80, 0):
import dbus.glib
else:

View File

@@ -1,15 +1,14 @@
#!/usr/bin/python
""" Wicd GUI module.
""" gui -- The main wicd GUI module.
Module containg all the code (other than the tray icon) related to the
Wicd user interface.
Module containing the code for the main wicd GUI.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2007-2009 Adam Blackburn
# Copyright (C) 2007-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -32,7 +31,6 @@ import pango
import gtk
import gtk.glade
from dbus import DBusException
from dbus import version as dbus_version
from wicd import misc
from wicd import wpath
@@ -42,7 +40,7 @@ from wicd import netentry
from wicd.misc import noneToString
from wicd.netentry import WiredNetworkEntry, WirelessNetworkEntry
from wicd.prefs import PreferencesDialog
from wicd.guiutil import error, GreyLabel, LabelEntry, SmallLabel
from wicd.guiutil import error, LabelEntry
from wicd.translations import language
if __name__ == '__main__':
@@ -58,7 +56,9 @@ def setup_dbus(force=True):
except DBusException:
if force:
print "Can't connect to the daemon, trying to start it automatically..."
misc.PromptToStartDaemon()
if not misc.PromptToStartDaemon():
print "Failed to find a graphical sudo program, cannot continue."
return False
try:
dbusmanager.connect_to_dbus()
except DBusException:
@@ -141,13 +141,16 @@ class WiredProfileChooser:
class appGui(object):
""" The main wicd GUI class. """
def __init__(self, standalone=False):
def __init__(self, standalone=False, tray=None):
""" Initializes everything needed for the GUI. """
setup_dbus()
self.tray = tray
gladefile = os.path.join(wpath.share, "wicd.glade")
self.wTree = gtk.glade.XML(gladefile)
self.window = self.wTree.get_widget("window1")
self.window.set_icon_name("wicd-client")
size = daemon.ReadWindowSize("main")
width = size[0]
height = size[1]
@@ -283,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. """
@@ -304,7 +311,7 @@ class appGui(object):
def settings_dialog(self, widget, event=None):
""" Displays a general settings dialog. """
if not self.pref:
self.pref = PreferencesDialog(self.wTree)
self.pref = PreferencesDialog(self, self.wTree)
else:
self.pref.load_preferences_diag()
if self.pref.run() == 1:
@@ -508,11 +515,11 @@ class appGui(object):
printLine = True # In this case we print a separator.
wirednet = WiredNetworkEntry()
self.network_list.pack_start(wirednet, False, False)
wirednet.connect_button.connect("button-press-event", self.connect,
wirednet.connect_button.connect("clicked", self.connect,
"wired", 0, wirednet)
wirednet.disconnect_button.connect("button-press-event", self.disconnect,
wirednet.disconnect_button.connect("clicked", self.disconnect,
"wired", 0, wirednet)
wirednet.advanced_button.connect("button-press-event",
wirednet.advanced_button.connect("clicked",
self.edit_advanced, "wired", 0,
wirednet)
@@ -530,13 +537,13 @@ class appGui(object):
printLine = True
tempnet = WirelessNetworkEntry(x)
self.network_list.pack_start(tempnet, False, False)
tempnet.connect_button.connect("button-press-event",
tempnet.connect_button.connect("clicked",
self.connect, "wireless", x,
tempnet)
tempnet.disconnect_button.connect("button-press-event",
tempnet.disconnect_button.connect("clicked",
self.disconnect, "wireless",
x, tempnet)
tempnet.advanced_button.connect("button-press-event",
tempnet.advanced_button.connect("clicked",
self.edit_advanced, "wireless",
x, tempnet)
else:
@@ -595,7 +602,7 @@ class appGui(object):
return True
def edit_advanced(self, widget, event, ttype, networkid, networkentry):
def edit_advanced(self, widget, ttype, networkid, networkentry):
""" Display the advanced settings dialog.
Displays the advanced settings dialog and saves any changes made.
@@ -635,7 +642,7 @@ class appGui(object):
for entry_info in encryption_info.itervalues():
if entry_info[0].entry.get_text() == "" and \
entry_info[1] == 'required':
error(self, "%s (%s)" % (language['encrypt_info_missing'],
error(self.window, "%s (%s)" % (language['encrypt_info_missing'],
entry_info[0].label.get_label())
)
return False
@@ -646,21 +653,47 @@ class appGui(object):
return False
return True
def connect(self, widget, event, nettype, networkid, networkentry):
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. """
cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(True)
def handler(*args):
self._connect_thread_started = True
def setup_interface_for_connection():
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)
self.edit_advanced(None, nettype, networkid, networkentry)
return False
wireless.ConnectWireless(networkid)
setup_interface_for_connection()
wireless.ConnectWireless(networkid, reply_handler=handler,
error_handler=handler)
elif nettype == "wired":
wired.ConnectWired()
self.update_statusbar()
setup_interface_for_connection()
wired.ConnectWired(reply_handler=handler, error_handler=handler)
def disconnect(self, widget, event, nettype, networkid, networkentry):
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.
Keyword arguments:
@@ -671,13 +704,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.
@@ -707,7 +745,7 @@ class appGui(object):
try:
daemon.WriteWindowSize(width, height, "main")
daemon.SetGUIOpen(False)
except dbusmanager.DBusException:
except DBusException:
pass
if self.standalone:

View File

@@ -1,7 +1,7 @@
""" guiutil - A collection of commonly used gtk/gui functions and classes. """
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -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)
@@ -146,5 +174,5 @@ class GreyLabel(gtk.Label):
gtk.Label.__init__(self)
def set_label(self, text):
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
self.set_markup(text)
self.set_alignment(0, 0)

View File

@@ -2,7 +2,7 @@
#
# Copyright (C) 1999-2006 Keith Dart <keith@kdart.com>
# Copyright (C) 2008 Dan O'Reilly <oreilldf@gmail.com>
# Copyright (C) 2008-2009 Dan O'Reilly <oreilldf@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,6 @@ import sys
import os
import time
import wicd.wpath as wpath
class SizeError(IOError):
pass

View File

@@ -1,8 +1,13 @@
""" Misc - miscellaneous functions for wicd """
""" misc - miscellaneous functions for wicd
This module contains a large variety of utility functions used
throughout wicd.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -44,6 +49,7 @@ AUTO = 0
DHCLIENT = 1
DHCPCD = 2
PUMP = 3
UDHCPC = 4
# Link detection tools
ETHTOOL = 1
@@ -68,7 +74,6 @@ class WicdError(Exception):
pass
__LANG = None
def Run(cmd, include_stderr=False, return_pipe=False,
return_obj=False, return_retcode=True):
""" Run a command.
@@ -88,7 +93,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
for the command that was run.
"""
global __LANG
if not isinstance(cmd, list):
cmd = to_unicode(str(cmd))
cmd = cmd.split()
@@ -105,11 +109,9 @@ def Run(cmd, include_stderr=False, return_pipe=False,
# We need to make sure that the results of the command we run
# are in English, so we set up a temporary environment.
if not __LANG:
__LANG = get_good_lang()
tmpenv = os.environ.copy()
tmpenv["LC_ALL"] = __LANG
tmpenv["LANG"] = __LANG
tmpenv["LC_ALL"] = "C"
tmpenv["LANG"] = "C"
try:
f = Popen(cmd, shell=False, stdout=PIPE, stdin=std_in, stderr=err,
@@ -118,7 +120,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
print "Running command %s failed: %s" % (str(cmd), str(e))
return ""
if return_obj:
return f
if return_pipe:
@@ -126,14 +127,6 @@ def Run(cmd, include_stderr=False, return_pipe=False,
else:
return f.communicate()[0]
def get_good_lang():
""" Check if en_US.utf8 is an available locale, if not use C. """
output = Popen(["locale", "-a"], shell=False, stdout=PIPE).communicate()[0]
if "en_US.utf8" in output:
return "en_US.utf8"
else:
return "C"
def LaunchAndWait(cmd):
""" Launches the given program with the given arguments, then blocks.
@@ -163,6 +156,8 @@ def PromptToStartDaemon():
""" Prompt the user to start the daemon """
daemonloc = wpath.sbin + 'wicd'
sudo_prog = choose_sudo_prog()
if not sudo_prog:
return False
if "gksu" in sudo_prog or "ktsuss" in sudo_prog:
msg = '--message'
else:
@@ -171,6 +166,7 @@ def PromptToStartDaemon():
'Wicd needs to access your computer\'s network cards.',
daemonloc]
os.spawnvpe(os.P_WAIT, sudo_prog, sudo_args, os.environ)
return True
def RunRegex(regex, string):
""" runs a regex search on a string """
@@ -186,6 +182,8 @@ def WriteLine(my_file, text):
def ExecuteScripts(scripts_dir, verbose=False):
""" Execute every executable file in a given directory. """
if not os.path.exists(scripts_dir):
return
for obj in os.listdir(scripts_dir):
obj = os.path.abspath(os.path.join(scripts_dir, obj))
if os.path.isfile(obj) and os.access(obj, os.X_OK):
@@ -197,7 +195,7 @@ def ExecuteScript(script, verbose=False):
print "Executing %s" % script
ret = call("%s > /dev/null 2>&1" % script, shell=True)
if verbose:
"%s returned %s" % (script, ret)
print "%s returned %s" % (script, ret)
def ReadFile(filename):
""" read in a file and return it's contents as a string """
@@ -256,7 +254,8 @@ def ParseEncryption(network):
else:
rep_val = network.get(cur_val[0].lower())
if rep_val:
line = line.replace("$_%s" % cur_val[0], rep_val)
line = line.replace("$_%s" % cur_val[0],
str(rep_val))
config_file = ''.join([config_file, line])
else:
print "Ignoring template line: '%s'" % line
@@ -450,7 +449,7 @@ def choose_sudo_prog(prog_num=0):
paths = []
if desktop_env == "kde":
progs = ["kdesu", "kdesudo", "ktusss"]
progs = ["kdesu", "kdesudo", "ktsuss"]
else:
progs = ["gksudo", "gksu", "ktsuss"]
@@ -460,8 +459,7 @@ def choose_sudo_prog(prog_num=0):
for path in paths:
if os.path.exists(path):
return path
return None
return ""
def find_path(cmd):
""" Try to find a full path for a given file name.
@@ -497,7 +495,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. """
@@ -547,4 +545,3 @@ def grouper(n, iterable, fillvalue=None):
"""
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)

View File

@@ -8,8 +8,8 @@ when appropriate.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -26,7 +26,6 @@ when appropriate.
import gobject
import time
import sys
from dbus import DBusException
@@ -45,7 +44,7 @@ daemon = dbus_dict["daemon"]
wired = dbus_dict["wired"]
wireless = dbus_dict["wireless"]
monitor = to_time = update_callback = mainloop = None
mainloop = None
def diewithdbus(func):
def wrapper(self, *__args, **__kargs):
@@ -53,7 +52,7 @@ def diewithdbus(func):
ret = func(self, *__args, **__kargs)
self.__lost_dbus_count = 0
return ret
except dbusmanager.DBusException, e:
except DBusException, e:
print "Caught exception %s" % str(e)
if not hasattr(self, "__lost_dbus_count"):
self.__lost_dbus_count = 0
@@ -86,11 +85,42 @@ class ConnectionStatus(object):
self.iwconfig = ""
self.trigger_reconnect = False
self.__lost_dbus_count = 0
self._to_time = daemon.GetBackendUpdateInterval()
self.add_poll_callback()
bus = dbusmanager.get_bus()
bus.add_signal_receiver(self._force_update_connection_status,
"UpdateState", "org.wicd.daemon")
bus.add_signal_receiver(self._update_timeout_interval,
"SignalBackendChanged", "org.wicd.daemon")
def _update_timeout_interval(self, interval):
""" Update the callback interval when signaled by the daemon. """
self._to_time = interval
gobject.source_remove(self.update_callback)
self.add_poll_callback()
def _force_update_connection_status(self):
""" Run a connection status update on demand.
Removes the scheduled update_connection_status()
call, explicitly calls the function, and reschedules
it.
"""
gobject.source_remove(self.update_callback)
self.update_connection_status()
self.add_poll_callback()
def add_poll_callback(self):
""" Registers a polling call at a predetermined interval.
The polling interval is determined by the backend in use.
"""
self.update_callback = misc.timeout_add(self._to_time,
self.update_connection_status)
def check_for_wired_connection(self, wired_ip):
""" Checks for a wired connection.
@@ -144,15 +174,18 @@ 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:
wifi_signal = self._get_printable_sig_strength(always_positive=True)
if wifi_signal <= 0:
# If we have no signal, increment connection loss counter.
# If we haven't gotten any signal 4 runs in a row (12 seconds),
# try to reconnect.
self.connection_lost_counter += 1
print self.connection_lost_counter
if self.connection_lost_counter >= 4:
if self.connection_lost_counter >= 4 and daemon.GetAutoReconnect():
wireless.DisconnectWireless()
self.connection_lost_counter = 0
return False
@@ -229,19 +262,6 @@ class ConnectionStatus(object):
self.auto_reconnect(from_wireless)
return self.update_state(state)
def _force_update_connection_status(self):
""" Run a connection status update on demand.
Removes the scheduled update_connection_status()
call, explicitly calls the function, and reschedules
it.
"""
global update_callback
gobject.source_remove(update_callback)
self.update_connection_status()
add_poll_callback()
def update_state(self, state, wired_ip=None, wifi_ip=None):
""" Set the current connection state. """
# Set our connection state/info.
@@ -277,13 +297,20 @@ class ConnectionStatus(object):
self.last_state = state
return True
def _get_printable_sig_strength(self):
def _get_printable_sig_strength(self, always_positive=False):
""" Get the correct signal strength format. """
try:
if daemon.GetSignalDisplayType() == 0:
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig))
else:
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig))
if always_positive:
# because dBm is negative, add 99 to the signal. This way, if
# the signal drops below -99, wifi_signal will == 0, and
# an automatic reconnect will be triggered
# this is only used in check_for_wireless_connection
wifi_signal = 99 + int(wireless.GetCurrentDBMStrength(self.iwconfig))
else:
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig))
except TypeError:
wifi_signal = 0
@@ -334,12 +361,6 @@ def err_handle(error):
""" Just a dummy function needed for asynchronous dbus calls. """
pass
def add_poll_callback():
global monitor, to_time, update_callback
update_callback = misc.timeout_add(to_time,
monitor.update_connection_status)
def main():
""" Starts the connection monitor.
@@ -347,11 +368,8 @@ def main():
an amount of time determined by the active backend.
"""
global monitor, to_time, mainloop
global mainloop
monitor = ConnectionStatus()
to_time = daemon.GetBackendUpdateInterval()
add_poll_callback()
mainloop = gobject.MainLoop()
mainloop.run()

View File

@@ -1,6 +1,13 @@
""" netentry -- Network entry widgets for the GUI.
This module provides GUI widgets used to represent wired and wireless
entries in the GUI's network list, as well as any settings dialogs
contained within them.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -22,7 +29,7 @@ import misc
import wpath
import dbusmanager
from misc import noneToString, stringToNone, noneToBlankString, to_bool
from guiutil import error, SmallLabel, LabelEntry, GreyLabel, LeftAlignedLabel, string_input
from guiutil import error, LabelEntry, GreyLabel, LeftAlignedLabel, string_input
from translations import language
@@ -38,14 +45,20 @@ def setup_dbus():
wired = dbusmanager.get_interface('wired')
class AdvancedSettingsDialog(gtk.Dialog):
def __init__(self):
def __init__(self, network_name=None):
""" Build the base advanced settings dialog.
This class isn't used by itself, instead it is used as a parent for
the WiredSettingsDialog and WirelessSettingsDialog.
"""
gtk.Dialog.__init__(self, title=language['properties'],
# if no network name was passed, just use Properties as the title
if network_name:
title = '%s - %s' % (network_name, language['properties'])
else:
title = language['properties']
gtk.Dialog.__init__(self, title=title,
flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CANCEL,
gtk.RESPONSE_REJECT,
gtk.STOCK_OK,
@@ -229,9 +242,9 @@ class AdvancedSettingsDialog(gtk.Dialog):
class WiredSettingsDialog(AdvancedSettingsDialog):
def __init__(self, name):
""" Build the wired settings dialog. """
AdvancedSettingsDialog.__init__(self)
AdvancedSettingsDialog.__init__(self, language['wired_network'])
self.des = self.connect("destroy", self.destroy_called)
self.script_button.connect("button-press-event", self.edit_scripts)
self.script_button.connect("clicked", self.edit_scripts)
self.prof_name = name
def set_net_prop(self, option, value):
@@ -287,7 +300,7 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
class WirelessSettingsDialog(AdvancedSettingsDialog):
def __init__(self, networkID):
""" Build the wireless settings dialog. """
AdvancedSettingsDialog.__init__(self)
AdvancedSettingsDialog.__init__(self, wireless.GetWirelessProperty(networkID, 'essid'))
# Set up encryption stuff
self.networkID = networkID
self.combo_encryption = gtk.combo_box_new_text()
@@ -302,7 +315,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
information_button = gtk.Button(stock=gtk.STOCK_INFO)
self.button_hbox.pack_start(information_button, False, False)
information_button.connect('clicked', lambda *a, **k: WirelessInformationDialog(networkID))
information_button.connect('clicked', lambda *a, **k: WirelessInformationDialog(networkID, self))
information_button.show()
# Build the encryption menu
@@ -328,7 +341,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
# Connect signals.
self.chkbox_encryption.connect("toggled", self.toggle_encryption)
self.combo_encryption.connect("changed", self.change_encrypt_method)
self.script_button.connect("button-press-event", self.edit_scripts)
self.script_button.connect("clicked", self.edit_scripts)
self.des = self.connect("destroy", self.destroy_called)
def destroy_called(self, *args):
@@ -398,9 +411,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
def save_settings(self, networkid):
# Check encryption info
encrypt_info = self.encryption_info
if self.chkbox_encryption.get_active():
print "setting encryption info..."
encrypt_info = self.encryption_info
encrypt_methods = self.encrypt_types
self.set_net_prop("enctype",
encrypt_methods[self.combo_encryption.get_active()]['type'])
@@ -424,8 +437,6 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
else:
print "no encryption specified..."
self.set_net_prop("enctype", "None")
for entry in encrypt_info.iterkeys():
self.set_net_prop(entry[0].entry, "")
AdvancedSettingsDialog.save_settings(self)
if self.chkbox_global_settings.get_active():
@@ -550,7 +561,8 @@ class WiredNetworkEntry(NetworkEntry):
self.image.show()
self.connect_button.show()
self.name_label.set_label(language['wired_network'])
self.name_label.set_use_markup(True)
self.name_label.set_label("<b>" + language['wired_network'] + "</b>")
self.is_full_gui = True
@@ -643,17 +655,16 @@ class WiredNetworkEntry(NetworkEntry):
def add_profile(self, widget):
""" Add a profile to the profile list. """
print "adding profile"
response = string_input("Enter a profile name", "The profile name " +
"will not be used by the computer. It " +
"allows you to " +
"easily distinguish between different network " +
"profiles.", "Profile name:")
"profiles.", "Profile name:").strip()
# if response is "" or None
if not response:
return
error(None, "Invalid profile name", block=True)
return False
profile_name = response
profile_list = wired.GetWiredProfileList()
@@ -751,7 +762,7 @@ class WirelessNetworkEntry(NetworkEntry):
'encryption_method'))
self.set_channel(wireless.GetWirelessProperty(networkID, 'channel'))
self.name_label.set_use_markup(True)
self.name_label.set_label("%s %s %s %s" % (self._escape(self.essid),
self.name_label.set_label("<b>%s</b> %s %s %s" % (self._escape(self.essid),
self.lbl_strength.get_label(),
self.lbl_encryption.get_label(),
self.lbl_channel.get_label(),
@@ -872,8 +883,8 @@ class WirelessNetworkEntry(NetworkEntry):
class WirelessInformationDialog(gtk.Dialog):
def __init__(self, networkID):
gtk.Dialog.__init__(self)
def __init__(self, networkID, parent):
gtk.Dialog.__init__(self,parent=parent)
# Make the combo box.
self.lbl_strength = gtk.Label()

View File

@@ -19,9 +19,9 @@ class WiredConnectThread() -- Connection thread for wired
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2008 Byron Hillis
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
# Copyright (C) 2007 - 2009 Byron Hillis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -116,7 +116,9 @@ def expand_script_macros(script, msg, bssid, essid):
script -- the script to execute.
msg -- the name of the script, %{script} will be expanded to this.
bssid -- the bssid of the network we connect to, defaults to 'wired'.
essid -- the essid of the network we connect to, defaults to 'wired'."""
essid -- the essid of the network we connect to, defaults to 'wired'.
"""
def repl(match):
macro = match.group(1).lower()
if macro_dict.has_key(macro):
@@ -149,10 +151,10 @@ class Controller(object):
self.connecting_thread = None
self.before_script = None
self.after_script = None
self.disconnect_script = None
self.pre_disconnect_script = None
self.post_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):
@@ -202,17 +204,23 @@ class Controller(object):
def Disconnect(self, *args, **kargs):
""" Disconnect from the network. """
iface = self.iface
misc.ExecuteScripts(wpath.disconnectscripts, self.debug)
if self.disconnect_script:
print 'Running disconnect script'
misc.ExecuteScript(expand_script_macros(self.disconnect_script,
'disconnection', *args),
misc.ExecuteScripts(wpath.predisconnectscripts, self.debug)
if self.pre_disconnect_script:
print 'Running pre-disconnect script'
misc.ExecuteScript(expand_script_macros(self.pre_disconnect_script,
'pre-disconnection', *args),
self.debug)
iface.ReleaseDHCP()
iface.SetAddress('0.0.0.0')
iface.FlushRoutes()
iface.Down()
iface.Up()
misc.ExecuteScripts(wpath.postdisconnectscripts, self.debug)
if self.post_disconnect_script:
print 'Running post-disconnect script'
misc.ExecuteScript(expand_script_macros(self.post_disconnect_script,
'post-disconnection', *args),
self.debug)
def ReleaseDHCP(self):
""" Release the DHCP lease for this interface. """
@@ -272,8 +280,8 @@ class ConnectThread(threading.Thread):
lock = threading.Lock()
def __init__(self, network, interface_name, before_script, after_script,
disconnect_script, gdns1, gdns2, gdns3, gdns_dom, gsearch_dom,
iface, debug):
pre_disconnect_script, post_disconnect_script, gdns1,
gdns2, gdns3, gdns_dom, gsearch_dom, iface, debug):
""" Initialise the required object variables and the thread.
Keyword arguments:
@@ -282,7 +290,8 @@ class ConnectThread(threading.Thread):
wired -- name of the wired interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
@@ -296,7 +305,8 @@ class ConnectThread(threading.Thread):
self.connect_result = None
self.before_script = before_script
self.after_script = after_script
self.disconnect_script = disconnect_script
self.pre_disconnect_script = pre_disconnect_script
self.post_disconnect_script = post_disconnect_script
self._should_die = False
self.abort_reason = ""
self.connect_result = ""
@@ -314,6 +324,13 @@ class ConnectThread(threading.Thread):
self.SetStatus('interface_down')
def run(self):
self.connect_result = "Failed"
try:
self._connect()
finally:
self.is_connecting = False
def set_should_die(self, val):
self.lock.acquire()
try:
@@ -564,23 +581,13 @@ class Wireless(Controller):
"""
def comp(x, y):
if x.has_key('quality'):
if x['quality'] > y['quality']:
return 1
elif x['quality'] < y['quality']:
return -1
else:
return 0
if 'quality' in x:
key = 'quality'
else:
if x['strength'] < y['strength']:
return 1
elif x['strength'] > y['strength']:
return -1
else:
return 0
key = 'strength'
return cmp(x[key], y[key])
if not self.wiface: return []
wiface = self.wiface
# Prepare the interface for scanning
@@ -609,7 +616,8 @@ class Wireless(Controller):
self.connecting_thread = WirelessConnectThread(network,
self.wireless_interface, self.wpa_driver, self.before_script,
self.after_script, self.disconnect_script, self.global_dns_1,
self.after_script, self.pre_disconnect_script,
self.post_disconnect_script, self.global_dns_1,
self.global_dns_2, self.global_dns_3, self.global_dns_dom,
self.global_search_dom, self.wiface, debug)
self.connecting_thread.setDaemon(True)
@@ -711,7 +719,7 @@ class Wireless(Controller):
wiface = self.wiface
print 'Creating ad-hoc network'
print 'Stopping dhcp client and wpa_supplicant'
BACKEND.ReleaseDHCP()
wiface.ReleaseDHCP()
wiface.StopWPA()
print 'Putting wireless interface down'
wiface.Down()
@@ -771,6 +779,7 @@ class Wireless(Controller):
""" Sets the wpa_supplicant driver associated with the interface. """
self.wiface.SetWpaDriver(driver)
class WirelessConnectThread(ConnectThread):
""" A thread class to perform the connection to a wireless network.
@@ -780,8 +789,9 @@ class WirelessConnectThread(ConnectThread):
"""
def __init__(self, network, wireless, wpa_driver, before_script,
after_script, disconnect_script, gdns1, gdns2, gdns3,
gdns_dom, gsearch_dom, wiface, debug=False):
after_script, pre_disconnect_script, post_disconnect_script,
gdns1, gdns2, gdns3, gdns_dom, gsearch_dom, wiface,
debug=False):
""" Initialise the thread with network information.
Keyword arguments:
@@ -790,19 +800,21 @@ class WirelessConnectThread(ConnectThread):
wpa_driver -- type of wireless interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wireless, before_script,
after_script, disconnect_script, gdns1, gdns2,
after_script, pre_disconnect_script,
post_disconnect_script, gdns1, gdns2,
gdns3, gdns_dom, gsearch_dom, wiface, debug)
self.wpa_driver = wpa_driver
def run(self):
def _connect(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
@@ -831,17 +843,17 @@ class WirelessConnectThread(ConnectThread):
self.reset_ip_addresses(wiface)
self.stop_wpa(wiface)
self.flush_routes(wiface)
# Generate PSK and authenticate if needed.
if self.wpa_driver != 'ralink legacy':
self.generate_psk_and_authenticate(wiface)
wiface.SetMode(self.network['mode'])
# Put interface up.
self.SetStatus('configuring_interface')
self.put_iface_up(wiface)
# Generate PSK and authenticate if needed.
if self.wpa_driver != 'ralink legacy':
self.generate_psk_and_authenticate(wiface)
# Associate.
wiface.SetMode(self.network['mode'])
wiface.Associate(self.network['essid'], self.network['channel'],
self.network['bssid'])
@@ -854,7 +866,8 @@ class WirelessConnectThread(ConnectThread):
if self.network.get('enctype'):
self.SetStatus('validating_authentication')
if not wiface.ValidateAuthentication(time.time()):
if not self.connect_result:
print "connect result is %s" % self.connect_result
if not self.connect_result or self.connect_result == 'Failed':
self.abort_connection('bad_pass')
# Set up gateway, IP address, and DNS servers.
@@ -968,9 +981,10 @@ class Wired(Controller):
if not self.liface: return False
self.connecting_thread = WiredConnectThread(network,
self.wired_interface, self.before_script, self.after_script,
self.disconnect_script, self.global_dns_1, self.global_dns_2,
self.global_dns_3, self.global_dns_dom, self.global_search_dom,
self.liface, debug)
self.pre_disconnect_script, self.post_disconnect_script,
self.global_dns_1, self.global_dns_2, self.global_dns_3,
self.global_dns_dom, self.global_search_dom, self.liface,
debug)
self.connecting_thread.setDaemon(True)
self.connecting_thread.start()
return self.connecting_thread
@@ -994,8 +1008,8 @@ class WiredConnectThread(ConnectThread):
"""
def __init__(self, network, wired, before_script, after_script,
disconnect_script, gdns1, gdns2, gdns3, gdns_dom, gsearch_dom,
liface, debug=False):
pre_disconnect_script, post_disconnect_script, gdns1,
gdns2, gdns3, gdns_dom, gsearch_dom, liface, debug=False):
""" Initialise the thread with network information.
Keyword arguments:
@@ -1004,17 +1018,19 @@ class WiredConnectThread(ConnectThread):
wired -- name of the wired interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
pre_disconnect_script -- script to run before disconnection
post_disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wired, before_script,
after_script, disconnect_script, gdns1, gdns2,
after_script, pre_disconnect_script,
post_disconnect_script, gdns1, gdns2,
gdns3, gdns_dom, gsearch_dom, liface, debug)
def run(self):
def _connect(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
@@ -1063,4 +1079,3 @@ class WiredConnectThread(ConnectThread):
self.connect_result = "Success"
self.is_connecting = False

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
""" Wicd Preferences Dialog.
""" prefs -- Wicd Preferences Dialog.
Displays the main settings dialog window for wicd and
handles recieving/sendings the settings from/to the daemon.
@@ -8,8 +8,8 @@ handles recieving/sendings the settings from/to the daemon.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2008-2009 Adam Blackburn
# Copyright (C) 2008-2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -26,7 +26,7 @@ handles recieving/sendings the settings from/to the daemon.
import gtk
import gobject
import pango
#import pango
import os
import gtk.glade
@@ -41,6 +41,8 @@ wired = None
from translations import language
USER_SETTINGS_DIR = os.path.expanduser('~/.wicd/')
def setup_dbus():
global daemon, wireless, wired
daemon = dbusmanager.get_interface('daemon')
@@ -49,20 +51,18 @@ def setup_dbus():
class PreferencesDialog(object):
""" Class for handling the wicd preferences dialog window. """
def __init__(self, wTree):
def __init__(self, parent, wTree):
setup_dbus()
self.parent = parent
self.wTree = wTree
self.prep_settings_diag()
self.load_preferences_diag()
def _setup_external_app_radios(self, radio_list, get_method, set_method):
""" Generic function for setting up external app radios. """
def set_available(apps):
for app in apps:
app.set_sensitive(daemon.GetAppAvailable(app.get_label()))
# Disable radios for apps that aren't installed.
set_available(radio_list[1:])
for app in radio_list[1:]:
app.set_sensitive(daemon.GetAppAvailable(app.get_label()))
selected_app = get_method()
# Make sure the app we want to select is actually available.
if radio_list[selected_app].get_property("sensitive"):
@@ -82,7 +82,7 @@ class PreferencesDialog(object):
self.preferwiredcheckbox.set_active(daemon.GetPreferWiredNetwork())
dhcp_list = [self.dhcpautoradio, self.dhclientradio, self.dhcpcdradio,
self.pumpradio]
self.pumpradio, self.udhcpcradio]
self._setup_external_app_radios(dhcp_list, daemon.GetDHCPClient,
daemon.SetDHCPClient)
@@ -100,7 +100,7 @@ class PreferencesDialog(object):
sudo_list = [self.sudoautoradio, self.gksudoradio, self.kdesuradio,
self.ktsussradio]
self._setup_external_app_radios(sudo_list, daemon.GetSudoApp,
daemon.SetAudoApp)
daemon.SetSudoApp)
auto_conn_meth = daemon.GetWiredAutoConnectMethod()
if auto_conn_meth == 1:
@@ -144,6 +144,24 @@ class PreferencesDialog(object):
self.backendcombo.set_active(self.backends.index(cur_backend))
except ValueError:
self.backendcombo.set_active(0)
self.notificationscheckbox.set_active(
os.path.exists(
os.path.join(USER_SETTINGS_DIR, 'USE_NOTIFICATIONS')
))
# if pynotify isn't installed disable the option
try:
import pynotify
except ImportError:
self.notificationscheckbox.set_active(False)
self.notificationscheckbox.set_sensitive(False)
# if notifications were disabled with the configure flag
if wpath.no_use_notifications:
self.notificationscheckbox.set_active(False)
self.notificationscheckbox.hide()
self.wTree.get_widget('label2').hide()
self.wTree.get_widget("notebook2").set_current_page(0)
@@ -192,8 +210,10 @@ class PreferencesDialog(object):
dhcp_client = misc.DHCLIENT
elif self.dhcpcdradio.get_active():
dhcp_client = misc.DHCPCD
else:
elif self.pumpradio.get_active():
dhcp_client = misc.PUMP
else:
dhcp_client = misc.UDHCPC
daemon.SetDHCPClient(dhcp_client)
if self.linkautoradio.get_active():
@@ -224,6 +244,19 @@ class PreferencesDialog(object):
[width, height] = self.dialog.get_size()
daemon.WriteWindowSize(width, height, "pref")
not_path = os.path.join(USER_SETTINGS_DIR, 'USE_NOTIFICATIONS')
if self.notificationscheckbox.get_active():
if not os.path.exists(not_path):
open(not_path, 'w')
else:
if os.path.exists(not_path):
os.remove(not_path)
# if this GUI was started by a tray icon,
# instantly change the notifications there
if self.parent.tray:
self.parent.tray.icon_info.use_notify = \
self.notificationscheckbox.get_active()
def set_label(self, glade_str, label):
""" Sets the label for the given widget in wicd.glade. """
@@ -308,11 +341,15 @@ class PreferencesDialog(object):
'use_last_used_profile')
self.notificationscheckbox = setup_label("pref_use_libnotify",
'display_notifications')
# DHCP Clients
self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config")
self.dhclientradio = self.wTree.get_widget("dhclient_radio")
self.pumpradio = self.wTree.get_widget("pump_radio")
self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio")
self.udhcpcradio = self.wTree.get_widget("udhcpc_radio")
# Wired Link Detection Apps
self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config')

View File

@@ -8,8 +8,8 @@ Used for when a laptop enters hibernation/suspension.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -* coding: utf-8 -*-
""" translations -- module for handling the translation strings for wicd. """
#
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
@@ -43,19 +44,20 @@ def get_gettext():
lc, encoding = locale.getdefaultlocale(envvars=('LC_MESSAGES',
'LC_ALL', 'LANG',
'LANGUAGE'))
langs += [lc]
except ValueError, e:
print str(e)
print "Default locale unavailable, falling back to en_US"
if (lc):
langs += [lc]
langs += ["en_US"]
lang = gettext.translation('wicd', local_path, languages=langs,
fallback=True)
_ = lang.gettext
return _
# Generated automatically on Sun, 05 Jul 2009 13:51:18 CDT
_ = get_gettext()
language = {}
<<<<<<< TREE
language['connect'] = _('Connect')
language['ip'] = _('IP')
language['netmask'] = _('Netmask')
@@ -234,3 +236,165 @@ language['ok'] = _('OK')
language['cancel'] = _('Cancel')
=======
language['resetting_ip_address'] = _('''Resetting IP address...''')
language['prefs_help'] = _('''Preferences dialog''')
language['no_dhcp_offers'] = _('''Connection Failed: No DHCP offers received.''')
language['more_help'] = _('''For more detailed help, consult the wicd-curses(8) man page.''')
language['bad_pass'] = _('''Connection Failed: Bad password''')
language['cannot_start_daemon'] = _('''Unable to connect to wicd daemon DBus interface. This typically means there was a problem starting the daemon. Check the wicd log for more information.''')
language['verifying_association'] = _('''Verifying access point association...''')
language['wired_always_on'] = _('''Always show wired interface''')
language['could_not_connect'] = _('''Could not connect to wicd's D-Bus interface. Check the wicd log for error messages.''')
language['path_to_pac_file'] = _('''Path to PAC File''')
language['always_switch_to_wired'] = _('''Always switch to wired connection when available''')
language['disconn_help'] = _('''Disconnect from all networks''')
language['wired_networks'] = _('''Wired Networks''')
language['backend_alert'] = _('''Changes to your backend won't occur until the daemon is restarted.''')
language['about_help'] = _('''Stop a network connection in progress''')
language['connecting'] = _('''Connecting''')
language['pre_disconnect_script'] = _('''Run pre-disconnect script''')
language['cannot_edit_scripts_1'] = _('''To avoid various complications, wicd-curses does not support directly editing the scripts directly. However, you can edit them manually. First, (as root)", open the "$A" config file, and look for the section labeled by the $B in question. In this case, this is:''')
language['cannot_edit_scripts_3'] = _('''You can also configure the wireless networks by looking for the "[<ESSID>]" field in the config file.''')
language['cannot_edit_scripts_2'] = _('''Once there, you can adjust (or add) the "beforescript", "afterscript", and "disconnectscript" variables as needed, to change the preconnect, postconnect, and disconnect scripts respectively. Note that you will be specifying the full path to the scripts - not the actual script contents. You will need to add/edit the script contents separately. Refer to the wicd manual page for more information.''')
language['scripts_need_pass'] = _('''You must enter your password to configure scripts''')
language['dns_domain'] = _('''DNS domain''')
language['aborted'] = _('''Connection Cancelled''')
language['scanning_stand_by'] = _('''Scanning networks... stand by...''')
language['password'] = _('''Password''')
language['no_daemon_tooltip'] = _('''Wicd daemon unreachable''')
language['use_static_dns'] = _('''Use Static DNS''')
language['setting_broadcast_address'] = _('''Setting broadcast address...''')
language['choose_wired_profile'] = _('''Select or create a wired profile to connect with''')
language['make_wired_profile'] = _('''To connect to a wired network, you must create a network profile. To create a network profile, type a name that describes this network, and press Add.''')
language['esc_to_cancel'] = _('''Press ESC to cancel''')
language['scanning'] = _('''Scanning''')
language['flushing_routing_table'] = _('''Flushing the routing table...''')
language['brought_to_you'] = _('''Brought to you by:''')
language['refresh_help'] = _('''Refresh network list''')
language['select_hidden_essid'] = _('''Select Hidden Network ESSID''')
language['ext_programs'] = _('''External Programs''')
language['connect'] = _('''Connect''')
language['help_help'] = _('''Display this help dialog''')
language['use_global_dns'] = _('''Use global DNS servers''')
language['enable_encryption'] = _('''This network requires encryption to be enabled.''')
language['use_last_used_profile'] = _('''Use last used profile on wired autoconnect''')
language['preferences'] = _('''Preferences''')
language['dhcp_failed'] = _('''Connection Failed: Unable to Get IP Address''')
language['setting_static_ip'] = _('''Setting static IP addresses...''')
language['connecting_to_daemon'] = _('''Connecting to daemon...''')
language['automatic_connect'] = _('''Automatically connect to this network''')
language['add_new_wired_profile'] = _('''Add a new wired profile''')
language['dhcp_client'] = _('''DHCP Client''')
language['display_type_dialog'] = _('''Use dBm to measure signal strength''')
language['global_settings'] = _('''Use these settings for all networks sharing this essid''')
language['config_help'] = _('''Configure Selected Network''')
language['use_debug_mode'] = _('''Enable debug mode''')
language['removing_old_connection'] = _('''Removing old connection...''')
language['no_sudo_prog'] = _('''Could not find a graphical sudo program. The script editor could not be launched. You'll have to edit scripts directly your configuration file.''')
language['wireless_networks'] = _('''Wireless Networks''')
language['configuring_wired'] = _('''Configuring preferences for wired profile "$A"''')
language['no_wireless_networks_found'] = _('''No wireless networks found.''')
language['madwifi_for_adhoc'] = _('''Check if using madwifi/atheros drivers''')
language['properties'] = _('''Properties''')
language['setting_encryption_info'] = _('''Setting encryption info''')
language['about'] = _('''About Wicd''')
language['ok'] = _('''OK''')
language['adhoc_help'] = _('''Set up Ad-hoc network''')
language['scripts_help'] = _('''Select scripts''')
language['invalid_address'] = _('''Invalid address in $A entry.''')
language['configuring_interface'] = _('''Configuring wireless interface...''')
language['generating_psk'] = _('''Generating PSK...''')
language['validating_authentication'] = _('''Validating authentication...''')
language['essid'] = _('''ESSID''')
language['anonymous_identity'] = _('''Anonymous Identity''')
language['wireless_interface'] = _('''Wireless Interface''')
language['hidden_network'] = _('''Hidden Network''')
language['key'] = _('''Key''')
language['wicd_curses'] = _('''Wicd Curses Interface''')
language['debugging'] = _('''Debugging''')
language['use_encryption'] = _('''Use Encryption''')
language['wpa_supplicant'] = _('''WPA Supplicant''')
language['global_dns_servers'] = _('''Global DNS servers''')
language['not_connected'] = _('''Not connected''')
language['done'] = _('''Done connecting...''')
language['cannot_connect_to_daemon'] = _('''Can't connect to the daemon, trying to start it automatically...''')
language['cancel'] = _('''Cancel''')
language['case_sensitive'] = _('''All controls are case sensitive''')
language['gateway'] = _('''Gateway''')
language['backend'] = _('''Backend''')
language['dbus_fail'] = _('''DBus failure! This is most likely caused by the wicd daemon stopping while wicd-curses is running. Please restart the daemon, and then restart wicd-curses.''')
language['terminated'] = _('''Terminated by user''')
language['wired_detect'] = _('''Wired Link Detection''')
language['add_new_profile'] = _('''Add a new profile''')
language['use_ics'] = _('''Activate Internet Connection Sharing''')
language['create_adhoc_network'] = _('''Create an Ad-Hoc Network''')
language['interface_up'] = _('''Putting interface up...''')
language['global_dns_not_enabled'] = _('''Global DNS has not been enabled in general preferences.''')
language['dns'] = _('''DNS''')
language['advanced_settings'] = _('''Advanced Settings''')
language['username'] = _('''Username''')
language['wicd_auto_config'] = _('''Automatic (recommended)''')
language['wired_network_found'] = _('''Wired connection detected''')
language['netmask'] = _('''Netmask''')
language['select_a_network'] = _('''Choose from the networks below:''')
language['connect_help'] = _('''Connect to selected network''')
language['no_delete_last_profile'] = _('''wicd-curses does not support deleting the last wired profile. Try renaming it ('F2')''')
language['gen_settings'] = _('''General Settings''')
language['connected_to_wireless'] = _('''Connected to $A at $B (IP: $C)''')
language['exception'] = _('''EXCEPTION! Please report this to the maintainer and file a bug report with the backtrace below:''')
language['configuring_wireless'] = _('''Configuring preferences for wireless network "$A" ($B)''')
language['generating_wpa_config'] = _('''Generating WPA configuration file...''')
language['search_domain'] = _('''Search domain''')
language['encrypt_info_missing'] = _('''Required encryption information is missing.''')
language['running_dhcp'] = _('''Obtaining IP address...''')
language['lost_dbus'] = _('''The wicd daemon has shut down. The UI will not function properly until it is restarted.''')
language['wired_network_instructions'] = _('''To connect to a wired network, you must create a network profile. To create a network profile, type a name that describes this network, and press Add.''')
language['setting_static_dns'] = _('''Setting static DNS servers...''')
language['auto_reconnect'] = _('''Automatically reconnect on connection loss''')
language['use_wep_encryption'] = _('''Use Encryption (WEP only)''')
language['wired_autoconnect_settings'] = _('''Wired Autoconnect Settings''')
language['before_script'] = _('''Run script before connect''')
language['always_use_wext'] = _('''You should almost always use wext as the WPA supplicant driver''')
language['network_interfaces'] = _('''Network Interfaces''')
language['use_default_profile'] = _('''Use default profile on wired autoconnect''')
language['scan'] = _('''Scan''')
language['ip'] = _('''IP''')
language['connected_to_wired'] = _('''Connected to wired network (IP: $A)''')
language['wpa_supplicant_driver'] = _('''WPA Supplicant Driver''')
language['access_cards'] = _('''Wicd needs to access your computer's network cards.''')
language['killswitch_enabled'] = _('''Wireless Kill Switch Enabled''')
language['hidden_network_essid'] = _('''Hidden Network ESSID''')
language['secured'] = _('''Secured''')
language['interface_down'] = _('''Putting interface down...''')
language['authentication'] = _('''Authentication''')
language['after_script'] = _('''Run script after connect''')
language['show_wired_list'] = _('''Prompt for profile on wired autoconnect''')
language['channel'] = _('''Channel''')
language['unsecured'] = _('''Unsecured''')
language['rename_wired_profile'] = _('''Rename wired profile''')
language['daemon_unavailable'] = _('''The wicd daemon is unavailable, so your request cannot be completed''')
language['stop_showing_chooser'] = _('''Stop Showing Autoconnect pop-up temporarily''')
language['scan_help'] = _('''Scan for hidden networks''')
language['use_static_ip'] = _('''Use Static IPs''')
language['raw_screen_arg'] = _('''use urwid's raw screen controller''')
language['route_flush'] = _('''Route Table Flushing''')
language['scripts'] = _('''Scripts''')
language['identity'] = _('''Identity''')
language['automatic_reconnection'] = _('''Automatic Reconnection''')
language['wired_interface'] = _('''Wired Interface''')
language['press_to_quit'] = _('''Press F8 or Q to quit.''')
language['default_wired'] = _('''Use as default profile (overwrites any previous default)''')
language['wired_network'] = _('''Wired Network''')
language['dns_server'] = _('''DNS server''')
language['notifications'] = _('''Notifications''')
language['display_notifications'] = _('''Display notifications about connection status''')
language['connection_established'] = _('''Connection established''')
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 daemon due to an access denied error from DBus. Please check that your user is in the $A group.''')
language['disconnecting_active'] = _('''Disconnecting active connections...''')
language['access_denied_wc'] = _('''ERROR: wicd-curses was denied access to the wicd daemon: please check that your user is in the "$A" group.''')
language['post_disconnect_script'] = _('''Run post-disconnect script''')
>>>>>>> MERGE-SOURCE

335
wicd/wicd-client.py Executable file → Normal file
View File

@@ -14,14 +14,14 @@ class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo.
class StatusTrayIconGUI() -- Implements the tray icon using a
gtk.StatusIcon.
class EggTrayIconGUI() -- Implements the tray icon using egg.trayicon.
def usage() -- Prints usage information.
def main() -- Runs the wicd frontend main loop.
def usage() -- Prints usage information.
def main() -- Runs the wicd frontend main loop.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -46,12 +46,23 @@ import time
import atexit
from dbus import DBusException
import pygtk
pygtk.require('2.0')
HAS_NOTIFY = True
try:
import pynotify
if not pynotify.init("Wicd"):
HAS_NOTIFY = False
except ImportError:
HAS_NOTIFY = False
# Wicd specific imports
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
@@ -79,8 +90,9 @@ def catchdbus(func):
try:
return func(*args, **kwargs)
except DBusException, e:
if "DBus.Error.AccessDenied" in e:
error(None, language['access_denied'])
if e.get_dbus_name() != None and "DBus.Error.AccessDenied" in e.get_dbus_name():
error(None, language['access_denied'].replace("$A","<b>"+wpath.wicd_group+"</b>"))
#raise
raise DBusException(e)
else:
print "warning: ignoring exception %s" % e
@@ -112,7 +124,7 @@ class TrayIcon(object):
Base Class for implementing a tray icon to display network status.
"""
def __init__(self, animate):
def __init__(self, animate, displaytray=True):
self.cur_sndbytes = -1
self.cur_rcvbytes = -1
self.last_sndbytes = -1
@@ -125,10 +137,13 @@ class TrayIcon(object):
else:
self.tr = self.StatusTrayIconGUI(self)
self.icon_info = self.TrayConnectionInfo(self, self.tr, animate)
self.tr.icon_info = self.icon_info
print 'displaytray %s' % displaytray
self.tr.visible(displaytray)
def is_embedded(self):
if USE_EGG:
raise NotImplementedError
raise NotImplementedError()
else:
return self.tr.is_embedded()
@@ -152,12 +167,19 @@ class TrayIcon(object):
class TrayConnectionInfo(object):
""" Class for updating the tray icon status. """
def __init__(self, parent, tr, animate=True):
# Initialize variables needed for the icon status methods.
""" Initialize variables needed for the icon status methods. """
self.last_strength = -2
self.still_wired = False
self.network = ''
self.tried_reconnect = False
self.connection_lost_counter = 0
self.tr = tr
self.last_sndbytes = -1
self.last_rcvbytes = -1
self.max_snd_gain = 10000
self.max_rcv_gain = 10000
self.animate = animate
self.parent = parent
self.network_name = '' # SSID
@@ -166,6 +188,12 @@ class TrayIcon(object):
self.network_addr = '0.0.0.0' # IP Address
self.network_br = '' # Bitrate
# keep track of the last state to provide appropriate
# notifications
self._last_bubble = None
self.last_state = None
self.should_notify = True
if DBUS_AVAIL:
self.update_tray_icon()
else:
@@ -198,6 +226,20 @@ class TrayIcon(object):
return True
def _show_notification(self, title, details, image=None):
if self.should_notify:
if not self._last_bubble:
self._last_bubble = pynotify.Notification(title, details,
image)
self._last_bubble.show()
else:
self._last_bubble.clear_actions()
self._last_bubble.clear_hints()
self._last_bubble.update(title, details, image)
self._last_bubble.show()
self.should_notify = False
@catchdbus
def wired_profile_chooser(self):
""" Launch the wired profile chooser. """
@@ -210,14 +252,24 @@ class TrayIcon(object):
self.network_addr = str(info[0])
self.network_type = "wired"
self.tr.set_from_file(os.path.join(wpath.images, "wired.png"))
# status_string = language['connected_to_wired'].replace('$A',
wired_ip)
# self.tr.set_tooltip(status_string)
self._show_notification(language['wired_network'],
language['connection_established'],
'network-wired')
self.update_tooltip()
@catchdbus
def set_wireless_state(self, info):
""" Sets the icon info for a wireless state. """
lock = ''
wireless_ip = info[0]
self.network = info[1]
strength = info[2]
cur_net_id = int(info[3])
sig_string = daemon.FormatSignalForPrinting(str(info[2]))
sig_string = daemon.FormatSignalForPrinting(str(strength))
self.network_type = "wireless"
self.network_addr = str(info[0])
self.network_name = info[1]
@@ -227,31 +279,57 @@ class TrayIcon(object):
if wireless.GetWirelessProperty(cur_net_id, "encryption"):
lock = "-lock"
# status_string = (language['connected_to_wireless']
.replace('$A', self.network)
.replace('$B', sig_string)
.replace('$C', str(wireless_ip)))
#self.tr.set_tooltip(status_string)
self.set_signal_image(int(strength), lock)
self._show_notification(self.network,
language['connection_established'],
'network-wireless')
self.update_tooltip()
def set_connecting_state(self, info):
""" Sets the icon info for a connecting state. """
self.network_type = info[0]
if info[0] == 'wireless':
self.network_name = info[1]
wired = False
if info[0] == 'wired' and len(info) == 1:
cur_network = language['wired_network']
wired = True
else:
cur_network = info[1]
status_string = language['connecting'] + " to " + \
cur_network + "..."
self.update_tooltip()
# self.tr.set_tooltip(status_string)
self.tr.set_from_file(os.path.join(wpath.images, "no-signal.png"))
if wired:
self._show_notification(cur_network,
language['establishing_connection'],
'network-wired')
else:
self._show_notification(cur_network,
language['establishing_connection'],
'network-wireless')
@catchdbus
def set_not_connected_state(self, info=None):
""" Set the icon info for the not connected state. """
self.tr.set_from_file(wpath.images + "no-signal.png")
if not DBUS_AVAIL:
self.network_type = "no_daemon"
status = language['no_daemon_tooltip']
elif wireless.GetKillSwitchEnabled():
self.network_type = "killswitch"
status = (language['not_connected'] + " (" +
language['killswitch_enabled'] + ")")
else:
self.network_type = "none"
status = language['not_connected']
# self.tr.set_tooltip(status)
self._show_notification(language['disconnected'], None, 'stop')
self.update_tooltip()
@catchdbus
def update_tray_icon(self, state=None, info=None):
""" Updates the tray icon and current connection status. """
@@ -259,6 +337,12 @@ class TrayIcon(object):
if not state or not info:
[state, info] = daemon.GetConnectionStatus()
# should this state change display a notification?
self.should_notify = (can_use_notify() and
self.last_state != state)
self.last_state = state
if state == misc.WIRED:
self.set_wired_state(info)
@@ -277,8 +361,7 @@ class TrayIcon(object):
def set_signal_image(self, wireless_signal, lock):
""" Sets the tray icon image for an active wireless connection. """
if self.animate:
TrayIcon.get_bandwidth_bytes(self.parent)
prefix = self.get_bandwidth_activity()
prefix = self.get_bandwidth_state()
else:
prefix = 'idle-'
if daemon.GetSignalDisplayType() == 0:
@@ -304,26 +387,40 @@ class TrayIcon(object):
self.tr.set_from_file(img_file)
@catchdbus
def get_bandwidth_activity(self):
def get_bandwidth_state(self):
""" Determines what network activity state we are in. """
transmitting = False
receiving = False
dev_dir = '/sys/class/net/'
wiface = daemon.GetWirelessInterface()
for fldr in os.listdir(dev_dir):
if fldr == wiface:
dev_dir = dev_dir + fldr + "/statistics/"
break
try:
rcvbytes = int(open(dev_dir + "rx_bytes", "r").read().strip())
sndbytes = int(open(dev_dir + "tx_bytes", "r").read().strip())
except IOError:
sndbytes = None
rcvbytes = None
if not rcvbytes or not sndbytes:
return 'idle-'
# Figure out receiving data info.
activity = self.is_network_active(self.parent.cur_rcvbytes,
self.parent.max_rcv_gain,
self.parent.last_rcvbytes)
activity = self.is_network_active(rcvbytes, self.max_rcv_gain,
self.last_rcvbytes)
receiving = activity[0]
self.parent.max_rcv_gain = activity[1]
self.parent.last_rcvbytes = activity[2]
self.max_rcv_gain = activity[1]
self.last_rcvbytes = activity[2]
# Figure out out transmitting data info.
activity = self.is_network_active(self.parent.cur_sndbytes,
self.parent.max_snd_gain,
self.parent.last_sndbytes)
activity = self.is_network_active(sndbytes, self.max_snd_gain,
self.last_sndbytes)
transmitting = activity[0]
self.parent.max_snd_gain = activity[1]
self.parent.last_sndbytes = activity[2]
self.max_snd_gain = activity[1]
self.last_sndbytes = activity[2]
if transmitting and receiving:
return 'both-'
@@ -369,7 +466,7 @@ class TrayIcon(object):
tray icons.
"""
def __init__(self, parent):
def __init__(self):
menu = """
<ui>
<menubar name="Menubar">
@@ -377,7 +474,6 @@ class TrayIcon(object):
<menu action="Connect">
</menu>
<separator/>
<menuitem action="Info"/>
<menuitem action="About"/>
<menuitem action="Quit"/>
</menu>
@@ -387,9 +483,6 @@ class TrayIcon(object):
actions = [
('Menu', None, 'Menu'),
('Connect', gtk.STOCK_CONNECT, "Connect"),
('Info', gtk.STOCK_INFO, "_Connection Info", None,
'Information about the current connection',
self.on_conn_info),
('About', gtk.STOCK_ABOUT, '_About...', None,
'About wicd-tray-icon', self.on_about),
('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
@@ -408,11 +501,6 @@ class TrayIcon(object):
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
net_menuitem.connect("activate", self.on_net_menu_activate)
self.parent = parent
self.time = 2 # Time between updates
self.cont = 'Stop'
self.conn_info_txt = ''
def tray_scan_started(self):
""" Callback for when a wireless scan is started. """
if not DBUS_AVAIL: return
@@ -446,96 +534,6 @@ class TrayIcon(object):
dialog.set_website('http://wicd.net')
dialog.run()
dialog.destroy()
def on_conn_info(self, data=None):
""" Opens the Connection Information Dialog """
window = gtk.Dialog("Wicd Connection Info", None, 0, (gtk.STOCK_OK, gtk.RESPONSE_CLOSE))
# Create labels
self.label = gtk.Label()
self.data = gtk.Label()
self.label.show()
self.data.show()
self.list = []
self.list.append(self.data)
self.list.append(self.label)
# Setup table
table = gtk.Table(1,2)
table.set_col_spacings(12)
table.attach(self.label, 0, 1, 0, 1)
table.attach(self.data, 1, 2, 0 ,1)
# Setup Window
content = window.get_content_area()
content.pack_start(table, True, True, 0)
content.show_all()
# Start updates
self.cont = 'Go'
gobject.timeout_add(5000, self.update_conn_info_win, self.list)
self.update_conn_info_win(self.list)
window.run()
# Destroy window and stop updates
window.destroy()
self.cont = 'Stop'
def update_conn_info_win(self, list):
""" Updates the information in the connection summary window """
if (self.cont == "Stop"):
return False
[state, info] = daemon.GetConnectionStatus()
[rx, tx] = self.get_current_bandwidth()
# Choose info for the data
if state == misc.WIRED:
text = (language['conn_info_wired']
.replace('$A', str(info[0])) #IP
.replace('$B', str(rx)) #RX
.replace('$C', str(tx))) #TX
elif state == misc.WIRELESS:
text = (language['conn_info_wireless']
.replace('$A', str(info[1])) #SSID
.replace('$B', str(info[4])) #Speed
.replace('$C', str(info[0])) #IP
.replace('$D', daemon.FormatSignalForPrinting(str(info[2])))
.replace('$E', str(rx))
.replace('$F', str(tx)))
else:
text = ''
# Choose info for the labels
self.list[0].set_text(text)
if state == misc.WIRED:
self.list[1].set_text(language['conn_info_wired_labels'])
elif state == misc.WIRELESS:
self.list[1].set_text(language['conn_info_wireless_labels'])
elif state == misc.CONNECTING:
self.list[1].set_text(language['conn_info_connecting'])
elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
self.list[1].set_text(language['conn_info_not_connected'])
return True
def get_current_bandwidth(self):
"""
Calculates the current bandwidth based on sent/received bytes
divided over time. Unit is in KB/s
"""
self.parent.get_bandwidth_bytes()
rxb = self.parent.cur_rcvbytes - self.parent.last_rcvbytes
txb = self.parent.cur_sndbytes - self.parent.last_sndbytes
self.parent.last_rcvbytes = self.parent.cur_rcvbytes
self.parent.last_sndbytes = self.parent.cur_sndbytes
rx_rate = float(rxb / (self.time * 1024))
tx_rate = float(txb / (self.time * 1024))
return (rx_rate, tx_rate)
def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting,
is_active):
@@ -600,29 +598,29 @@ class TrayIcon(object):
signal_img = 'signal-25.png'
return wpath.images + signal_img
@catchdbus
def on_net_menu_activate(self, item):
""" Trigger a background scan to populate the network menu.
Called when the network submenu is moused over. We
sleep briefly, clear pending gtk events, and if
we're still being moused over we trigger a scan.
This is to prevent scans when the user is just
mousing past the menu to select another menu item.
Clear the network menu, and schedule a method to be
called in .8 seconds to trigger a scan if the menu
is still being moused over.
"""
def dummy(x=None): pass
if self._is_scanning:
return True
self.init_network_menu()
time.sleep(.4)
gobject.timeout_add(800, self._trigger_scan_if_needed, item)
@catchdbus
def _trigger_scan_if_needed(self, item):
""" Trigger a scan if the network menu is being hovered over. """
while gtk.events_pending():
gtk.main_iteration()
if item.state != gtk.STATE_PRELIGHT:
return True
return False
wireless.Scan(False)
return False
@catchdbus
def populate_network_menu(self, data=None):
@@ -671,7 +669,7 @@ class TrayIcon(object):
net_menuitem.show()
def init_network_menu(self):
""" Set the right-click menu for to the scanning state. """
""" Set the right-click network menu to the scanning state. """
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
submenu = net_menuitem.get_submenu()
self._clear_menu(submenu)
@@ -691,7 +689,7 @@ class TrayIcon(object):
def toggle_wicd_gui(self):
""" Toggles the wicd GUI. """
if not self.gui_win:
self.gui_win = gui.appGui()
self.gui_win = gui.appGui(tray=self)
elif not self.gui_win.is_visible:
self.gui_win.show_win()
else:
@@ -708,9 +706,9 @@ class TrayIcon(object):
for machines running versions of GTK < 2.10.
"""
def __init__(self, parent):
def __init__(self):
"""Initializes the tray icon"""
TrayIcon.TrayIconGUI.__init__(self, parent)
TrayIcon.TrayIconGUI.__init__(self)
self.tooltip = gtk.Tooltips()
self.eb = gtk.EventBox()
self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
@@ -744,6 +742,18 @@ class TrayIcon(object):
"""
self.tooltip.set_tip(self.eb, val)
def visible(self, val):
""" Set if the icon is visible or not.
If val is True, makes the icon visible, if val is False,
hides the tray icon.
"""
if val:
self.tray.show_all()
else:
self.tray.hide_all()
if hasattr(gtk, "StatusIcon"):
class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
@@ -752,8 +762,8 @@ class TrayIcon(object):
Uses gtk.StatusIcon to implement a tray icon.
"""
def __init__(self, parent):
TrayIcon.TrayIconGUI.__init__(self, parent)
def __init__(self):
TrayIcon.TrayIconGUI.__init__(self)
gtk.StatusIcon.__init__(self)
self.current_icon_path = ''
@@ -774,6 +784,14 @@ class TrayIcon(object):
self.current_icon_path = path
gtk.StatusIcon.set_from_file(self, path)
def visible(self, val):
""" Set if the icon is visible or not.
If val is True, makes the icon visible, if val is False,
hides the tray icon.
"""
self.set_visible(val)
def usage():
""" Print usage information. """
@@ -785,6 +803,7 @@ Arguments:
\t-n\t--no-tray\tRun wicd without the tray icon.
\t-h\t--help\t\tPrint this help information.
\t-a\t--no-animate\tRun the tray without network traffic tray animations.
\t-o\t--only-notifications\tDon't display anything except notifications.
""" % wpath.version
def setup_dbus(force=True):
@@ -798,7 +817,7 @@ def setup_dbus(force=True):
misc.PromptToStartDaemon()
try:
dbusmanager.connect_to_dbus()
except dbusmanager.DBusException:
except DBusException:
error(None, "Could not connect to wicd's D-Bus interface. " +
"Check the wicd log for error messages.")
return False
@@ -820,7 +839,7 @@ def on_exit():
if DBUS_AVAIL:
try:
daemon.SetGUIOpen(False)
except dbusmanager.DBusException:
except DBusException:
pass
def handle_no_dbus():
@@ -842,8 +861,9 @@ def main(argv):
"""
try:
opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
'no-animate'])
opts, args = getopt.getopt(sys.argv[1:], 'nhao', ['help', 'no-tray',
'no-animate',
'only-notifications'])
except getopt.GetoptError:
# Print help information and exit
usage()
@@ -851,6 +871,7 @@ def main(argv):
use_tray = True
animate = True
display_app = True
for opt, a in opts:
if opt in ('-h', '--help'):
usage()
@@ -859,6 +880,10 @@ def main(argv):
use_tray = False
elif opt in ('-a', '--no-animate'):
animate = False
elif opt in ('-o', '--only-notifications'):
print "only displaying notifications"
use_tray = False
display_app = False
else:
usage()
sys.exit(2)
@@ -867,14 +892,14 @@ def main(argv):
setup_dbus()
atexit.register(on_exit)
if not use_tray or not ICON_AVAIL:
if display_app and not use_tray or not ICON_AVAIL:
the_gui = gui.appGui(standalone=True)
mainloop = gobject.MainLoop()
mainloop.run()
sys.exit(0)
# Set up the tray icon GUI and backend
tray_icon = TrayIcon(animate)
tray_icon = TrayIcon(animate, displaytray=display_app)
# Check to see if wired profile chooser was called before icon
# was launched (typically happens on startup or daemon restart).

File diff suppressed because it is too large Load Diff

View File

@@ -6,18 +6,16 @@
This module implements functions to control and obtain information from
network interfaces.
def SetDNS() -- Set the DNS servers of the system.
def GetWirelessInterfaces() -- Get the wireless interfaces available.
class Interface() -- Control a network interface.
class WiredInterface() -- Control a wired network interface.
class WirelessInterface() -- Control a wireless network interface.
class BaseInterface() -- Control a network interface.
class BaseWiredInterface() -- Control a wired network interface.
class BaseWirelessInterface() -- Control a wireless network interface.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
# Copyright (C) 2007 - 2008 Byron Hillis
# Copyright (C) 2007 - 2009 Adam Blackburn
# Copyright (C) 2007 - 2009 Dan O'Reilly
# Copyright (C) 2007 - 2009 Byron Hillis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
@@ -43,30 +41,30 @@ import misc
from misc import find_path
# Regular expressions.
__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)
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)
bitrates_pattern = re.compile('.*Bit Rates:(.*?)E', __re_mode)
mode_pattern = re.compile('.*Mode:(.*?)\n', __re_mode)
freq_pattern = re.compile('.*Frequency:(.*?)\n', __re_mode)
wep_pattern = re.compile('.*Encryption key:(.*?)\n', __re_mode)
altwpa_pattern = re.compile('(wpa_ie)', __re_mode)
wpa1_pattern = re.compile('(WPA Version 1)', __re_mode)
wpa2_pattern = re.compile('(WPA2)', __re_mode)
_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)
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)
bitrates_pattern = re.compile('(\d+\s+\S+/s)', _re_mode)
mode_pattern = re.compile('.*Mode:(.*?)\n', _re_mode)
freq_pattern = re.compile('.*Frequency:(.*?)\n', _re_mode)
wep_pattern = re.compile('.*Encryption key:(.*?)\n', _re_mode)
altwpa_pattern = re.compile('(wpa_ie)', _re_mode)
wpa1_pattern = re.compile('(WPA Version 1)', _re_mode)
wpa2_pattern = re.compile('(WPA2)', _re_mode)
#iwconfig-only regular expressions.
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)',re.S)
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', __re_mode)
bitrate_pattern = re.compile('.*Bit Rate=(.*?/s)', __re_mode)
opmode_pattern = re.compile('.*Mode:(.*?) ', __re_mode)
authmethods_pattern = re.compile('.*Authentication capabilities :\n(.*?)Current', __re_mode)
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)', re.S)
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', _re_mode)
bitrate_pattern = re.compile('.*Bit Rate=(.*?/s)', _re_mode)
opmode_pattern = re.compile('.*Mode:(.*?) ', _re_mode)
authmethods_pattern = re.compile('.*Authentication capabilities :\n(.*?)Current', _re_mode)
# Regular expressions for wpa_cli output
auth_pattern = re.compile('.*wpa_state=(.*?)\n', __re_mode)
auth_pattern = re.compile('.*wpa_state=(.*?)\n', _re_mode)
RALINK_DRIVER = 'ralink legacy'
@@ -74,9 +72,6 @@ blacklist_strict = '!"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ '
blacklist_norm = ";`$!*|><&\\"
blank_trans = maketrans("", "")
__all__ = ["GetDefaultGateway", "GetWiredInterfaces",
"GetWirelessInterfaces", "IsValidWpaSuppDriver"]
def _sanitize_string(string):
if string:
return translate(str(string), blank_trans, blacklist_norm)
@@ -88,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. """
@@ -117,18 +137,18 @@ def GetWirelessInterfaces():
"""
dev_dir = '/sys/class/net/'
ifnames = []
ifnames = [iface for iface in os.listdir(dev_dir) if os.path.isdir(dev_dir + iface)
and 'wireless' in os.listdir(dev_dir + iface)]
ifnames = [iface for iface in os.listdir(dev_dir)
if os.path.isdir(dev_dir + iface) and
'wireless' in os.listdir(dev_dir + iface)]
return ifnames
def GetWiredInterfaces():
""" Returns a list of wired interfaces on the system. """
basedir = '/sys/class/net/'
return [iface for iface in os.listdir(basedir) if not 'wireless'
in os.listdir(basedir + iface) and
return [iface for iface in os.listdir(basedir)
if os.path.isdir(basedir + iface) and not 'wireless'
in os.listdir(basedir + iface) and
open(basedir + iface + "/type").readlines()[0].strip() == "1"]
def NeedsExternalCalls():
@@ -139,10 +159,7 @@ def IsValidWpaSuppDriver(driver):
""" Returns True if given string is a valid wpa_supplicant driver. """
output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iolan19",
"-c/etc/abcd%sdefzz.zconfz" % random.randint(1, 1000)])
if re.match("Unsupported driver", output):
return False
else:
return True
return not "Unsupported driver" in output
def neediface(default_response):
""" A decorator for only running a method if self.iface is defined.
@@ -154,7 +171,8 @@ def neediface(default_response):
"""
def wrapper(func):
def newfunc(self, *args, **kwargs):
if not self.iface:
if not self.iface or \
not os.path.exists('/sys/class/net/%s' % self.iface):
return default_response
return func(self, *args, **kwargs)
newfunc.__dict__ = func.__dict__
@@ -222,15 +240,20 @@ class BaseInterface(object):
"""
def get_client_name(cl):
""" Converts the integer value for a dhcp client to a string. """
if self.dhclient_cmd and cl in [misc.DHCLIENT, misc.AUTO]:
client = "dhclient"
cmd = self.dhclient_cmd
elif self.dhcpcd_cmd and cl in [misc.DHCPCD, misc.AUTO]:
if self.dhcpcd_cmd and cl in [misc.DHCPCD, misc.AUTO]:
client = "dhcpcd"
cmd = self.dhcpcd_cmd
elif self.pump_cmd and cl in [misc.PUMP, misc.AUTO]:
client = "pump"
cmd = self.pump_cmd
elif self.dhclient_cmd and cl in [misc.DHCLIENT, misc.AUTO]:
client = "dhclient"
cmd = self.dhclient_cmd
if self.dhclient_needs_verbose:
cmd += ' -v'
elif self.udhcpc_cmd and cl in [misc.UDHCPC, misc.AUTO]:
client = "udhcpc"
cmd = self.udhcpc_cmd
else:
client = None
cmd = ""
@@ -238,20 +261,25 @@ class BaseInterface(object):
client_dict = {
"dhclient" :
{'connect' : r"%s %s",
'release' : r"%s -r %s",
{'connect' : r"%(cmd)s %(iface)s",
'release' : r"%(cmd)s -r %(iface)s",
'id' : misc.DHCLIENT,
},
"pump" :
{ 'connect' : r"%s -i %s",
'release' : r"%s -r -i %s",
{ 'connect' : r"%(cmd)s -i %(iface)s",
'release' : r"%(cmd)s -r -i %(iface)s",
'id' : misc.PUMP,
},
"dhcpcd" :
{'connect' : r"%s %s",
'release' : r"%s -k %s",
{'connect' : r"%(cmd)s %(iface)s",
'release' : r"%(cmd)s -k %(iface)s",
'id' : misc.DHCPCD,
},
"udhcpc":
{'connect' : r"%(cmd)s -n -i %(iface)s",
'release' : r"killall -SIGUSR2 %(cmd)s",
'id' : misc.UDHCPC,
},
}
(client_name, cmd) = get_client_name(self.DHCP_CLIENT)
if not client_name or not cmd:
@@ -259,9 +287,9 @@ class BaseInterface(object):
return ""
if flavor == "connect":
return client_dict[client_name]['connect'] % (cmd, self.iface)
return client_dict[client_name]['connect'] % {"cmd":cmd, "iface":self.iface}
elif flavor == "release":
return client_dict[client_name]['release'] % (cmd, self.iface)
return client_dict[client_name]['release'] % {"cmd":cmd, "iface":self.iface}
else:
return client_dict[client_name]['id']
@@ -299,8 +327,16 @@ class BaseInterface(object):
"""
self.dhclient_cmd = self._find_program_path("dhclient")
if self.dhclient_cmd != None:
output = misc.Run(self.dhclient_cmd + " --version",
include_stderr=True)
if '4.' in output:
self.dhclient_needs_verbose = True
else:
self.dhclient_needs_verbose = False
self.dhcpcd_cmd = self._find_program_path("dhcpcd")
self.pump_cmd = self._find_program_path("pump")
self.udhcpc_cmd = self._find_program_path("udhcpc")
def CheckWiredTools(self):
""" Check for the existence of ethtool and mii-tool. """
@@ -348,6 +384,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):
@@ -397,7 +441,7 @@ class BaseInterface(object):
if line == '': # Empty string means dhclient is done.
dhclient_complete = True
else:
print line.strip('\n')
print misc.to_unicode(line.strip('\n'))
if line.startswith('bound'):
dhclient_success = True
dhclient_complete = True
@@ -424,7 +468,7 @@ class BaseInterface(object):
elif line.strip().lower().startswith('Operation failed.'):
pump_success = False
pump_complete = True
print line
print misc.to_unicode(line)
return self._check_dhcp_result(pump_success)
@@ -448,10 +492,34 @@ class BaseInterface(object):
dhcpcd_complete = True
elif line == '':
dhcpcd_complete = True
print line
print misc.to_unicode(line)
return self._check_dhcp_result(dhcpcd_success)
def _parse_udhcpc(self, pipe):
""" Determines if obtaining an IP using udhcpc succeeded.
Keyword arguments:
pipe -- stdout pipe to the dhcpcd process.
Returns:
'success' if successful, an error code string otherwise.
"""
udhcpc_complete = False
udhcpc_success = True
while not udhcpc_complete:
line = pipe.readline()
if line.endswith("failing"):
udhcpc_success = False
udhcpc_complete = True
elif line == '':
udhcpc_complete = True
print line
return self._check_dhcp_result(udhcpc_success)
def _check_dhcp_result(self, success):
""" Print and return the correct DHCP connection result.
@@ -490,6 +558,8 @@ class BaseInterface(object):
return self._parse_pump(pipe)
elif DHCP_CLIENT == misc.DHCPCD:
return self._parse_dhcpcd(pipe)
elif DHCP_CLIENT == misc.UDHCPC:
return self._parse_udhcpc(pipe)
else:
print 'ERROR no dhclient found!'
@@ -595,9 +665,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)
@@ -634,9 +702,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')
@@ -799,6 +865,7 @@ class BaseWirelessInterface(BaseInterface):
return radiostatus
@timedcache(2)
@neediface(False)
def GetIwconfig(self):
""" Returns the output of iwconfig for this interface. """
@@ -964,12 +1031,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.
@@ -982,7 +1054,7 @@ class BaseWirelessInterface(BaseInterface):
if not wpa_pass_path: return None
key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*',
re.I | re.M | re.S)
cmd = [wpa_pass_path, network['essid'], network['key']]
cmd = [wpa_pass_path, network['essid'], str(network['key'])]
if self.verbose: print cmd
return misc.RunRegex(key_pattern, misc.Run(cmd))
@@ -1070,15 +1142,21 @@ class BaseWirelessInterface(BaseInterface):
# An array for the access points
access_points = []
access_points = {}
for cell in networks:
# Only use sections where there is an ESSID.
if 'ESSID:' in cell:
# Add this network to the list of networks
entry = self._ParseAccessPoint(cell, ralink_info)
if entry is not None:
access_points.append(entry)
# Normally we only get duplicate bssids with hidden
# networks. If we hit this, we only want the entry
# with the real essid to be in the network list.
if (entry['bssid'] not in access_points
or not entry['hidden']):
access_points[entry['bssid']] = entry
return access_points
return access_points.values()
def _ParseAccessPoint(self, cell, ralink_info):
""" Parse a single cell from the output of iwlist.
@@ -1099,7 +1177,8 @@ class BaseWirelessInterface(BaseInterface):
except (UnicodeDecodeError, UnicodeEncodeError):
print 'Unicode problem with current network essid, ignoring!!'
return None
if ap['essid'] in ['<hidden>', ""]:
if ap['essid'] in ['<hidden>', "", None]:
print 'hidden'
ap['hidden'] = True
ap['essid'] = "<hidden>"
else:
@@ -1113,9 +1192,9 @@ class BaseWirelessInterface(BaseInterface):
ap['channel'] = self._FreqToChannel(freq)
# Bit Rate
ap['bitrates'] = misc.RunRegex(bitrates_pattern, cell).split('\n')
ap['bitrates'] = '; '.join(m.strip() for m in ap['bitrates']).rstrip('; ')
ap['bitrates'] = misc.RunRegex(bitrates_pattern,
cell.split("Bit Rates")[-1])
# BSSID
ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
@@ -1181,6 +1260,7 @@ class BaseWirelessInterface(BaseInterface):
MAX_TIME = 35
MAX_DISCONNECTED_TIME = 3
disconnected_time = 0
forced_rescan = False
while (time.time() - auth_time) < MAX_TIME:
cmd = '%s -i %s status' % (self.wpa_cli_cmd, self.iface)
output = misc.Run(cmd)
@@ -1192,11 +1272,12 @@ class BaseWirelessInterface(BaseInterface):
return False
if result == "COMPLETED":
return True
elif result == "DISCONNECTED":
elif result == "DISCONNECTED" and not forced_rescan:
disconnected_time += 1
if disconnected_time > MAX_DISCONNECTED_TIME:
disconnected_time = 0
# Force a rescan to get wpa_supplicant moving again.
forced_rescan = True
self._ForceSupplicantScan()
MAX_TIME += 5
else:
@@ -1233,9 +1314,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
@@ -1246,9 +1325,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
@@ -1259,9 +1336,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
@@ -1292,7 +1367,14 @@ class BaseWirelessInterface(BaseInterface):
(strength, max_strength) = (None, None)
if strength in ['', None]:
[(strength, max_strength)] = altstrength_pattern.findall(output)
try:
[(strength, max_strength)] = altstrength_pattern.findall(output)
except ValueError:
# if the pattern was unable to match anything
# we'll return 101, which will allow us to stay
# connected even though we don't know the strength
# it also allows us to tell if
return 101
if strength not in ['', None] and max_strength:
return (100 * int(strength) // int(max_strength))
elif strength not in ["", None]:
@@ -1309,9 +1391,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)
@@ -1325,9 +1405,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*)',
@@ -1344,9 +1422,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:"(.*?)"',