mirror of
https://github.com/gryf/wicd.git
synced 2026-01-29 11:55:45 +01:00
Experimental: Apply changes involving setup.py
* Added setup.py from trunk * Updated various information files (AUTHORS, README, etc) * Update the Wicd icon * Move stuff around to match trunk's layout
This commit is contained in:
44
wicd/autoconnect.py
Normal file
44
wicd/autoconnect.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import dbus
|
||||
import time
|
||||
import gobject
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
bus = dbus.SystemBus()
|
||||
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
|
||||
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
|
||||
|
||||
def reply_handle():
|
||||
loop.quit()
|
||||
def error_handle(e):
|
||||
loop.quit()
|
||||
|
||||
print daemon.Hello()
|
||||
time.sleep(3)
|
||||
daemon.SetSuspend(False)
|
||||
if not daemon.CheckIfConnecting():
|
||||
print daemon.AutoConnect(True, reply_handler=reply_handle,
|
||||
error_handler=error_handle)
|
||||
daemon.SetForcedDisconnect(False)
|
||||
|
||||
loop = gobject.MainLoop()
|
||||
loop.run()
|
||||
192
wicd/configscript.py
Executable file
192
wicd/configscript.py
Executable file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" 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
|
||||
editing scripts requires root access, and the GUI/Tray are typically
|
||||
run as the current user.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import gtk
|
||||
import ConfigParser
|
||||
import dbus
|
||||
import gtk.glade
|
||||
|
||||
import wicd.wpath as wpath
|
||||
import wicd.misc as misc
|
||||
|
||||
_ = misc.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")
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
|
||||
# Connect to the daemon
|
||||
try:
|
||||
print 'Attempting to connect tray to daemon...'
|
||||
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
|
||||
print 'Success.'
|
||||
except Exception:
|
||||
print 'Daemon not running...'
|
||||
misc.PromptToStartDaemon()
|
||||
sys.exit(1)
|
||||
|
||||
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
|
||||
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
|
||||
config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config')
|
||||
|
||||
wireless_conf = wpath.etc + 'wireless-settings.conf'
|
||||
wired_conf = wpath.etc + 'wired-settings.conf'
|
||||
|
||||
|
||||
def none_to_blank(text):
|
||||
""" Converts special string cases to a blank string.
|
||||
|
||||
If text is None, 'None', or '' then this method will
|
||||
return '', otherwise it will just return str(text).
|
||||
|
||||
"""
|
||||
if text in (None, "None", ""):
|
||||
return ""
|
||||
else:
|
||||
return str(text)
|
||||
|
||||
def blank_to_none(text):
|
||||
""" Convert an empty or null string to 'None'. """
|
||||
if text in ("", None):
|
||||
return "None"
|
||||
else:
|
||||
return str(text)
|
||||
|
||||
def get_val(con, network, option, default="None"):
|
||||
""" Returns the specified option for the given network.
|
||||
|
||||
Returns the value stored in the config file for the given option,
|
||||
unless the option isn't stored yet, in which case the default value
|
||||
provided is stored and then returned.
|
||||
|
||||
Keyword arguments:
|
||||
network -- The section to search.
|
||||
option -- The option to search for.
|
||||
deafult -- The default value to store/return if the option isn't found.
|
||||
|
||||
"""
|
||||
if not con.has_option(network, option):
|
||||
con.set(network, option, default)
|
||||
return con.get(network, option)
|
||||
|
||||
|
||||
def get_script_info(network, network_type):
|
||||
""" Read script info from disk and load it into the configuration dialog """
|
||||
info = {}
|
||||
con = ConfigParser.ConfigParser()
|
||||
if network_type == "wired":
|
||||
con.read(wired_conf)
|
||||
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")
|
||||
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")
|
||||
return info
|
||||
|
||||
def write_scripts(network, network_type, script_info):
|
||||
""" Writes script info to disk and loads it into the daemon. """
|
||||
con = ConfigParser.ConfigParser()
|
||||
|
||||
if network_type == "wired":
|
||||
con.read(wired_conf)
|
||||
if not con.has_section(network):
|
||||
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.write(open(wired_conf, "w"))
|
||||
config.ReadWiredNetworkProfile(network)
|
||||
config.SaveWiredNetworkProfile(network)
|
||||
else:
|
||||
bssid = wireless.GetWirelessProperty(int(network), "bssid")
|
||||
con.read(wireless_conf)
|
||||
if not con.has_section(bssid):
|
||||
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.write(open(wireless_conf, "w"))
|
||||
config.ReadWirelessNetworkProfile(int(network))
|
||||
config.SaveWirelessNetworkProfile(int(network))
|
||||
|
||||
def main (argv):
|
||||
""" Runs the script configuration dialog. """
|
||||
if len(argv) < 2:
|
||||
print 'Network id to configure is missing, aborting.'
|
||||
sys.exit(1)
|
||||
|
||||
network = argv[1]
|
||||
network_type = argv[2]
|
||||
|
||||
script_info = get_script_info(network, network_type)
|
||||
|
||||
gladefile = wpath.etc + "wicd.glade"
|
||||
wTree = gtk.glade.XML(gladefile)
|
||||
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("window1").hide()
|
||||
|
||||
pre_entry = wTree.get_widget("pre_entry")
|
||||
post_entry = wTree.get_widget("post_entry")
|
||||
disconnect_entry = wTree.get_widget("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")))
|
||||
|
||||
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())
|
||||
write_scripts(network, network_type, script_info)
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if os.getuid() != 0:
|
||||
print "Root privileges are required to configure scripts. Exiting."
|
||||
sys.exit(0)
|
||||
main(sys.argv)
|
||||
1463
wicd/daemon.py
Normal file
1463
wicd/daemon.py
Normal file
File diff suppressed because it is too large
Load Diff
0
wicd/dbusmanager.py
Normal file
0
wicd/dbusmanager.py
Normal file
903
wicd/gui.py
Normal file
903
wicd/gui.py
Normal file
@@ -0,0 +1,903 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
""" Wicd GUI module.
|
||||
|
||||
Module containg all the code (other than the tray icon) related to the
|
||||
Wicd user interface.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import gobject
|
||||
import pango
|
||||
import gtk
|
||||
import gtk.glade
|
||||
from dbus import DBusException
|
||||
from dbus import version as dbus_version
|
||||
|
||||
import wicd.misc
|
||||
import wicd.wpath
|
||||
from wicd.misc import noneToString, noneToBlankString, stringToBoolean, checkboxTextboxToggle
|
||||
from wicd.netentry import WiredNetworkEntry, WirelessNetworkEntry
|
||||
from wicd.prefs import PreferencesDialog
|
||||
from wicd.dbusmanager import DBusManager
|
||||
|
||||
if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
try:
|
||||
import pygtk
|
||||
pygtk.require("2.0")
|
||||
except:
|
||||
pass
|
||||
|
||||
if not dbus_version or (dbus_version < (0, 80, 0)):
|
||||
import dbus.glib
|
||||
else:
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
proxy_obj, daemon, wireless, wired, bus, config = [None for x in
|
||||
range(0, 6)]
|
||||
language = misc.get_language_list_gui()
|
||||
|
||||
def setup_dbus(dbus_man=None):
|
||||
global bus, daemon, wireless, wired, config, dbus_manager
|
||||
if dbus_man:
|
||||
dbus_manager = dbus_man
|
||||
else:
|
||||
dbus_manager = DBusManager()
|
||||
try:
|
||||
dbus_manager.connect_to_dbus()
|
||||
except DBusException:
|
||||
print "Can't connect to the daemon, trying to start it automatically..."
|
||||
misc.PromptToStartDaemon()
|
||||
try:
|
||||
dbus_manager.connect_to_dbus()
|
||||
except DBusException:
|
||||
error(None, "Could not connect to wicd's D-Bus interface. " +
|
||||
"Make sure the daemon is started.")
|
||||
sys.exit(1)
|
||||
|
||||
bus = dbus_manager.get_bus()
|
||||
dbus_ifaces = dbus_manager.get_dbus_ifaces()
|
||||
daemon = dbus_ifaces['daemon']
|
||||
wireless = dbus_ifaces['wireless']
|
||||
wired = dbus_ifaces['wired']
|
||||
config = dbus_ifaces['config']
|
||||
return True
|
||||
|
||||
|
||||
def error(parent, message):
|
||||
""" Shows an error dialog """
|
||||
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
|
||||
gtk.BUTTONS_OK)
|
||||
dialog.set_markup(message)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
########################################
|
||||
##### GTK EXTENSION CLASSES
|
||||
########################################
|
||||
|
||||
class SmallLabel(gtk.Label):
|
||||
def __init__(self, text=''):
|
||||
gtk.Label.__init__(self, text)
|
||||
self.set_size_request(50, -1)
|
||||
|
||||
class LabelEntry(gtk.HBox):
|
||||
""" A label on the left with a textbox on the right. """
|
||||
def __init__(self,text):
|
||||
gtk.HBox.__init__(self)
|
||||
self.entry = gtk.Entry()
|
||||
self.entry.set_size_request(200, -1)
|
||||
self.label = SmallLabel()
|
||||
self.label.set_text(text)
|
||||
self.label.set_size_request(170, -1)
|
||||
self.pack_start(self.label, fill=False, expand=False)
|
||||
self.pack_start(self.entry, fill=False, expand=False)
|
||||
self.label.show()
|
||||
self.entry.show()
|
||||
self.entry.connect('focus-out-event', self.hide_characters)
|
||||
self.entry.connect('focus-in-event', self.show_characters)
|
||||
self.auto_hide_text = False
|
||||
self.show()
|
||||
|
||||
def set_text(self, text):
|
||||
# For compatibility...
|
||||
self.entry.set_text(text)
|
||||
|
||||
def get_text(self):
|
||||
return self.entry.get_text()
|
||||
|
||||
def set_auto_hidden(self, value):
|
||||
self.entry.set_visibility(False)
|
||||
self.auto_hide_text = value
|
||||
|
||||
def show_characters(self, widget=None, event=None):
|
||||
# When the box has focus, show the characters
|
||||
if self.auto_hide_text and widget:
|
||||
self.entry.set_visibility(True)
|
||||
|
||||
def set_sensitive(self, value):
|
||||
self.entry.set_sensitive(value)
|
||||
self.label.set_sensitive(value)
|
||||
|
||||
def hide_characters(self, widget=None, event=None):
|
||||
# When the box looses focus, hide them
|
||||
if self.auto_hide_text and widget:
|
||||
self.entry.set_visibility(False)
|
||||
|
||||
|
||||
class GreyLabel(gtk.Label):
|
||||
""" Creates a grey gtk.Label. """
|
||||
def __init__(self):
|
||||
gtk.Label.__init__(self)
|
||||
|
||||
def set_label(self, text):
|
||||
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
|
||||
self.set_alignment(0, 0)
|
||||
|
||||
|
||||
class WiredProfileChooser:
|
||||
""" Class for displaying the wired profile chooser. """
|
||||
def __init__(self):
|
||||
""" Initializes and runs the wired profile chooser. """
|
||||
# Import and init WiredNetworkEntry to steal some of the
|
||||
# functions and widgets it uses.
|
||||
wired_net_entry = WiredNetworkEntry(dbus_manager.get_dbus_ifaces())
|
||||
|
||||
dialog = gtk.Dialog(title = language['wired_network_found'],
|
||||
flags = gtk.DIALOG_MODAL,
|
||||
buttons = (gtk.STOCK_CONNECT, 1,
|
||||
gtk.STOCK_CANCEL, 2))
|
||||
dialog.set_has_separator(False)
|
||||
dialog.set_size_request(400, 150)
|
||||
instruct_label = gtk.Label(language['choose_wired_profile'] + ':\n')
|
||||
stoppopcheckbox = gtk.CheckButton(language['stop_showing_chooser'])
|
||||
|
||||
wired_net_entry.is_full_gui = False
|
||||
instruct_label.set_alignment(0, 0)
|
||||
stoppopcheckbox.set_active(False)
|
||||
|
||||
# Remove widgets that were added to the normal WiredNetworkEntry
|
||||
# so that they can be added to the pop-up wizard.
|
||||
wired_net_entry.vbox_top.remove(wired_net_entry.hbox_temp)
|
||||
wired_net_entry.vbox_top.remove(wired_net_entry.profile_help)
|
||||
|
||||
dialog.vbox.pack_start(instruct_label, fill=False, expand=False)
|
||||
dialog.vbox.pack_start(wired_net_entry.profile_help, False, False)
|
||||
dialog.vbox.pack_start(wired_net_entry.hbox_temp, False, False)
|
||||
dialog.vbox.pack_start(stoppopcheckbox, False, False)
|
||||
dialog.show_all()
|
||||
|
||||
wired_profiles = wired_net_entry.combo_profile_names
|
||||
wired_net_entry.profile_help.hide()
|
||||
if wired_net_entry.profile_list != None:
|
||||
wired_profiles.set_active(0)
|
||||
print "wired profiles found"
|
||||
else:
|
||||
print "no wired profiles found"
|
||||
wired_net_entry.profile_help.show()
|
||||
|
||||
response = dialog.run()
|
||||
if response == 1:
|
||||
print 'reading profile ', wired_profiles.get_active_text()
|
||||
config.ReadWiredNetworkProfile(wired_profiles.get_active_text())
|
||||
wired.ConnectWired()
|
||||
else:
|
||||
if stoppopcheckbox.get_active():
|
||||
daemon.SetForcedDisconnect(True)
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
class appGui(object):
|
||||
""" The main wicd GUI class. """
|
||||
def __init__(self, dbus_man=None, standalone=False):
|
||||
""" Initializes everything needed for the GUI. """
|
||||
if not standalone:
|
||||
setup_dbus(dbus_man)
|
||||
|
||||
gladefile = "data/wicd.glade"
|
||||
self.wTree = gtk.glade.XML(gladefile)
|
||||
|
||||
dic = { "refresh_clicked" : self.refresh_networks,
|
||||
"quit_clicked" : self.exit,
|
||||
"disconnect_clicked" : self.disconnect_all,
|
||||
"main_exit" : self.exit,
|
||||
"cancel_clicked" : self.cancel_connect,
|
||||
"connect_clicked" : self.connect_hidden,
|
||||
"preferences_clicked" : self.settings_dialog,
|
||||
"about_clicked" : self.about_dialog,
|
||||
"create_adhoc_network_button_button" : self.create_adhoc_network,
|
||||
"on_iface_menu_enable_wireless" : self.on_enable_wireless,
|
||||
"on_iface_menu_disable_wireless" : self.on_disable_wireless,
|
||||
"on_iface_menu_enable_wired" : self.on_enable_wired,
|
||||
"on_iface_menu_disable_wired" : self.on_disable_wired,}
|
||||
self.wTree.signal_autoconnect(dic)
|
||||
|
||||
# Set some strings in the GUI - they may be translated
|
||||
label_instruct = self.wTree.get_widget("label_instructions")
|
||||
label_instruct.set_label(language['select_a_network'])
|
||||
|
||||
probar = self.wTree.get_widget("progressbar")
|
||||
probar.set_text(language['connecting'])
|
||||
|
||||
self.window = self.wTree.get_widget("window1")
|
||||
self.network_list = self.wTree.get_widget("network_list_vbox")
|
||||
self.status_area = self.wTree.get_widget("connecting_hbox")
|
||||
self.status_bar = self.wTree.get_widget("statusbar")
|
||||
|
||||
self.status_area.hide_all()
|
||||
|
||||
if os.path.exists(wpath.etc + "wicd.png"):
|
||||
self.window.set_icon_from_file(wpath.etc + "wicd.png")
|
||||
self.statusID = None
|
||||
self.first_dialog_load = True
|
||||
self.is_visible = True
|
||||
self.pulse_active = False
|
||||
self.standalone = standalone
|
||||
self.wpadrivercombo = None
|
||||
self.connecting = False
|
||||
self.fast = True # Use ioctl instead of external program calls
|
||||
self.prev_state = None
|
||||
self.refresh_networks(fresh=False)
|
||||
|
||||
self.window.connect('delete_event', self.exit)
|
||||
self.window.connect('key-release-event', self.key_event)
|
||||
|
||||
if not wireless.IsWirelessUp():
|
||||
self.wTree.get_widget("iface_menu_disable_wireless").hide()
|
||||
else:
|
||||
self.wTree.get_widget("iface_menu_enable_wireless").hide()
|
||||
if not wired.IsWiredUp():
|
||||
self.wTree.get_widget("iface_menu_disable_wired").hide()
|
||||
else:
|
||||
self.wTree.get_widget("iface_menu_enable_wired").hide()
|
||||
|
||||
size = config.ReadWindowSize("main")
|
||||
width = size[0]
|
||||
height = size[1]
|
||||
if width > -1 and height > -1:
|
||||
self.window.resize(int(width), int(height))
|
||||
|
||||
gobject.timeout_add(400, self.update_statusbar)
|
||||
|
||||
def create_adhoc_network(self, widget=None):
|
||||
""" Shows a dialog that creates a new adhoc network. """
|
||||
print "Starting the Ad-Hoc Network Creation Process..."
|
||||
dialog = gtk.Dialog(title = language['create_adhoc_network'],
|
||||
flags = gtk.DIALOG_MODAL,
|
||||
buttons=(gtk.STOCK_OK, 1, gtk.STOCK_CANCEL, 2))
|
||||
dialog.set_has_separator(False)
|
||||
dialog.set_size_request(400, -1)
|
||||
self.chkbox_use_encryption = gtk.CheckButton(language['use_wep_encryption'])
|
||||
self.chkbox_use_encryption.set_active(False)
|
||||
ip_entry = LabelEntry(language['ip'] + ':')
|
||||
essid_entry = LabelEntry(language['essid'] + ':')
|
||||
channel_entry = LabelEntry(language['channel'] + ':')
|
||||
self.key_entry = LabelEntry(language['key'] + ':')
|
||||
self.key_entry.set_auto_hidden(True)
|
||||
self.key_entry.set_sensitive(False)
|
||||
|
||||
chkbox_use_ics = gtk.CheckButton(language['use_ics'])
|
||||
|
||||
self.chkbox_use_encryption.connect("toggled",
|
||||
self.toggle_encrypt_check)
|
||||
channel_entry.entry.set_text('3')
|
||||
essid_entry.entry.set_text('My_Adhoc_Network')
|
||||
ip_entry.entry.set_text('169.254.12.10') # Just a random IP
|
||||
|
||||
vbox_ah = gtk.VBox(False, 0)
|
||||
vbox_ah.pack_start(self.chkbox_use_encryption, False, False)
|
||||
vbox_ah.pack_start(self.key_entry, False, False)
|
||||
vbox_ah.show()
|
||||
dialog.vbox.pack_start(essid_entry)
|
||||
dialog.vbox.pack_start(ip_entry)
|
||||
dialog.vbox.pack_start(channel_entry)
|
||||
dialog.vbox.pack_start(chkbox_use_ics)
|
||||
dialog.vbox.pack_start(vbox_ah)
|
||||
dialog.vbox.set_spacing(5)
|
||||
dialog.show_all()
|
||||
response = dialog.run()
|
||||
if response == 1:
|
||||
wireless.CreateAdHocNetwork(essid_entry.entry.get_text(),
|
||||
channel_entry.entry.get_text(),
|
||||
ip_entry.entry.get_text(), "WEP",
|
||||
self.key_entry.entry.get_text(),
|
||||
self.chkbox_use_encryption.get_active(),
|
||||
False) #chkbox_use_ics.get_active())
|
||||
dialog.destroy()
|
||||
|
||||
def toggle_encrypt_check(self, widget=None):
|
||||
""" Toggles the encryption key entry box for the ad-hoc dialog. """
|
||||
self.key_entry.set_sensitive(self.chkbox_use_encryption.get_active())
|
||||
|
||||
def disconnect_all(self, widget=None):
|
||||
""" Disconnects from any active network. """
|
||||
daemon.Disconnect()
|
||||
|
||||
def about_dialog(self, widget, event=None):
|
||||
""" Displays an about dialog. """
|
||||
dialog = gtk.AboutDialog()
|
||||
dialog.set_name("Wicd")
|
||||
dialog.set_version(daemon.Hello())
|
||||
dialog.set_authors([ "Adam Blackburn", "Dan O'Reilly" ])
|
||||
dialog.set_website("http://wicd.sourceforge.net")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
def key_event (self, widget, event=None):
|
||||
""" Handle key-release-events. """
|
||||
if event.state & gtk.gdk.CONTROL_MASK and \
|
||||
gtk.gdk.keyval_name(event.keyval) in ["w", "q"]:
|
||||
self.exit()
|
||||
|
||||
def settings_dialog(self, widget, event=None):
|
||||
""" Displays a general settings dialog. """
|
||||
pref = PreferencesDialog(self.wTree, dbus_manager.get_dbus_ifaces())
|
||||
if pref.run() == 1:
|
||||
pref.save_results()
|
||||
pref.hide()
|
||||
|
||||
def connect_hidden(self, widget):
|
||||
""" Prompts the user for a hidden network, then scans for it. """
|
||||
dialog = gtk.Dialog(title=language['hidden_network'],
|
||||
flags=gtk.DIALOG_MODAL,
|
||||
buttons=(gtk.STOCK_CONNECT, 1, gtk.STOCK_CANCEL, 2))
|
||||
dialog.set_has_separator(False)
|
||||
lbl = gtk.Label(language['hidden_network_essid'])
|
||||
textbox = gtk.Entry()
|
||||
dialog.vbox.pack_start(lbl)
|
||||
dialog.vbox.pack_start(textbox)
|
||||
dialog.show_all()
|
||||
button = dialog.run()
|
||||
if button == 1:
|
||||
answer = textbox.get_text()
|
||||
dialog.destroy()
|
||||
self.refresh_networks(None, True, answer)
|
||||
else:
|
||||
dialog.destroy()
|
||||
|
||||
def on_enable_wireless(self, widget):
|
||||
""" Called when the Enable Wireless Interface button is clicked. """
|
||||
success = wireless.EnableWirelessInterface()
|
||||
if success:
|
||||
enable_item = self.wTree.get_widget("iface_menu_enable_wireless")
|
||||
disable_item = self.wTree.get_widget("iface_menu_disable_wireless")
|
||||
enable_item.hide()
|
||||
disable_item.show()
|
||||
else:
|
||||
error(self.window, "Failed to enable wireless interface.")
|
||||
|
||||
def on_disable_wireless(self, widget):
|
||||
""" Called when the Disable Wireless Interface button is clicked. """
|
||||
success = wireless.DisableWirelessInterface()
|
||||
if success:
|
||||
enable_item = self.wTree.get_widget("iface_menu_enable_wireless")
|
||||
disable_item = self.wTree.get_widget("iface_menu_disable_wireless")
|
||||
enable_item.show()
|
||||
disable_item.hide()
|
||||
else:
|
||||
error(self.window, "Failed to disable wireless interface.")
|
||||
|
||||
def on_enable_wired(self, widget):
|
||||
""" Called when the Enable Wired Interface button is clicked. """
|
||||
success = wired.EnableWiredInterface()
|
||||
if success:
|
||||
enable_item = self.wTree.get_widget("iface_menu_enable_wired")
|
||||
disable_item = self.wTree.get_widget("iface_menu_disable_wired")
|
||||
enable_item.hide()
|
||||
disable_item.show()
|
||||
else:
|
||||
error(self.window, "Failed to enable wired interface.")
|
||||
|
||||
def on_disable_wired(self, widget):
|
||||
""" Called when the Disable Wired Interface button is clicked. """
|
||||
success = wired.DisableWiredInterface()
|
||||
if success:
|
||||
enable_item = self.wTree.get_widget("iface_menu_enable_wired")
|
||||
disable_item = self.wTree.get_widget("iface_menu_disable_wired")
|
||||
enable_item.show()
|
||||
disable_item.hide()
|
||||
else:
|
||||
error(self.window, "Failed to disable wired interface.")
|
||||
|
||||
def cancel_connect(self, widget):
|
||||
""" Alerts the daemon to cancel the connection process. """
|
||||
#should cancel a connection if there
|
||||
#is one in progress
|
||||
cancel_button = self.wTree.get_widget("cancel_button")
|
||||
cancel_button.set_sensitive(False)
|
||||
daemon.CancelConnect()
|
||||
# Prevents automatic reconnecting if that option is enabled
|
||||
daemon.SetForcedDisconnect(True)
|
||||
|
||||
def pulse_progress_bar(self):
|
||||
""" Pulses the progress bar while connecting to a network. """
|
||||
if not self.pulse_active:
|
||||
return False
|
||||
if not self.is_visible:
|
||||
return True
|
||||
try:
|
||||
self.wTree.get_widget("progressbar").pulse()
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
|
||||
def update_statusbar(self):
|
||||
""" Updates the status bar. """
|
||||
if not self.is_visible:
|
||||
return True
|
||||
|
||||
fast = self.fast
|
||||
wired_connecting = wired.CheckIfWiredConnecting()
|
||||
wireless_connecting = wireless.CheckIfWirelessConnecting()
|
||||
self.connecting = wired_connecting or wireless_connecting
|
||||
|
||||
if self.connecting:
|
||||
if not self.pulse_active:
|
||||
self.pulse_active = True
|
||||
gobject.timeout_add(100, self.pulse_progress_bar)
|
||||
self.network_list.set_sensitive(False)
|
||||
self.status_area.show_all()
|
||||
if self.statusID:
|
||||
self.status_bar.remove(1, self.statusID)
|
||||
if wireless_connecting:
|
||||
if not fast:
|
||||
iwconfig = wireless.GetIwconfig()
|
||||
else:
|
||||
iwconfig = ''
|
||||
self.set_status(wireless.GetCurrentNetwork(iwconfig, fast) + ': ' +
|
||||
language[str(wireless.CheckWirelessConnectingMessage())])
|
||||
if wired_connecting:
|
||||
self.set_status(language['wired_network'] + ': ' +
|
||||
language[str(wired.CheckWiredConnectingMessage())])
|
||||
return True
|
||||
else:
|
||||
if self.pulse_active:
|
||||
self.pulse_progress_bar()
|
||||
self.pulse_active = False
|
||||
self.network_list.set_sensitive(True)
|
||||
self.status_area.hide_all()
|
||||
|
||||
if self.statusID:
|
||||
self.status_bar.remove(1, self.statusID)
|
||||
|
||||
# Determine connection status.
|
||||
if self.check_for_wired(wired.GetWiredIP(fast)):
|
||||
return True
|
||||
if not fast:
|
||||
iwconfig = wireless.GetIwconfig()
|
||||
else:
|
||||
iwconfig = ''
|
||||
if self.check_for_wireless(iwconfig,
|
||||
wireless.GetWirelessIP(fast)):
|
||||
return True
|
||||
self.set_status(language['not_connected'])
|
||||
return True
|
||||
|
||||
def update_connect_buttons(self, state=None, x=None, force_check=False):
|
||||
""" Updates the connect/disconnect buttons for each network entry. """
|
||||
if not state:
|
||||
state, x = daemon.GetConnectionStatus()
|
||||
|
||||
if self.prev_state != state or force_check:
|
||||
apbssid = wireless.GetApBssid()
|
||||
for entry in self.network_list:
|
||||
if hasattr(entry, "update_connect_button"):
|
||||
entry.update_connect_button(state, apbssid)
|
||||
self.prev_state = state
|
||||
|
||||
def check_for_wired(self, wired_ip):
|
||||
""" Determine if wired is active, and if yes, set the status. """
|
||||
if wired_ip and wired.CheckPluggedIn(self.fast):
|
||||
self.set_status(language['connected_to_wired'].replace('$A',
|
||||
wired_ip))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_for_wireless(self, iwconfig, wireless_ip):
|
||||
""" Determine if wireless is active, and if yes, set the status. """
|
||||
if not wireless_ip:
|
||||
return False
|
||||
|
||||
network = wireless.GetCurrentNetwork(iwconfig, self.fast)
|
||||
if not network:
|
||||
return False
|
||||
|
||||
network = str(network)
|
||||
if daemon.GetSignalDisplayType() == 0:
|
||||
strength = wireless.GetCurrentSignalStrength(iwconfig, self.fast)
|
||||
else:
|
||||
strength = wireless.GetCurrentDBMStrength(iwconfig, self.fast)
|
||||
|
||||
if strength is None:
|
||||
return False
|
||||
strength = str(strength)
|
||||
ip = str(wireless_ip)
|
||||
self.set_status(language['connected_to_wireless'].replace
|
||||
('$A', network).replace
|
||||
('$B', daemon.FormatSignalForPrinting(strength)).replace
|
||||
('$C', wireless_ip))
|
||||
return True
|
||||
|
||||
def set_status(self, msg):
|
||||
""" Sets the status bar message for the GUI. """
|
||||
self.statusID = self.status_bar.push(1, msg)
|
||||
|
||||
def dbus_scan_finished(self):
|
||||
""" Calls for a non-fresh update of the gui window.
|
||||
|
||||
This method is called after the daemon runs an automatic
|
||||
rescan.
|
||||
|
||||
"""
|
||||
if not self.connecting:
|
||||
self.refresh_networks(fresh=False)
|
||||
|
||||
def dbus_scan_started(self):
|
||||
self.network_list.set_sensitive(False)
|
||||
|
||||
def refresh_networks(self, widget=None, fresh=True, hidden=None):
|
||||
""" Refreshes the network list.
|
||||
|
||||
If fresh=True, scans for wireless networks and displays the results.
|
||||
If a ethernet connection is available, or the user has chosen to,
|
||||
displays a Wired Network entry as well.
|
||||
If hidden isn't None, will scan for networks after running
|
||||
iwconfig <wireless interface> essid <hidden>.
|
||||
|
||||
"""
|
||||
print "refreshing..."
|
||||
self.network_list.set_sensitive(False)
|
||||
self.wait_for_events()
|
||||
printLine = False # We don't print a separator by default.
|
||||
# Remove stuff already in there.
|
||||
for z in self.network_list:
|
||||
self.network_list.remove(z)
|
||||
z.destroy()
|
||||
del z
|
||||
|
||||
if wired.CheckPluggedIn(self.fast) or wired.GetAlwaysShowWiredInterface():
|
||||
printLine = True # In this case we print a separator.
|
||||
wirednet = WiredNetworkEntry(dbus_manager.get_dbus_ifaces())
|
||||
self.network_list.pack_start(wirednet, False, False)
|
||||
wirednet.connect_button.connect("button-press-event", self.connect,
|
||||
"wired", 0, wirednet)
|
||||
wirednet.disconnect_button.connect("button-press-event", self.disconnect,
|
||||
"wired", 0, wirednet)
|
||||
wirednet.advanced_button.connect("button-press-event",
|
||||
self.edit_advanced, "wired", 0,
|
||||
wirednet)
|
||||
# Scan
|
||||
if fresh:
|
||||
# Even if it is None, it can still be passed.
|
||||
wireless.SetHiddenNetworkESSID(noneToString(hidden))
|
||||
wireless.Scan()
|
||||
|
||||
num_networks = wireless.GetNumberOfNetworks()
|
||||
instruct_label = self.wTree.get_widget("label_instructions")
|
||||
if num_networks > 0:
|
||||
instruct_label.show()
|
||||
for x in range(0, num_networks):
|
||||
if printLine:
|
||||
sep = gtk.HSeparator()
|
||||
self.network_list.pack_start(sep, padding=10, fill=False,
|
||||
expand=False)
|
||||
sep.show()
|
||||
else:
|
||||
printLine = True
|
||||
tempnet = WirelessNetworkEntry(x, dbus_manager.get_dbus_ifaces())
|
||||
self.network_list.pack_start(tempnet, False, False)
|
||||
tempnet.connect_button.connect("button-press-event",
|
||||
self.connect, "wireless", x,
|
||||
tempnet)
|
||||
tempnet.disconnect_button.connect("button-press-event",
|
||||
self.disconnect, "wireless",
|
||||
x, tempnet)
|
||||
tempnet.advanced_button.connect("button-press-event",
|
||||
self.edit_advanced, "wireless",
|
||||
x, tempnet)
|
||||
else:
|
||||
instruct_label.hide()
|
||||
if wireless.GetKillSwitchEnabled():
|
||||
label = gtk.Label(language['killswitch_enabled'] + ".")
|
||||
else:
|
||||
label = gtk.Label(language['no_wireless_networks_found'])
|
||||
self.network_list.pack_start(label)
|
||||
label.show()
|
||||
self.update_connect_buttons(force_check=True)
|
||||
self.network_list.set_sensitive(True)
|
||||
|
||||
def save_settings(self, nettype, networkid, networkentry):
|
||||
""" Verifies and saves the settings for the network entry. """
|
||||
entry = networkentry.advanced_dialog
|
||||
entlist = []
|
||||
|
||||
# First make sure all the Addresses entered are valid.
|
||||
if entry.chkbox_static_ip.get_active():
|
||||
entlist = [ent for ent in [entry.txt_ip, entry.txt_netmask,
|
||||
entry.txt_gateway]]
|
||||
|
||||
if entry.chkbox_static_dns.get_active() and \
|
||||
not entry.chkbox_global_dns.get_active():
|
||||
entlist.append(entry.txt_dns_1)
|
||||
# Only append additional dns entries if they're entered.
|
||||
for ent in [entry.txt_dns_2, entry.txt_dns_3]:
|
||||
if ent.get_text() != "":
|
||||
entlist.append(ent)
|
||||
for lblent in entlist:
|
||||
if not misc.IsValidIP(lblent.get_text()):
|
||||
error(self.window, language['invalid_address'].
|
||||
replace('$A', lblent.label.get_label()))
|
||||
return False
|
||||
|
||||
# Now save the settings.
|
||||
if nettype == "wireless":
|
||||
if not self.save_wireless_settings(networkid, entry, networkentry):
|
||||
return False
|
||||
|
||||
elif nettype == "wired":
|
||||
if not self.save_wired_settings(entry):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def save_wired_settings(self, entry):
|
||||
""" Saved wired network settings. """
|
||||
if entry.chkbox_static_ip.get_active():
|
||||
entry.set_net_prop("ip", noneToString(entry.txt_ip.get_text()))
|
||||
entry.set_net_prop("netmask", noneToString(entry.txt_netmask.get_text()))
|
||||
entry.set_net_prop("gateway", noneToString(entry.txt_gateway.get_text()))
|
||||
else:
|
||||
entry.set_net_prop("ip", '')
|
||||
entry.set_net_prop("netmask", '')
|
||||
entry.set_net_prop("gateway", '')
|
||||
|
||||
if entry.chkbox_static_dns.get_active() and \
|
||||
not entry.chkbox_global_dns.get_active():
|
||||
entry.set_net_prop('use_static_dns', True)
|
||||
entry.set_net_prop('use_global_dns', False)
|
||||
entry.set_net_prop("dns1", noneToString(entry.txt_dns_1.get_text()))
|
||||
entry.set_net_prop("dns2", noneToString(entry.txt_dns_2.get_text()))
|
||||
entry.set_net_prop("dns3", noneToString(entry.txt_dns_3.get_text()))
|
||||
elif entry.chkbox_static_dns.get_active() and \
|
||||
entry.chkbox_global_dns.get_active():
|
||||
entry.set_net_prop('use_static_dns', True)
|
||||
entry.set_net_prop('use_global_dns', True)
|
||||
else:
|
||||
entry.set_net_prop('use_static_dns', False)
|
||||
entry.set_net_prop("dns1", '')
|
||||
entry.set_net_prop("dns2", '')
|
||||
entry.set_net_prop("dns3", '')
|
||||
config.SaveWiredNetworkProfile(entry.prof_name)
|
||||
return True
|
||||
|
||||
def save_wireless_settings(self, networkid, entry, netent):
|
||||
""" Save wireless network settings. """
|
||||
# Check encryption info
|
||||
if entry.chkbox_encryption.get_active():
|
||||
print "setting encryption info..."
|
||||
encryption_info = entry.encryption_info
|
||||
encrypt_methods = misc.LoadEncryptionMethods()
|
||||
entry.set_net_prop("enctype",
|
||||
encrypt_methods[entry.combo_encryption.
|
||||
get_active()][1])
|
||||
for x in encryption_info:
|
||||
if encryption_info[x].get_text() == "":
|
||||
error(self.window, language['encrypt_info_missing'])
|
||||
return False
|
||||
entry.set_net_prop(x, noneToString(encryption_info[x].
|
||||
get_text()))
|
||||
elif not entry.chkbox_encryption.get_active() and \
|
||||
wireless.GetWirelessProperty(networkid, "encryption"):
|
||||
error(self.window, language['enable_encryption'])
|
||||
return False
|
||||
else:
|
||||
print 'encryption is ' + str(wireless.GetWirelessProperty(networkid,
|
||||
"encryption"))
|
||||
print "no encryption specified..."
|
||||
entry.set_net_prop("enctype", "None")
|
||||
|
||||
entry.set_net_prop("automatic",
|
||||
noneToString(netent.chkbox_autoconnect.get_active()))
|
||||
# Save IP info
|
||||
if entry.chkbox_static_ip.get_active():
|
||||
entry.set_net_prop("ip", noneToString(entry.txt_ip.get_text()))
|
||||
entry.set_net_prop("netmask",
|
||||
noneToString(entry.txt_netmask.get_text()))
|
||||
entry.set_net_prop("gateway",
|
||||
noneToString(entry.txt_gateway.get_text()))
|
||||
else:
|
||||
# Blank the values
|
||||
entry.set_net_prop("ip", '')
|
||||
entry.set_net_prop("netmask", '')
|
||||
entry.set_net_prop("gateway", '')
|
||||
|
||||
# Save DNS info
|
||||
if entry.chkbox_static_dns.get_active() and \
|
||||
not entry.chkbox_global_dns.get_active():
|
||||
entry.set_net_prop('use_static_dns', True)
|
||||
entry.set_net_prop('use_global_dns', False)
|
||||
entry.set_net_prop('dns1', noneToString(entry.txt_dns_1.get_text()))
|
||||
entry.set_net_prop('dns2', noneToString(entry.txt_dns_2.get_text()))
|
||||
entry.set_net_prop('dns3', noneToString(entry.txt_dns_3.get_text()))
|
||||
elif entry.chkbox_static_dns.get_active() and \
|
||||
entry.chkbox_global_dns.get_active():
|
||||
entry.set_net_prop('use_static_dns', True)
|
||||
entry.set_net_prop('use_global_dns', True)
|
||||
else:
|
||||
entry.set_net_prop('use_static_dns', False)
|
||||
entry.set_net_prop('use_global_dns', False)
|
||||
entry.set_net_prop('dns1', '')
|
||||
entry.set_net_prop('dns2', '')
|
||||
entry.set_net_prop('dns3', '')
|
||||
|
||||
if entry.chkbox_global_settings.get_active():
|
||||
entry.set_net_prop('use_settings_globally', True)
|
||||
else:
|
||||
entry.set_net_prop('use_settings_globally', False)
|
||||
config.RemoveGlobalEssidEntry(networkid)
|
||||
|
||||
config.SaveWirelessNetworkProfile(networkid)
|
||||
return True
|
||||
|
||||
def edit_advanced(self, widget, event, ttype, networkid, networkentry):
|
||||
""" Display the advanced settings dialog.
|
||||
|
||||
Displays the advanced settings dialog and saves any changes made.
|
||||
If errors occur in the settings, an error message will be displayed
|
||||
and the user won't be able to save the changes until the errors
|
||||
are fixed.
|
||||
|
||||
"""
|
||||
dialog = networkentry.advanced_dialog
|
||||
dialog.set_values()
|
||||
dialog.show_all()
|
||||
while True:
|
||||
if self.run_settings_dialog(dialog, ttype, networkid, networkentry):
|
||||
break
|
||||
dialog.hide()
|
||||
|
||||
def run_settings_dialog(self, dialog, nettype, networkid, networkentry):
|
||||
""" Runs the settings dialog.
|
||||
|
||||
Runs the settings dialog and returns True if settings are saved
|
||||
successfully, and false otherwise.
|
||||
|
||||
"""
|
||||
result = dialog.run()
|
||||
if result == gtk.RESPONSE_ACCEPT:
|
||||
if self.save_settings(nettype, networkid, networkentry):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_encryption_valid(self, networkid, entry):
|
||||
""" Make sure that encryption settings are properly filled in. """
|
||||
# Make sure no entries are left blank
|
||||
if entry.chkbox_encryption.get_active():
|
||||
encryption_info = entry.encryption_info
|
||||
for x in encryption_info:
|
||||
if encryption_info[x].get_text() == "":
|
||||
error(self.window, language['encrypt_info_missing'])
|
||||
return False
|
||||
# Make sure the checkbox is checked when it should be
|
||||
elif not entry.chkbox_encryption.get_active() and \
|
||||
wireless.GetWirelessProperty(networkid, "encryption"):
|
||||
error(self.window, language['enable_encryption'])
|
||||
return False
|
||||
return True
|
||||
|
||||
def connect(self, widget, event, nettype, networkid, networkentry):
|
||||
""" Initiates the connection process in the daemon. """
|
||||
cancel_button = self.wTree.get_widget("cancel_button")
|
||||
cancel_button.set_sensitive(True)
|
||||
if nettype == "wireless":
|
||||
if not self.check_encryption_valid(networkid,
|
||||
networkentry.advanced_dialog):
|
||||
return False
|
||||
wireless.ConnectWireless(networkid)
|
||||
elif nettype == "wired":
|
||||
wired.ConnectWired()
|
||||
self.update_statusbar()
|
||||
|
||||
def disconnect(self, widget, event, nettype, networkid, networkentry):
|
||||
""" Disconnects from the given network.
|
||||
|
||||
Keyword arguments:
|
||||
widget -- The disconnect button that was pressed.
|
||||
event -- unused
|
||||
nettype -- "wired" or "wireless", depending on the network entry type.
|
||||
networkid -- unused
|
||||
networkentry -- The NetworkEntry containing the disconnect button.
|
||||
|
||||
"""
|
||||
widget.hide()
|
||||
networkentry.connect_button.show()
|
||||
if nettype == "wired":
|
||||
wired.DisconnectWired()
|
||||
else:
|
||||
wireless.DisconnectWireless()
|
||||
|
||||
def wait_for_events(self, amt=0):
|
||||
""" Wait for any pending gtk events to finish before moving on.
|
||||
|
||||
Keyword arguments:
|
||||
amt -- a number specifying the number of ms to wait before checking
|
||||
for pending events.
|
||||
|
||||
"""
|
||||
time.sleep(amt)
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
def exit(self, widget=None, event=None):
|
||||
""" Hide the wicd GUI.
|
||||
|
||||
This method hides the wicd GUI and writes the current window size
|
||||
to disc for later use. This method normally does NOT actually
|
||||
destroy the GUI, it just hides it.
|
||||
|
||||
"""
|
||||
self.window.hide()
|
||||
[width, height] = self.window.get_size()
|
||||
config.WriteWindowSize(width, height, "main")
|
||||
|
||||
if self.standalone:
|
||||
self.window.destroy()
|
||||
sys.exit(0)
|
||||
|
||||
self.is_visible = False
|
||||
daemon.SetGUIOpen(False)
|
||||
self.wait_for_events()
|
||||
return True
|
||||
|
||||
def show_win(self):
|
||||
""" Brings the GUI out of the hidden state.
|
||||
|
||||
Method to show the wicd GUI, alert the daemon that it is open,
|
||||
and refresh the network list.
|
||||
|
||||
"""
|
||||
self.window.show()
|
||||
self.wait_for_events()
|
||||
self.is_visible = True
|
||||
daemon.SetGUIOpen(True)
|
||||
self.wait_for_events(0.1)
|
||||
self.window.grab_focus()
|
||||
gobject.idle_add(self.refresh_networks)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setup_dbus()
|
||||
app = appGui(standalone=True)
|
||||
bus.add_signal_receiver(app.dbus_scan_finished, 'SendEndScanSignal',
|
||||
'org.wicd.daemon')
|
||||
bus.add_signal_receiver(app.dbus_scan_started, 'SendStartScanSignal',
|
||||
'org.wicd.daemon')
|
||||
bus.add_signal_receiver(app.update_connect_buttons, 'StatusChanged',
|
||||
'org.wicd.daemon')
|
||||
gtk.main()
|
||||
175
wicd/logfile.py
Normal file
175
wicd/logfile.py
Normal file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (C) 1999-2006 Keith Dart <keith@kdart.com>
|
||||
# Copyright (C) 2008 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
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
"""
|
||||
Managing logfile rotation. A ManagedLog object is a file-like object that
|
||||
rotates itself when a maximum size is reached.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
class SizeError(IOError):
|
||||
pass
|
||||
|
||||
class LogFile(file):
|
||||
"""LogFile(name, [mode="w"], [maxsize=360000])
|
||||
Opens a new file object. After writing <maxsize> bytes a SizeError will be
|
||||
raised. """
|
||||
def __init__(self, name, mode="a", maxsize=360000):
|
||||
super(LogFile, self).__init__(name, mode)
|
||||
self.maxsize = maxsize
|
||||
self.eol = True
|
||||
try:
|
||||
self.written = os.fstat(self.fileno())[6]
|
||||
except OSError:
|
||||
self.written = 0
|
||||
|
||||
def write(self, data):
|
||||
self.written += len(data)
|
||||
|
||||
data = data.decode('utf-8').encode('utf-8')
|
||||
if len(data) <= 0: return
|
||||
if self.eol:
|
||||
super(LogFile, self).write(self.get_time() + ' :: ')
|
||||
self.eol = False
|
||||
|
||||
if data[-1] == '\n':
|
||||
self.eol = True
|
||||
data = data[:-1]
|
||||
|
||||
super(LogFile, self).write(data.replace(
|
||||
'\n', '\n' + self.get_time() + ' :: '))
|
||||
if self.eol:
|
||||
super(LogFile, self).write('\n')
|
||||
|
||||
self.flush()
|
||||
if self.written > self.maxsize:
|
||||
raise SizeError
|
||||
|
||||
def get_time(self):
|
||||
""" Return a string with the current time nicely formatted.
|
||||
|
||||
The format of the returned string is yyyy/mm/dd HH:MM:SS
|
||||
|
||||
"""
|
||||
x = time.localtime()
|
||||
return ''.join([
|
||||
str(x[0]).rjust(4, '0'), '/', str(x[1]).rjust(2, '0'), '/',
|
||||
str(x[2]).rjust(2, '0'), ' ', str(x[3]).rjust(2, '0'), ':',
|
||||
str(x[4]).rjust(2, '0'), ':', str(x[5]).rjust(2, '0')])
|
||||
|
||||
def rotate(self):
|
||||
return rotate(self)
|
||||
|
||||
def note(self, text):
|
||||
"""Writes a specially formated note text to the file.The note starts
|
||||
with the string '\\n#*=' so you can easily filter them. """
|
||||
self.write("\n#*===== %s =====\n" % (text,))
|
||||
|
||||
|
||||
class ManagedLog(object):
|
||||
"""ManagedLog(name, [maxsize=360000], [maxsave=9])
|
||||
A ManagedLog instance is a persistent log object. Write data with the
|
||||
write() method. The log size and rotation is handled automatically.
|
||||
|
||||
"""
|
||||
def __init__(self, name, maxsize=360000, maxsave=3):
|
||||
self._lf = LogFile(name, "a", maxsize)
|
||||
self.maxsave = maxsave
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r, %r, %r)" % (self.__class__.__name__, self._lf.name,
|
||||
self._lf.maxsize, self.maxsave)
|
||||
|
||||
def write(self, data):
|
||||
try:
|
||||
self._lf.write(data)
|
||||
except SizeError:
|
||||
self._lf = rotate(self._lf, self.maxsave)
|
||||
|
||||
def note(self, data):
|
||||
try:
|
||||
self._lf.note(data)
|
||||
except SizeError:
|
||||
self._lf = rotate(self._lf, self.maxsave)
|
||||
|
||||
def written(self):
|
||||
return self._lf.written
|
||||
|
||||
def rotate(self):
|
||||
self._lf = rotate(self._lf, self.maxsave)
|
||||
|
||||
# auto-delegate remaining methods (but you should not read or seek an open
|
||||
# log file).
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._lf, name)
|
||||
|
||||
|
||||
# useful for logged stdout for daemon processes
|
||||
class ManagedStdio(ManagedLog):
|
||||
def write(self, data):
|
||||
try:
|
||||
self._lf.write(data)
|
||||
except SizeError:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
self._lf = rotate(self._lf, self.maxsave)
|
||||
fd = self._lf.fileno()
|
||||
os.dup2(fd, 1)
|
||||
os.dup2(fd, 2)
|
||||
sys.stdout = sys.stderr = self
|
||||
|
||||
|
||||
def rotate(fileobj, maxsave=9):
|
||||
name = fileobj.name
|
||||
mode = fileobj.mode
|
||||
maxsize = fileobj.maxsize
|
||||
fileobj.close()
|
||||
shiftlogs(name, maxsave)
|
||||
return LogFile(name, mode, maxsize)
|
||||
|
||||
|
||||
# assumes basename logfile is closed.
|
||||
def shiftlogs(basename, maxsave):
|
||||
topname = "%s.%d" % (basename, maxsave)
|
||||
if os.path.isfile(topname):
|
||||
os.unlink(topname)
|
||||
|
||||
for i in range(maxsave, 0, -1):
|
||||
oldname = "%s.%d" % (basename, i)
|
||||
newname = "%s.%d" % (basename, i+1)
|
||||
try:
|
||||
os.rename(oldname, newname)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
os.rename(basename, "%s.1" % (basename))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def open(name, maxsize=360000, maxsave=9):
|
||||
return ManagedLog(name, maxsize, maxsave)
|
||||
|
||||
def writelog(logobj, data):
|
||||
try:
|
||||
logobj.write(data)
|
||||
except SizeError:
|
||||
return rotate(logobj)
|
||||
else:
|
||||
return logobj
|
||||
493
wicd/misc.py
Normal file
493
wicd/misc.py
Normal file
@@ -0,0 +1,493 @@
|
||||
""" Misc - miscellaneous functions for wicd """
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
import locale
|
||||
import gettext
|
||||
import sys
|
||||
from subprocess import Popen, STDOUT, PIPE
|
||||
import subprocess
|
||||
import commands
|
||||
|
||||
import wicd.wpath as wpath
|
||||
|
||||
if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
NOT_CONNECTED = 0
|
||||
CONNECTING = 1
|
||||
WIRELESS = 2
|
||||
WIRED = 3
|
||||
SUSPENDED = 4
|
||||
|
||||
AUTO = 0
|
||||
DHCLIENT = 1
|
||||
DHCPCD = 2
|
||||
PUMP = 3
|
||||
|
||||
ETHTOOL = 1
|
||||
MIITOOL = 2
|
||||
|
||||
IP = 1
|
||||
ROUTE = 2
|
||||
|
||||
class WicdError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def Run(cmd, include_stderr=False, return_pipe=False):
|
||||
""" Run a command.
|
||||
|
||||
Runs the given command, returning either the output
|
||||
of the program, or a pipe to read output from.
|
||||
|
||||
keyword arguments --
|
||||
cmd - The command to execute
|
||||
include_std_err - Boolean specifying if stderr should
|
||||
be included in the pipe to the cmd.
|
||||
return_pipe - Boolean specifying if a pipe to the
|
||||
command should be returned. If it is
|
||||
false, all that will be returned is
|
||||
one output string from the command.
|
||||
|
||||
"""
|
||||
|
||||
cmd = to_unicode(str(cmd))
|
||||
if include_stderr:
|
||||
err = STDOUT
|
||||
fds = True
|
||||
else:
|
||||
err = None
|
||||
fds = False
|
||||
|
||||
f = Popen(cmd, shell=True, stdout=PIPE, stderr=err, close_fds=fds)
|
||||
|
||||
if return_pipe:
|
||||
return f.stdout
|
||||
else:
|
||||
return f.communicate()[0]
|
||||
|
||||
def LaunchAndWait(cmd):
|
||||
""" Launches the given program with the given arguments, then blocks. """
|
||||
subprocess.call(cmd)
|
||||
|
||||
def IsValidIP(ip):
|
||||
""" Make sure an entered IP is valid """
|
||||
if ip != None:
|
||||
if ip.count('.') == 3:
|
||||
ipNumbers = ip.split('.')
|
||||
for number in ipNumbers:
|
||||
if not number.isdigit() or int(number) > 255:
|
||||
return False
|
||||
return ipNumbers
|
||||
return False
|
||||
|
||||
def PromptToStartDaemon():
|
||||
""" Prompt the user to start the daemon """
|
||||
daemonloc = wpath.bin + 'launchdaemon.sh'
|
||||
sudo_prog = choose_sudo_prog()
|
||||
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
|
||||
msg = '--message'
|
||||
else:
|
||||
msg = '--caption'
|
||||
sudo_args = [sudo_prog, msg,
|
||||
'Wicd needs to access your computer\'s network cards.',
|
||||
daemonloc]
|
||||
os.spawnvpe(os.P_WAIT, sudo_prog, sudo_args, os.environ)
|
||||
|
||||
def RunRegex(regex, string):
|
||||
""" runs a regex search on a string """
|
||||
m = regex.search(string)
|
||||
if m:
|
||||
return m.groups()[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def WriteLine(my_file, text):
|
||||
""" write a line to a file """
|
||||
my_file.write(text + "\n")
|
||||
|
||||
def ExecuteScript(script):
|
||||
""" Execute a command and send its output to the bit bucket. """
|
||||
os.system("%s > /dev/null 2>&1" % script)
|
||||
|
||||
def ReadFile(filename):
|
||||
""" read in a file and return it's contents as a string """
|
||||
if not os.path.exists(filename):
|
||||
return None
|
||||
my_file = open(filename,'r')
|
||||
data = my_file.read().strip()
|
||||
my_file.close()
|
||||
return str(data)
|
||||
|
||||
def to_bool(var):
|
||||
""" Convert a string to type bool, but make "False"/"0" become False. """
|
||||
if var in ("False", "0"):
|
||||
var = False
|
||||
else:
|
||||
var = bool(var)
|
||||
return var
|
||||
|
||||
def Noneify(variable):
|
||||
""" Convert string types to either None or booleans"""
|
||||
#set string Nones to real Nones
|
||||
if variable in ("None", "", None):
|
||||
return None
|
||||
if variable in ("False", "0"):
|
||||
return False
|
||||
if variable in ("True", "1"):
|
||||
return True
|
||||
return variable
|
||||
|
||||
def ParseEncryption(network):
|
||||
""" Parse through an encryption template file
|
||||
|
||||
Parses an encryption template, reading in a network's info
|
||||
and creating a config file for it
|
||||
|
||||
"""
|
||||
enctemplate = open("encryption/templates/" + network["enctype"])
|
||||
template = enctemplate.readlines()
|
||||
# Set these to nothing so that we can hold them outside the loop
|
||||
z = "ap_scan=1\n"
|
||||
# Loop through the lines in the template, selecting ones to use
|
||||
for y, x in enumerate(template):
|
||||
x = x.strip("\n")
|
||||
if y > 4:
|
||||
# replace values
|
||||
x = x.replace("$_SCAN","0")
|
||||
for t in network:
|
||||
# Don't bother if z's value is None cause it will cause errors
|
||||
if Noneify(network[t]) is not None:
|
||||
x = x.replace("$_" + str(t).upper(), str(network[t]))
|
||||
z = z + "\n" + x
|
||||
|
||||
# Write the data to the files then chmod them so they can't be read
|
||||
# by normal users.
|
||||
file = open(wpath.networks + network["bssid"].replace(":", "").lower(), "w")
|
||||
os.chmod(wpath.networks + network["bssid"].replace(":", "").lower(), 0600)
|
||||
os.chown(wpath.networks + network["bssid"].replace(":", "").lower(), 0, 0)
|
||||
# We could do this above, but we'd like to read protect
|
||||
# them before we write, so that it can't be read.
|
||||
file.write(z)
|
||||
file.close()
|
||||
|
||||
def LoadEncryptionMethods():
|
||||
""" Load encryption methods from configuration files
|
||||
|
||||
Loads all the encryption methods from the template files
|
||||
in /encryption/templates into a data structure. To be
|
||||
loaded, the template must be listed in the "active" file.
|
||||
|
||||
"""
|
||||
def parse_ent(line, key):
|
||||
return line.replace(key, "").replace("=", "").strip()
|
||||
|
||||
encryptionTypes = []
|
||||
try:
|
||||
enctypes = open("encryption/templates/active","r").readlines()
|
||||
except IOError, e:
|
||||
print "Fatal Error: template index file is missing."
|
||||
raise IOError(e)
|
||||
|
||||
# Parse each encryption method
|
||||
for x in enctypes:
|
||||
x = x.strip()
|
||||
try:
|
||||
f = open("encryption/templates/" + x, "r")
|
||||
except IOError:
|
||||
print 'Failed to load encryption type ' + str(x)
|
||||
continue
|
||||
line = f.readlines()
|
||||
f.close()
|
||||
|
||||
cur_type = {}
|
||||
cur_type[0] = parse_ent(line[0], "name")
|
||||
cur_type[1] = x
|
||||
cur_type[2] = {}
|
||||
|
||||
# Find the line containing our required fields.
|
||||
i = 1
|
||||
try:
|
||||
while not line[i].startswith("require"):
|
||||
i += 1
|
||||
except IndexError:
|
||||
print "Bad encryption template: Couldn't find 'require' line"
|
||||
requiredFields = parse_ent(line[i], "require")
|
||||
requiredFields = requiredFields.split(" ")
|
||||
|
||||
# Get the required fields.
|
||||
index = -1
|
||||
for current in requiredFields:
|
||||
# The pretty names will start with an * so we can
|
||||
# separate them with that.
|
||||
if current[0] == "*":
|
||||
# Make underscores spaces
|
||||
# and remove the *
|
||||
cur_type[2][index][0] = current.replace("_", " ").lstrip("*")
|
||||
else:
|
||||
# Add to the list of things that are required.
|
||||
index = len(cur_type[2])
|
||||
cur_type[2][index] = {}
|
||||
cur_type[2][index][1] = current
|
||||
# Add the current type to the dict of encryption types.
|
||||
encryptionTypes.append(cur_type)
|
||||
return encryptionTypes
|
||||
|
||||
def noneToString(text):
|
||||
""" Convert None, "None", or "" to string type "None"
|
||||
|
||||
Used for putting text in a text box. If the value to put in is 'None',
|
||||
the box will be blank.
|
||||
|
||||
"""
|
||||
if text in (None, ""):
|
||||
return "None"
|
||||
else:
|
||||
return str(text)
|
||||
|
||||
def get_gettext():
|
||||
""" Set up gettext for translations. """
|
||||
# Borrowed from an excellent post on how to do this at
|
||||
# http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/
|
||||
local_path = os.path.realpath(os.path.dirname(sys.argv[0])) + \
|
||||
'/translations'
|
||||
langs = []
|
||||
lc, encoding = locale.getdefaultlocale()
|
||||
if (lc):
|
||||
langs = [lc]
|
||||
osLanguage = os.environ.get('LANGUAGE', None)
|
||||
if (osLanguage):
|
||||
langs += osLanguage.split(":")
|
||||
langs += ["en_US"]
|
||||
lang = gettext.translation('wicd', local_path, languages=langs,
|
||||
fallback=True)
|
||||
_ = lang.gettext
|
||||
return _
|
||||
|
||||
def to_unicode(x):
|
||||
""" Attempts to convert a string to utf-8. """
|
||||
try: # This may never fail, but let's be safe
|
||||
encoding = locale.getpreferredencoding()
|
||||
except:
|
||||
# Just guess utf-8 if it fails.
|
||||
encoding = 'utf-8'
|
||||
ret = x.decode(encoding, 'replace').encode('utf-8')
|
||||
return ret
|
||||
|
||||
def RenameProcess(new_name):
|
||||
if sys.platform != 'linux2':
|
||||
print 'Unsupported platform'
|
||||
return False
|
||||
try:
|
||||
import ctypes
|
||||
is_64 = os.path.exists('/lib64/libc.so.6')
|
||||
if is_64:
|
||||
libc = ctypes.CDLL('/lib64/libc.so.6')
|
||||
else:
|
||||
libc = ctypes.CDLL('/lib/libc.so.6')
|
||||
libc.prctl(15, new_name, 0, 0, 0)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def detect_desktop_environment():
|
||||
desktop_environment = 'generic'
|
||||
if os.environ.get('KDE_FULL_SESSION') == 'true':
|
||||
desktop_environment = 'kde'
|
||||
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
|
||||
desktop_environment = 'gnome'
|
||||
else:
|
||||
try:
|
||||
info = commands.getoutput('xprop -root _DT_SAVE_MODE')
|
||||
if ' = "xfce4"' in info:
|
||||
desktop_environment = 'xfce'
|
||||
except (OSError, RuntimeError):
|
||||
pass
|
||||
|
||||
return desktop_environment
|
||||
|
||||
def choose_sudo_prog():
|
||||
desktop_env = detect_desktop_environment()
|
||||
env_path = os.environ['PATH'].split(":")
|
||||
|
||||
if desktop_env == "kde":
|
||||
paths = []
|
||||
for p in env_path:
|
||||
paths.extend([p + '/kdesu', p + '/kdesudo', p + '/ktsuss'])
|
||||
else:
|
||||
paths = []
|
||||
for p in env_path:
|
||||
paths.extend([p + '/gksu', p + '/ktsuss'])
|
||||
for path in paths:
|
||||
if os.access(path, os.F_OK):
|
||||
return path
|
||||
|
||||
raise WicdError("Couldn't find graphical sudo program.")
|
||||
|
||||
def get_language_list_gui():
|
||||
""" Returns a dict of translatable strings used by the GUI.
|
||||
|
||||
translations are done at http://wicd.net/translator. Please
|
||||
translate if you can.
|
||||
|
||||
"""
|
||||
_ = get_gettext()
|
||||
language = {}
|
||||
language['connect'] = _("Connect")
|
||||
language['ip'] = _("IP")
|
||||
language['netmask'] = _("Netmask")
|
||||
language['gateway'] = _('Gateway')
|
||||
language['dns'] = _('DNS')
|
||||
language['use_static_ip'] = _('Use Static IPs')
|
||||
language['use_static_dns'] = _('Use Static DNS')
|
||||
language['use_encryption'] = _('Use Encryption')
|
||||
language['advanced_settings'] = _('Advanced Settings')
|
||||
language['wired_network'] = _('Wired Network')
|
||||
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['automatic_connect'] = _('Automatically connect to this network')
|
||||
language['secured'] = _('Secured')
|
||||
language['unsecured'] = _('Unsecured')
|
||||
language['channel'] = _('Channel')
|
||||
language['preferences'] = _('Preferences')
|
||||
language['wpa_supplicant_driver'] = _('WPA Supplicant Driver')
|
||||
language['wireless_interface'] = _('Wireless Interface')
|
||||
language['wired_interface'] = _('Wired Interface')
|
||||
language['hidden_network'] = _('Hidden Network')
|
||||
language['hidden_network_essid'] = _('Hidden Network ESSID')
|
||||
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
|
||||
language['connected_to_wired'] = _('Connected to wired network (IP: $A)')
|
||||
language['not_connected'] = _('Not connected')
|
||||
language['no_wireless_networks_found'] = _('No wireless networks found.')
|
||||
language['killswitch_enabled'] = _('Wireless Kill Switch Enabled')
|
||||
language['key'] = _('Key')
|
||||
language['username'] = _('Username')
|
||||
language['password'] = _('Password')
|
||||
language['anonymous_identity'] = _('Anonymous Identity')
|
||||
language['identity'] = _('Identity')
|
||||
language['authentication'] = _('Authentication')
|
||||
language['path_to_pac_file'] = _('Path to PAC File')
|
||||
language['select_a_network'] = _('Choose from the networks below:')
|
||||
language['connecting'] = _('Connecting...')
|
||||
language['wired_always_on'] = _('Always show wired interface')
|
||||
language['auto_reconnect'] = _('Automatically reconnect on connection loss')
|
||||
language['create_adhoc_network'] = _('Create an Ad-Hoc Network')
|
||||
language['essid'] = _('ESSID')
|
||||
language['use_wep_encryption'] = _('Use Encryption (WEP only)')
|
||||
language['before_script'] = _('Run script before connect')
|
||||
language['after_script'] = _('Run script after connect')
|
||||
language['disconnect_script'] = _('Run disconnect script')
|
||||
language['script_settings'] = _('Scripts')
|
||||
language['use_ics'] = _('Activate Internet Connection Sharing')
|
||||
language['madwifi_for_adhoc'] = _('Check if using madwifi/atheros drivers')
|
||||
language['default_wired'] = _('Use as default profile (overwrites any previous default)')
|
||||
language['use_debug_mode'] = _('Enable debug mode')
|
||||
language['use_global_dns'] = _('Use global DNS servers')
|
||||
language['use_default_profile'] = _('Use default profile on wired autoconnect')
|
||||
language['show_wired_list'] = _('Prompt for profile on wired autoconnect')
|
||||
language['use_last_used_profile'] = _('Use last used profile on wired autoconnect')
|
||||
language['choose_wired_profile'] = _('Select or create a wired profile to connect with')
|
||||
language['wired_network_found'] = _('Wired connection detected')
|
||||
language['stop_showing_chooser'] = _('Stop Showing Autoconnect pop-up temporarily')
|
||||
language['display_type_dialog'] = _('Use dBm to measure signal strength')
|
||||
language['scripts'] = _('Scripts')
|
||||
language['invalid_address'] = _('Invalid address in $A entry.')
|
||||
language['global_settings'] = _('Use these settings for all networks sharing this essid')
|
||||
language['encrypt_info_missing'] = _('Required encryption information is missing.')
|
||||
language['enable_encryption'] = _('This network requires encryption to be enabled.')
|
||||
language['wicd_auto_config'] = _('Automatic (recommended)')
|
||||
language["gen_settings"] = _("General Settings")
|
||||
language["ext_programs"] = _("External Programs")
|
||||
language["dhcp_client"] = _("DHCP Client")
|
||||
language["wired_detect"] = _("Wired Link Detection")
|
||||
language["route_flush"] = _("Route Table Flushing")
|
||||
|
||||
language['0'] = _('0')
|
||||
language['1'] = _('1')
|
||||
language['2'] = _('2')
|
||||
language['3'] = _('3')
|
||||
language['4'] = _('4')
|
||||
language['5'] = _('5')
|
||||
language['6'] = _('6')
|
||||
language['7'] = _('7')
|
||||
language['8'] = _('8')
|
||||
language['9'] = _('9')
|
||||
|
||||
language['interface_down'] = _('Putting interface down...')
|
||||
language['resetting_ip_address'] = _('Resetting IP address...')
|
||||
language['interface_up'] = _('Putting interface up...')
|
||||
language['setting_encryption_info'] = _('Setting encryption info')
|
||||
language['removing_old_connection'] = _('Removing old connection...')
|
||||
language['generating_psk'] = _('Generating PSK...')
|
||||
language['generating_wpa_config'] = _('Generating WPA configuration file...')
|
||||
language['flushing_routing_table'] = _('Flushing the routing table...')
|
||||
language['configuring_interface'] = _('Configuring wireless interface...')
|
||||
language['validating_authentication'] = _('Validating authentication...')
|
||||
language['setting_broadcast_address'] = _('Setting broadcast address...')
|
||||
language['setting_static_dns'] = _('Setting static DNS servers...')
|
||||
language['setting_static_ip'] = _('Setting static IP addresses...')
|
||||
language['running_dhcp'] = _('Obtaining IP address...')
|
||||
language['dhcp_failed'] = _('Connection Failed: Unable to Get IP Address')
|
||||
language['aborted'] = _('Connection Cancelled')
|
||||
language['bad_pass'] = _('Connection Failed: Bad password')
|
||||
language['done'] = _('Done connecting...')
|
||||
|
||||
return language
|
||||
|
||||
def get_language_list_tray():
|
||||
_ = get_gettext()
|
||||
language = {}
|
||||
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
|
||||
language['connected_to_wired'] = _('Connected to wired network (IP: $A)')
|
||||
language['not_connected'] = _('Not connected')
|
||||
language['killswitch_enabled'] = _('Wireless Kill Switch Enabled')
|
||||
language['connecting'] = _('Connecting')
|
||||
language['wired'] = _('Wired Network')
|
||||
language['scanning'] = _('Scanning')
|
||||
|
||||
return language
|
||||
|
||||
def noneToBlankString(text):
|
||||
""" Converts NoneType or "None" to a blank string. """
|
||||
if text in (None, "None"):
|
||||
return ""
|
||||
else:
|
||||
return str(text)
|
||||
|
||||
def stringToNone(text):
|
||||
""" Performs opposite function of noneToString. """
|
||||
if text in ("", None, "None"):
|
||||
return None
|
||||
else:
|
||||
return str(text)
|
||||
|
||||
def stringToBoolean(text):
|
||||
""" Turns a string representation of a bool to a boolean if needed. """
|
||||
if text in ("True", "1"):
|
||||
return True
|
||||
if text in ("False", "0"):
|
||||
return False
|
||||
return text
|
||||
|
||||
def checkboxTextboxToggle(checkbox, textboxes):
|
||||
# Really bad practice, but checkbox == self
|
||||
for textbox in textboxes:
|
||||
textbox.set_sensitive(checkbox.get_active())
|
||||
299
wicd/monitor.py
Executable file
299
wicd/monitor.py
Executable file
@@ -0,0 +1,299 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" monitor -- connection monitoring process
|
||||
|
||||
This process is spawned as a child of the daemon, and is responsible
|
||||
for monitoring connection status and initiating autoreconnection
|
||||
when appropriate.
|
||||
|
||||
"""
|
||||
#
|
||||
# Copyright (C) 2007 - 2008 Adam Blackburn
|
||||
# Copyright (C) 2007 - 2008 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import dbus
|
||||
import gobject
|
||||
import time
|
||||
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
|
||||
import dbus.glib
|
||||
else:
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
import wicd.wpath as wpath
|
||||
import wicd.misc as misc
|
||||
|
||||
misc.RenameProcess("wicd-monitor")
|
||||
|
||||
if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
proxy_obj = dbus.SystemBus().get_object('org.wicd.daemon', '/org/wicd/daemon')
|
||||
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
|
||||
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
|
||||
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
|
||||
|
||||
class ConnectionStatus(object):
|
||||
""" Class for monitoring the computer's connection status. """
|
||||
def __init__(self):
|
||||
""" Initialize variables needed for the connection status methods. """
|
||||
self.last_strength = -2
|
||||
self.displayed_strength = -1
|
||||
self.still_wired = False
|
||||
self.network = ''
|
||||
self.tried_reconnect = False
|
||||
self.connection_lost_counter = 0
|
||||
self.last_state = misc.NOT_CONNECTED
|
||||
self.reconnecting = False
|
||||
self.reconnect_tries = 0
|
||||
self.last_reconnect_time = time.time()
|
||||
self.signal_changed = False
|
||||
|
||||
# This determines if we use ioctl or external programs
|
||||
self.fast = True
|
||||
self.iwconfig = ""
|
||||
|
||||
def check_for_wired_connection(self, wired_ip):
|
||||
""" Checks for an active wired connection.
|
||||
|
||||
Checks for and updates the tray icon for an active wired connection
|
||||
Returns True if wired connection is active, false if inactive.
|
||||
|
||||
"""
|
||||
|
||||
if wired_ip and wired.CheckPluggedIn(self.fast):
|
||||
# Only change the interface if it's not already set for wired
|
||||
if not self.still_wired:
|
||||
daemon.SetCurrentInterface(daemon.GetWiredInterface())
|
||||
self.still_wired = True
|
||||
return True
|
||||
# Wired connection isn't active
|
||||
self.still_wired = False
|
||||
return False
|
||||
|
||||
def check_for_wireless_connection(self, wireless_ip):
|
||||
""" Checks for an active wireless connection.
|
||||
|
||||
Checks for and updates the tray icon for an active
|
||||
wireless connection. Returns True if wireless connection
|
||||
is active, and False otherwise.
|
||||
|
||||
"""
|
||||
|
||||
# Make sure we have an IP before we do anything else.
|
||||
if wireless_ip is None:
|
||||
return False
|
||||
|
||||
if self.fast:
|
||||
self.iwconfig = ''
|
||||
else:
|
||||
self.iwconfig = wireless.GetIwconfig()
|
||||
# Reset this, just in case.
|
||||
self.tried_reconnect = False
|
||||
|
||||
# Try getting signal strength, and default to 0
|
||||
# if something goes wrong.
|
||||
try:
|
||||
if daemon.GetSignalDisplayType() == 0:
|
||||
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig,
|
||||
self.fast))
|
||||
else:
|
||||
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig,
|
||||
self.fast))
|
||||
except:
|
||||
wifi_signal = 0
|
||||
|
||||
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:
|
||||
self.connection_lost_counter = 0
|
||||
return False
|
||||
else: # If we have a signal, reset the counter
|
||||
self.connection_lost_counter = 0
|
||||
|
||||
# Only update if the signal strength has changed because doing I/O
|
||||
# calls is expensive, and the icon flickers.
|
||||
if (wifi_signal != self.last_strength or
|
||||
self.network != wireless.GetCurrentNetwork(self.iwconfig,
|
||||
self.fast)):
|
||||
self.last_strength = wifi_signal
|
||||
self.signal_changed = True
|
||||
daemon.SetCurrentInterface(daemon.GetWirelessInterface())
|
||||
|
||||
return True
|
||||
|
||||
def update_connection_status(self):
|
||||
""" Updates the tray icon and current connection status.
|
||||
|
||||
Determines the current connection state and sends a dbus signal
|
||||
announcing when the status changes. Also starts the automatic
|
||||
reconnection process if necessary.
|
||||
|
||||
"""
|
||||
wired_ip = None
|
||||
wifi_ip = None
|
||||
|
||||
try:
|
||||
if daemon.GetSuspend():
|
||||
print "Suspended."
|
||||
state = misc.SUSPENDED
|
||||
self.update_state(state)
|
||||
return True
|
||||
|
||||
# Determine what our current state is.
|
||||
# Check for wired.
|
||||
wired_ip = wired.GetWiredIP(self.fast)
|
||||
wired_found = self.check_for_wired_connection(wired_ip)
|
||||
if wired_found:
|
||||
self.update_state(misc.WIRED, wired_ip=wired_ip)
|
||||
return True
|
||||
|
||||
# Check for wireless
|
||||
wifi_ip = wireless.GetWirelessIP(self.fast)
|
||||
#self.iwconfig = wireless.GetIwconfig()
|
||||
self.signal_changed = False
|
||||
wireless_found = self.check_for_wireless_connection(wifi_ip)
|
||||
if wireless_found:
|
||||
self.update_state(misc.WIRELESS, wifi_ip=wifi_ip)
|
||||
return True
|
||||
|
||||
# Are we currently connecting?
|
||||
if daemon.CheckIfConnecting():
|
||||
state = misc.CONNECTING
|
||||
else: # No connection at all.
|
||||
state = misc.NOT_CONNECTED
|
||||
if self.last_state == misc.WIRELESS:
|
||||
from_wireless = True
|
||||
else:
|
||||
from_wireless = False
|
||||
self.auto_reconnect(from_wireless)
|
||||
self.update_state(state)
|
||||
except dbus.exceptions.DBusException, e:
|
||||
print 'Ignoring DBus Error: ' + str(e)
|
||||
finally:
|
||||
return True
|
||||
|
||||
def update_state(self, state, wired_ip=None, wifi_ip=None):
|
||||
""" Set the current connection state. """
|
||||
# Set our connection state/info.
|
||||
iwconfig = self.iwconfig
|
||||
fast = self.fast
|
||||
if state == misc.NOT_CONNECTED:
|
||||
info = [""]
|
||||
elif state == misc.SUSPENDED:
|
||||
info = [""]
|
||||
elif state == misc.CONNECTING:
|
||||
if wired.CheckIfWiredConnecting():
|
||||
info = ["wired"]
|
||||
else:
|
||||
info = ["wireless", wireless.GetCurrentNetwork(iwconfig, fast)]
|
||||
elif state == misc.WIRELESS:
|
||||
self.reconnect_tries = 0
|
||||
info = [wifi_ip, wireless.GetCurrentNetwork(iwconfig, fast),
|
||||
str(wireless.GetPrintableSignalStrength(iwconfig, fast)),
|
||||
str(wireless.GetCurrentNetworkID(iwconfig, fast))]
|
||||
elif state == misc.WIRED:
|
||||
self.reconnect_tries = 0
|
||||
info = [wired_ip]
|
||||
else:
|
||||
print 'ERROR: Invalid state!'
|
||||
return True
|
||||
daemon.SetConnectionStatus(state, info)
|
||||
|
||||
# Send a D-Bus signal announcing status has changed if necessary.
|
||||
if state != self.last_state or \
|
||||
(state == misc.WIRELESS and self.signal_changed):
|
||||
daemon.EmitStatusChanged(state, info)
|
||||
self.last_state = state
|
||||
return True
|
||||
|
||||
def auto_reconnect(self, from_wireless=None):
|
||||
""" Automatically reconnects to a network if needed.
|
||||
|
||||
If automatic reconnection is turned on, this method will
|
||||
attempt to first reconnect to the last used wireless network, and
|
||||
should that fail will simply run AutoConnect()
|
||||
|
||||
"""
|
||||
if self.reconnecting:
|
||||
return
|
||||
|
||||
# Some checks to keep reconnect retries from going crazy.
|
||||
if self.reconnect_tries > 2 and \
|
||||
time.time() - self.last_reconnect_time < 30:
|
||||
return
|
||||
|
||||
self.reconnecting = True
|
||||
daemon.SetCurrentInterface('')
|
||||
|
||||
if daemon.ShouldAutoReconnect():
|
||||
print 'Starting automatic reconnect process'
|
||||
self.last_reconnect_time = time.time()
|
||||
self.reconnect_tries += 1
|
||||
|
||||
# If we just lost a wireless connection, try to connect to that
|
||||
# network again. Otherwise just call Autoconnect.
|
||||
cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig, self.fast)
|
||||
if from_wireless and cur_net_id > -1:
|
||||
print 'Trying to reconnect to last used wireless ' + \
|
||||
'network'
|
||||
wireless.ConnectWireless(cur_net_id)
|
||||
else:
|
||||
daemon.AutoConnect(True, reply_handler=reply_handle,
|
||||
error_handler=err_handle)
|
||||
self.reconnecting = False
|
||||
|
||||
def rescan_networks(self):
|
||||
""" Calls a wireless scan. """
|
||||
try:
|
||||
if daemon.GetSuspend() or daemon.CheckIfConnecting():
|
||||
return True
|
||||
wireless.Scan()
|
||||
except dbus.exceptions.DBusException, e:
|
||||
print 'dbus exception while attempting rescan: %s' % str(e)
|
||||
finally:
|
||||
return True
|
||||
|
||||
def reply_handle():
|
||||
""" Just a dummy function needed for asynchronous dbus calls. """
|
||||
pass
|
||||
|
||||
def err_handle(error):
|
||||
""" Just a dummy function needed for asynchronous dbus calls. """
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
""" Starts the connection monitor.
|
||||
|
||||
Starts a ConnectionStatus instance, sets the status to update
|
||||
every two seconds, and sets a wireless scan to be called every
|
||||
two minutes.
|
||||
|
||||
"""
|
||||
monitor = ConnectionStatus()
|
||||
gobject.timeout_add(2000, monitor.update_connection_status)
|
||||
#gobject.timeout_add(120000, monitor.rescan_networks)
|
||||
|
||||
mainloop = gobject.MainLoop()
|
||||
mainloop.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
927
wicd/netentry.py
Normal file
927
wicd/netentry.py
Normal file
@@ -0,0 +1,927 @@
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import gtk
|
||||
|
||||
import wicd.misc as misc
|
||||
from wicd.misc import noneToString, stringToNone, noneToBlankString, stringToBoolean
|
||||
import wicd.wpath as wpath
|
||||
|
||||
language = misc.get_language_list_gui()
|
||||
|
||||
# These get set when a NetworkEntry is instantiated.
|
||||
daemon, wireless, wired, vpn_session, config = [None for x in range(0, 5)]
|
||||
|
||||
def error(parent, message):
|
||||
""" Shows an error dialog """
|
||||
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
|
||||
gtk.BUTTONS_OK)
|
||||
dialog.set_markup(message)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
class SmallLabel(gtk.Label):
|
||||
def __init__(self, text=''):
|
||||
gtk.Label.__init__(self, text)
|
||||
self.set_size_request(50, -1)
|
||||
|
||||
class LabelEntry(gtk.HBox):
|
||||
""" A label on the left with a textbox on the right. """
|
||||
def __init__(self, text):
|
||||
gtk.HBox.__init__(self)
|
||||
self.entry = gtk.Entry()
|
||||
self.entry.set_size_request(200, -1)
|
||||
self.label = SmallLabel()
|
||||
self.label.set_text(text)
|
||||
self.label.set_size_request(170, -1)
|
||||
self.pack_start(self.label, fill=False, expand=False)
|
||||
self.pack_start(self.entry, fill=False, expand=False)
|
||||
self.label.show()
|
||||
self.entry.show()
|
||||
self.entry.connect('focus-out-event', self.hide_characters)
|
||||
self.entry.connect('focus-in-event', self.show_characters)
|
||||
self.auto_hide_text = False
|
||||
self.show()
|
||||
|
||||
def set_text(self, text):
|
||||
# For compatibility...
|
||||
self.entry.set_text(text)
|
||||
|
||||
def get_text(self):
|
||||
return self.entry.get_text()
|
||||
|
||||
def set_auto_hidden(self, value):
|
||||
self.entry.set_visibility(False)
|
||||
self.auto_hide_text = value
|
||||
|
||||
def show_characters(self, widget=None, event=None):
|
||||
# When the box has focus, show the characters
|
||||
if self.auto_hide_text and widget:
|
||||
self.entry.set_visibility(True)
|
||||
|
||||
def set_sensitive(self, value):
|
||||
self.entry.set_sensitive(value)
|
||||
self.label.set_sensitive(value)
|
||||
|
||||
def hide_characters(self, widget=None, event=None):
|
||||
# When the box looses focus, hide them
|
||||
if self.auto_hide_text and widget:
|
||||
self.entry.set_visibility(False)
|
||||
|
||||
|
||||
class GreyLabel(gtk.Label):
|
||||
""" Creates a grey gtk.Label. """
|
||||
def __init__(self):
|
||||
gtk.Label.__init__(self)
|
||||
|
||||
def set_label(self, text):
|
||||
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
|
||||
self.set_alignment(0, 0)
|
||||
|
||||
|
||||
class AdvancedSettingsDialog(gtk.Dialog):
|
||||
def __init__(self):
|
||||
""" 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['advanced_settings'],
|
||||
flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CANCEL,
|
||||
gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK,
|
||||
gtk.RESPONSE_ACCEPT))
|
||||
# Set up the Advanced Settings Dialog.
|
||||
self.txt_ip = LabelEntry(language['ip'])
|
||||
self.txt_ip.entry.connect('focus-out-event', self.set_defaults)
|
||||
self.txt_netmask = LabelEntry(language['netmask'])
|
||||
self.txt_gateway = LabelEntry(language['gateway'])
|
||||
self.txt_dns_1 = LabelEntry(language['dns'] + ' ' + language['1'])
|
||||
self.txt_dns_2 = LabelEntry(language['dns'] + ' ' + language['2'])
|
||||
self.txt_dns_3 = LabelEntry(language['dns'] + ' ' + language['3'])
|
||||
self.chkbox_static_ip = gtk.CheckButton(language['use_static_ip'])
|
||||
self.chkbox_static_dns = gtk.CheckButton(language['use_static_dns'])
|
||||
self.chkbox_global_dns = gtk.CheckButton(language['use_global_dns'])
|
||||
self.hbox_dns = gtk.HBox(False, 0)
|
||||
self.hbox_dns.pack_start(self.chkbox_static_dns)
|
||||
self.hbox_dns.pack_start(self.chkbox_global_dns)
|
||||
|
||||
self.vbox.pack_start(self.chkbox_static_ip, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_ip, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_netmask, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_gateway, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.hbox_dns, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_dns_1, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_dns_2, fill=False, expand=False)
|
||||
self.vbox.pack_start(self.txt_dns_3, fill=False, expand=False)
|
||||
|
||||
# Connect the events to the actions
|
||||
self.chkbox_static_ip.connect("toggled", self.toggle_ip_checkbox)
|
||||
self.chkbox_static_dns.connect("toggled", self.toggle_dns_checkbox)
|
||||
self.chkbox_global_dns.connect("toggled", self.toggle_global_dns_checkbox)
|
||||
|
||||
# Start with all disabled, then they will be enabled later.
|
||||
self.chkbox_static_ip.set_active(False)
|
||||
self.chkbox_static_dns.set_active(False)
|
||||
|
||||
def set_defaults(self, widget=None, event=None):
|
||||
""" Put some default values into entries to help the user out. """
|
||||
ipAddress = self.txt_ip.get_text() # For easy typing :)
|
||||
netmask = self.txt_netmask
|
||||
gateway = self.txt_gateway
|
||||
ip_parts = misc.IsValidIP(ipAddress)
|
||||
if ip_parts:
|
||||
if stringToNone(gateway.get_text()) is None: # Make sure the gateway box is blank
|
||||
# Fill it in with a .1 at the end
|
||||
gateway.set_text('.'.join(ip_parts[0:3]) + '.1')
|
||||
|
||||
if stringToNone(netmask.get_text()) is None: # Make sure the netmask is blank
|
||||
netmask.set_text('255.255.255.0') # Fill in the most common one
|
||||
elif ipAddress != "":
|
||||
error(None, "Invalid IP Address Entered.")
|
||||
|
||||
def reset_static_checkboxes(self):
|
||||
# Enable the right stuff
|
||||
if stringToNone(self.txt_ip.get_text()):
|
||||
self.chkbox_static_ip.set_active(True)
|
||||
self.chkbox_static_dns.set_active(True)
|
||||
self.chkbox_static_dns.set_sensitive(False)
|
||||
else:
|
||||
self.chkbox_static_ip.set_active(False)
|
||||
self.chkbox_static_dns.set_active(False)
|
||||
self.chkbox_static_dns.set_sensitive(True)
|
||||
|
||||
if stringToNone(self.txt_dns_1.get_text()):
|
||||
self.chkbox_static_dns.set_active(True)
|
||||
else:
|
||||
self.chkbox_static_dns.set_active(False)
|
||||
|
||||
# This will properly disable unused boxes.
|
||||
self.toggle_ip_checkbox()
|
||||
self.toggle_dns_checkbox()
|
||||
self.toggle_global_dns_checkbox()
|
||||
|
||||
def toggle_ip_checkbox(self, widget=None):
|
||||
"""Toggle entries/checkboxes based on the static IP checkbox. """
|
||||
# Should disable the static IP text boxes, and also enable the DNS
|
||||
# checkbox when disabled and disable when enabled.
|
||||
if self.chkbox_static_ip.get_active():
|
||||
self.chkbox_static_dns.set_active(True)
|
||||
self.chkbox_static_dns.set_sensitive(False)
|
||||
else:
|
||||
self.chkbox_static_dns.set_sensitive(True)
|
||||
#self.chkbox_static_dns.set_active(False)
|
||||
|
||||
self.txt_ip.set_sensitive(self.chkbox_static_ip.get_active())
|
||||
self.txt_netmask.set_sensitive(self.chkbox_static_ip.get_active())
|
||||
self.txt_gateway.set_sensitive(self.chkbox_static_ip.get_active())
|
||||
|
||||
def toggle_dns_checkbox(self, widget=None):
|
||||
""" Toggle entries and checkboxes based on the static dns checkbox. """
|
||||
# Should disable the static DNS boxes
|
||||
if self.chkbox_static_ip.get_active():
|
||||
self.chkbox_static_dns.set_active(self.chkbox_static_ip.
|
||||
get_active())
|
||||
self.chkbox_static_dns.set_sensitive(False)
|
||||
|
||||
self.chkbox_global_dns.set_sensitive(self.chkbox_static_dns.
|
||||
get_active())
|
||||
if self.chkbox_static_dns.get_active():
|
||||
# If global dns is on, don't use local dns
|
||||
self.txt_dns_1.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
self.txt_dns_2.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
self.txt_dns_3.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
else:
|
||||
self.txt_dns_1.set_sensitive(False)
|
||||
self.txt_dns_2.set_sensitive(False)
|
||||
self.txt_dns_3.set_sensitive(False)
|
||||
self.chkbox_global_dns.set_active(False)
|
||||
|
||||
def toggle_global_dns_checkbox(self, widget=None):
|
||||
""" Set the DNS entries' sensitivity based on the Global checkbox. """
|
||||
if daemon.GetUseGlobalDNS() and self.chkbox_static_dns.get_active():
|
||||
self.txt_dns_1.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
self.txt_dns_2.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
self.txt_dns_3.set_sensitive(not self.chkbox_global_dns.get_active())
|
||||
|
||||
def destroy_called(self):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
for obj in vars(self):
|
||||
if hasattr(obj, "destroy"):
|
||||
obj.destroy()
|
||||
if hasattr(obj, "__del__"):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(AdvancedSettingsDialog, self).destroy()
|
||||
self.destroy()
|
||||
del self
|
||||
|
||||
|
||||
class WiredSettingsDialog(AdvancedSettingsDialog):
|
||||
def __init__(self, name):
|
||||
""" Build the wired settings dialog. """
|
||||
AdvancedSettingsDialog.__init__(self)
|
||||
self.des = self.connect("destroy", self.destroy_called)
|
||||
self.prof_name = name
|
||||
|
||||
def set_net_prop(self, option, value):
|
||||
""" Sets the given option to the given value for this network. """
|
||||
wired.SetWiredProperty(option, value)
|
||||
|
||||
def set_values(self):
|
||||
""" Fill in the Gtk.Entry objects with the correct values. """
|
||||
self.txt_ip.set_text(self.format_entry("ip"))
|
||||
self.txt_netmask.set_text(self.format_entry("netmask"))
|
||||
self.txt_gateway.set_text(self.format_entry("gateway"))
|
||||
|
||||
self.txt_dns_1.set_text(self.format_entry("dns1"))
|
||||
self.txt_dns_2.set_text(self.format_entry("dns2"))
|
||||
self.txt_dns_3.set_text(self.format_entry("dns3"))
|
||||
self.reset_static_checkboxes()
|
||||
|
||||
def format_entry(self, label):
|
||||
""" Helper method to fetch and format wired properties. """
|
||||
return noneToBlankString(wired.GetWiredProperty(label))
|
||||
|
||||
def destroy_called(self):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
self.disconnect(self.des)
|
||||
for obj in vars(self):
|
||||
if hasattr(obj, "destroy"):
|
||||
obj.destroy()
|
||||
if hasattr(obj, "__del__"):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(WiredSettingsDialog, self).destroy_called()
|
||||
self.destroy()
|
||||
del self
|
||||
|
||||
|
||||
class WirelessSettingsDialog(AdvancedSettingsDialog):
|
||||
def __init__(self, networkID):
|
||||
""" Build the wireless settings dialog. """
|
||||
AdvancedSettingsDialog.__init__(self)
|
||||
# Set up encryption stuff
|
||||
self.networkID = networkID
|
||||
self.combo_encryption = gtk.combo_box_new_text()
|
||||
self.chkbox_encryption = gtk.CheckButton(language['use_encryption'])
|
||||
self.chkbox_global_settings = gtk.CheckButton(language['global_settings'])
|
||||
# Make the vbox to hold the encryption stuff.
|
||||
self.vbox_encrypt_info = gtk.VBox(False, 0)
|
||||
self.toggle_encryption()
|
||||
self.chkbox_encryption.set_active(False)
|
||||
self.combo_encryption.set_sensitive(False)
|
||||
self.encrypt_types = misc.LoadEncryptionMethods()
|
||||
|
||||
# Build the encryption menu
|
||||
activeID = -1 # Set the menu to this item when we are done
|
||||
for x, enc_type in enumerate(self.encrypt_types):
|
||||
self.combo_encryption.append_text(enc_type[0])
|
||||
if enc_type[1] == wireless.GetWirelessProperty(networkID,
|
||||
"enctype"):
|
||||
activeID = x
|
||||
self.combo_encryption.set_active(activeID)
|
||||
if activeID != -1:
|
||||
self.chkbox_encryption.set_active(True)
|
||||
self.combo_encryption.set_sensitive(True)
|
||||
self.vbox_encrypt_info.set_sensitive(True)
|
||||
else:
|
||||
self.combo_encryption.set_active(0)
|
||||
self.change_encrypt_method()
|
||||
|
||||
self.vbox.pack_start(self.chkbox_global_settings, False, False)
|
||||
self.vbox.pack_start(self.chkbox_encryption, False, False)
|
||||
self.vbox.pack_start(self.combo_encryption, False, False)
|
||||
self.vbox.pack_start(self.vbox_encrypt_info, False, False)
|
||||
|
||||
# Connect signals.
|
||||
self.chkbox_encryption.connect("toggled", self.toggle_encryption)
|
||||
self.combo_encryption.connect("changed", self.change_encrypt_method)
|
||||
self.des = self.connect("destroy", self.destroy_called)
|
||||
|
||||
def destroy_called(self):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
self.disconnect(self.des)
|
||||
for obj in vars(self):
|
||||
if hasattr(obj, "destroy"):
|
||||
obj.destroy()
|
||||
if hasattr(obj, "__del__"):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(WirelessSettingsDialog, self).destroy_called()
|
||||
self.destroy()
|
||||
del self
|
||||
|
||||
def set_net_prop(self, option, value):
|
||||
""" Sets the given option to the given value for this network. """
|
||||
wireless.SetWirelessProperty(self.networkID, option, value)
|
||||
|
||||
def set_values(self):
|
||||
""" Set the various network settings to the right values. """
|
||||
networkID = self.networkID
|
||||
self.txt_ip.set_text(self.format_entry(networkID,"ip"))
|
||||
self.txt_netmask.set_text(self.format_entry(networkID,"netmask"))
|
||||
self.txt_gateway.set_text(self.format_entry(networkID,"gateway"))
|
||||
|
||||
self.chkbox_global_dns.set_active(bool(wireless.GetWirelessProperty(networkID,
|
||||
'use_global_dns')))
|
||||
|
||||
self.txt_dns_1.set_text(self.format_entry(networkID, "dns1"))
|
||||
self.txt_dns_2.set_text(self.format_entry(networkID, "dns2"))
|
||||
self.txt_dns_3.set_text(self.format_entry(networkID, "dns3"))
|
||||
|
||||
self.reset_static_checkboxes()
|
||||
self.chkbox_encryption.set_active(bool(wireless.GetWirelessProperty(networkID,
|
||||
'encryption')))
|
||||
self.chkbox_global_settings.set_active(bool(wireless.GetWirelessProperty(networkID,
|
||||
'use_settings_globally')))
|
||||
|
||||
|
||||
activeID = -1 # Set the menu to this item when we are done
|
||||
user_enctype = wireless.GetWirelessProperty(networkID, "enctype")
|
||||
for x, enc_type in enumerate(self.encrypt_types):
|
||||
if enc_type[1] == user_enctype:
|
||||
activeID = x
|
||||
|
||||
self.combo_encryption.set_active(activeID)
|
||||
if activeID != -1:
|
||||
self.chkbox_encryption.set_active(True)
|
||||
self.combo_encryption.set_sensitive(True)
|
||||
self.vbox_encrypt_info.set_sensitive(True)
|
||||
else:
|
||||
self.combo_encryption.set_active(0)
|
||||
self.change_encrypt_method()
|
||||
|
||||
def format_entry(self, networkid, label):
|
||||
""" Helper method for fetching/formatting wireless properties. """
|
||||
return noneToBlankString(wireless.GetWirelessProperty(networkid, label))
|
||||
|
||||
def toggle_encryption(self, widget=None):
|
||||
""" Toggle the encryption combobox based on the encryption checkbox. """
|
||||
active = self.chkbox_encryption.get_active()
|
||||
self.vbox_encrypt_info.set_sensitive(active)
|
||||
self.combo_encryption.set_sensitive(active)
|
||||
|
||||
def change_encrypt_method(self, widget=None):
|
||||
""" Load all the entries for a given encryption method. """
|
||||
for z in self.vbox_encrypt_info:
|
||||
z.destroy() # Remove stuff in there already
|
||||
ID = self.combo_encryption.get_active()
|
||||
methods = misc.LoadEncryptionMethods()
|
||||
self.encryption_info = {}
|
||||
|
||||
# If nothing is selected, select the first entry.
|
||||
if ID == -1:
|
||||
self.combo_encryption.set_active(0)
|
||||
ID = 0
|
||||
|
||||
opts = methods[ID][2]
|
||||
for x in opts:
|
||||
box = None
|
||||
if language.has_key(opts[x][0]):
|
||||
box = LabelEntry(language[opts[x][0].lower().replace(' ','_')])
|
||||
else:
|
||||
box = LabelEntry(opts[x][0].replace('_',' '))
|
||||
box.set_auto_hidden(True)
|
||||
self.vbox_encrypt_info.pack_start(box)
|
||||
#add the data to any array, so that the information
|
||||
#can be easily accessed by giving the name of the wanted
|
||||
#data
|
||||
self.encryption_info[opts[x][1]] = box.entry
|
||||
|
||||
box.entry.set_text(noneToBlankString(
|
||||
wireless.GetWirelessProperty(self.networkID, opts[x][1])))
|
||||
self.vbox_encrypt_info.show_all()
|
||||
|
||||
|
||||
class NetworkEntry(gtk.HBox):
|
||||
def __init__(self, dbus_ifaces):
|
||||
""" Base network entry class.
|
||||
|
||||
Provides gtk objects used by both the WiredNetworkEntry and
|
||||
WirelessNetworkEntry classes.
|
||||
|
||||
"""
|
||||
global daemon, wired, wireless, config
|
||||
daemon = dbus_ifaces["daemon"]
|
||||
wired = dbus_ifaces["wired"]
|
||||
wireless = dbus_ifaces["wireless"]
|
||||
config = dbus_ifaces["config"]
|
||||
gtk.HBox.__init__(self, False, 2)
|
||||
self.expander = gtk.Expander()
|
||||
self.image = gtk.Image()
|
||||
self.pack_start(self.image, False, False)
|
||||
|
||||
# Set up the Connect button
|
||||
self.connect_button = gtk.Button(stock=gtk.STOCK_CONNECT)
|
||||
self.connect_hbox = gtk.HBox(False, 2)
|
||||
self.connect_hbox.pack_start(self.connect_button, False, False)
|
||||
self.connect_hbox.show()
|
||||
|
||||
# Set up the Disconnect button
|
||||
self.disconnect_button = gtk.Button(stock=gtk.STOCK_DISCONNECT)
|
||||
self.connect_hbox.pack_start(self.disconnect_button, False, False)
|
||||
|
||||
# Set up the VBox that goes in the gtk.Expander
|
||||
self.expander_vbox = gtk.VBox(False, 1)
|
||||
self.expander_vbox.show()
|
||||
self.expander_vbox.pack_start(self.expander)
|
||||
self.expander_vbox.pack_start(self.connect_hbox, False, False)
|
||||
self.pack_end(self.expander_vbox)
|
||||
|
||||
# Set up the advanced settings button
|
||||
self.advanced_button = gtk.Button()
|
||||
self.advanced_image = gtk.Image()
|
||||
self.advanced_image.set_from_stock(gtk.STOCK_EDIT, 4)
|
||||
self.advanced_image.set_padding(4, 0)
|
||||
self.advanced_button.set_alignment(.5, .5)
|
||||
self.advanced_button.set_label(language['advanced_settings'])
|
||||
self.advanced_button.set_image(self.advanced_image)
|
||||
|
||||
# Set up the script settings button
|
||||
self.script_button = gtk.Button()
|
||||
self.script_image = gtk.Image()
|
||||
self.script_image.set_from_stock(gtk.STOCK_EXECUTE, 4)
|
||||
self.script_image.set_padding(4, 0)
|
||||
self.script_button.set_alignment(.5, .5)
|
||||
self.script_button.set_image(self.script_image)
|
||||
self.script_button.set_label(language['scripts'])
|
||||
|
||||
self.settings_hbox = gtk.HBox(False, 3)
|
||||
self.settings_hbox.set_border_width(5)
|
||||
self.settings_hbox.pack_start(self.script_button, False, False)
|
||||
self.settings_hbox.pack_start(self.advanced_button, False, False)
|
||||
|
||||
self.vbox_top = gtk.VBox(False, 0)
|
||||
self.vbox_top.pack_end(self.settings_hbox, False, False)
|
||||
|
||||
aligner = gtk.Alignment(xscale=1.0)
|
||||
aligner.add(self.vbox_top)
|
||||
aligner.set_padding(0, 0, 15, 0)
|
||||
self.expander.add(aligner)
|
||||
|
||||
def destroy_called(self, *args):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
for obj in vars(self):
|
||||
try: obj.destroy()
|
||||
except: pass
|
||||
if hasattr(obj, '__del__'):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
for obj in vars(super(NetworkEntry, self)):
|
||||
try: obj.destroy()
|
||||
except: pass
|
||||
if hasattr(obj, '__del__'):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(NetworkEntry, self).destroy()
|
||||
self.destroy()
|
||||
|
||||
|
||||
class WiredNetworkEntry(NetworkEntry):
|
||||
def __init__(self, dbus_ifaces):
|
||||
""" Load the wired network entry. """
|
||||
NetworkEntry.__init__(self, dbus_ifaces)
|
||||
# Center the picture and pad it a bit
|
||||
self.image.set_alignment(.5, 0)
|
||||
self.image.set_size_request(60, -1)
|
||||
self.image.set_from_icon_name("network-wired", 6)
|
||||
self.image.show()
|
||||
self.expander.show()
|
||||
self.connect_button.show()
|
||||
|
||||
self.expander.set_label(language['wired_network'])
|
||||
#self.reset_static_checkboxes()
|
||||
self.is_full_gui = True
|
||||
|
||||
self.button_add = gtk.Button(stock=gtk.STOCK_ADD)
|
||||
self.button_delete = gtk.Button(stock=gtk.STOCK_DELETE)
|
||||
self.profile_help = gtk.Label(language['wired_network_instructions'])
|
||||
self.chkbox_default_profile = gtk.CheckButton(language['default_wired'])
|
||||
|
||||
# Build the profile list.
|
||||
self.combo_profile_names = gtk.combo_box_entry_new_text()
|
||||
self.profile_list = config.GetWiredProfileList()
|
||||
if self.profile_list:
|
||||
for x in self.profile_list:
|
||||
self.combo_profile_names.append_text(x)
|
||||
|
||||
# Format the profile help label.
|
||||
self.profile_help.set_justify(gtk.JUSTIFY_LEFT)
|
||||
self.profile_help.set_line_wrap(True)
|
||||
|
||||
# Pack the various VBox objects.
|
||||
self.hbox_temp = gtk.HBox(False, 0)
|
||||
self.hbox_def = gtk.HBox(False, 0)
|
||||
self.vbox_top.pack_start(self.profile_help, True, True)
|
||||
self.vbox_top.pack_start(self.hbox_def)
|
||||
self.vbox_top.pack_start(self.hbox_temp)
|
||||
self.hbox_temp.pack_start(self.combo_profile_names, True, True)
|
||||
self.hbox_temp.pack_start(self.button_add, False, False)
|
||||
self.hbox_temp.pack_start(self.button_delete, False, False)
|
||||
self.hbox_def.pack_start(self.chkbox_default_profile, False, False)
|
||||
|
||||
# Connect events
|
||||
self.button_add.connect("clicked", self.add_profile)
|
||||
self.button_delete.connect("clicked", self.remove_profile)
|
||||
self.chkbox_default_profile.connect("toggled",
|
||||
self.toggle_default_profile)
|
||||
self.combo_profile_names.connect("changed", self.change_profile)
|
||||
self.script_button.connect("button-press-event", self.edit_scripts)
|
||||
|
||||
# Toggle the default profile checkbox to the correct state.
|
||||
if stringToBoolean(wired.GetWiredProperty("default")):
|
||||
self.chkbox_default_profile.set_active(True)
|
||||
else:
|
||||
self.chkbox_default_profile.set_active(False)
|
||||
|
||||
# Show everything, but hide the profile help label.
|
||||
self.show_all()
|
||||
self.profile_help.hide()
|
||||
self.advanced_dialog = WiredSettingsDialog(self.combo_profile_names.get_active_text())
|
||||
|
||||
# Display the default profile if it exists.
|
||||
if self.profile_list is not None:
|
||||
prof = config.GetDefaultWiredNetwork()
|
||||
if prof != None: # Make sure the default profile gets displayed.
|
||||
i = 0
|
||||
while self.combo_profile_names.get_active_text() != prof:
|
||||
self.combo_profile_names.set_active(i)
|
||||
i += 1
|
||||
else:
|
||||
self.combo_profile_names.set_active(0)
|
||||
print "wired profiles found"
|
||||
self.expander.set_expanded(False)
|
||||
else:
|
||||
print "no wired profiles found"
|
||||
if not wired.GetAlwaysShowWiredInterface():
|
||||
self.expander.set_expanded(True)
|
||||
self.profile_help.show()
|
||||
self.check_enable()
|
||||
self.wireddis = self.connect("destroy", self.destroy_called)
|
||||
|
||||
def destroy_called(self, *args):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
self.disconnect(self.wireddis)
|
||||
self.advanced_dialog.destroy_called()
|
||||
del self.advanced_dialog
|
||||
for obj in vars(self):
|
||||
if hasattr(obj, "destroy"):
|
||||
obj.destroy()
|
||||
if hasattr(obj, '__del__'):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(WiredNetworkEntry, self).destroy_called()
|
||||
self.destroy()
|
||||
del self
|
||||
|
||||
def edit_scripts(self, widget=None, event=None):
|
||||
""" Launch the script editting dialog. """
|
||||
profile = self.combo_profile_names.get_active_text()
|
||||
try:
|
||||
sudo_prog = misc.choose_sudo_prog()
|
||||
msg = "You must enter your password to configure scripts"
|
||||
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
|
||||
msg_flag = "-m"
|
||||
else:
|
||||
msg_flag = "--caption"
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
|
||||
profile, "wired"])
|
||||
except misc.WicdError:
|
||||
error("Could not find a graphical sudo program." + \
|
||||
" Script editor could not be launched.")
|
||||
|
||||
def check_enable(self):
|
||||
""" Disable objects if the profile list is empty. """
|
||||
profile_list = config.GetWiredProfileList()
|
||||
if profile_list == None:
|
||||
self.button_delete.set_sensitive(False)
|
||||
self.connect_button.set_sensitive(False)
|
||||
self.advanced_button.set_sensitive(False)
|
||||
self.script_button.set_sensitive(False)
|
||||
|
||||
def update_connect_button(self, state, apbssid=None):
|
||||
""" Update the connection/disconnect button for this entry. """
|
||||
if state == misc.WIRED:
|
||||
self.disconnect_button.show()
|
||||
self.connect_button.hide()
|
||||
else:
|
||||
self.disconnect_button.hide()
|
||||
self.connect_button.show()
|
||||
|
||||
def add_profile(self, widget):
|
||||
""" Add a profile to the profile list. """
|
||||
print "adding profile"
|
||||
profile_name = self.combo_profile_names.get_active_text()
|
||||
profile_list = config.GetWiredProfileList()
|
||||
if profile_list:
|
||||
if profile_name in profile_list:
|
||||
return False
|
||||
if profile_name != "":
|
||||
self.profile_help.hide()
|
||||
config.CreateWiredNetworkProfile(profile_name)
|
||||
self.combo_profile_names.prepend_text(profile_name)
|
||||
self.combo_profile_names.set_active(0)
|
||||
self.advanced_dialog.prof_name = profile_name
|
||||
if self.is_full_gui:
|
||||
self.button_delete.set_sensitive(True)
|
||||
self.connect_button.set_sensitive(True)
|
||||
self.advanced_button.set_sensitive(True)
|
||||
self.script_button.set_sensitive(True)
|
||||
|
||||
def remove_profile(self, widget):
|
||||
""" Remove a profile from the profile list. """
|
||||
print "removing profile"
|
||||
profile_name = self.combo_profile_names.get_active_text()
|
||||
config.DeleteWiredNetworkProfile(profile_name)
|
||||
self.combo_profile_names.remove_text(self.combo_profile_names.
|
||||
get_active())
|
||||
self.combo_profile_names.set_active(0)
|
||||
self.advanced_dialog.prof_name = self.combo_profile_names.get_active_text()
|
||||
if not config.GetWiredProfileList():
|
||||
self.profile_help.show()
|
||||
entry = self.combo_profile_names.child
|
||||
entry.set_text("")
|
||||
if self.is_full_gui:
|
||||
self.button_delete.set_sensitive(False)
|
||||
self.advanced_button.set_sensitive(False)
|
||||
self.script_button.set_sensitive(False)
|
||||
self.connect_button.set_sensitive(False)
|
||||
else:
|
||||
self.profile_help.hide()
|
||||
|
||||
def toggle_default_profile(self, widget):
|
||||
""" Change the default profile. """
|
||||
if self.chkbox_default_profile.get_active():
|
||||
# Make sure there is only one default profile at a time
|
||||
config.UnsetWiredDefault()
|
||||
wired.SetWiredProperty("default",
|
||||
self.chkbox_default_profile.get_active())
|
||||
config.SaveWiredNetworkProfile(self.combo_profile_names.get_active_text())
|
||||
|
||||
def change_profile(self, widget):
|
||||
""" Called when a new profile is chosen from the list. """
|
||||
# Make sure the name doesn't change everytime someone types something
|
||||
if self.combo_profile_names.get_active() > -1:
|
||||
if not self.is_full_gui:
|
||||
return
|
||||
|
||||
profile_name = self.combo_profile_names.get_active_text()
|
||||
config.ReadWiredNetworkProfile(profile_name)
|
||||
|
||||
self.advanced_dialog.txt_ip.set_text(self.format_entry("ip"))
|
||||
self.advanced_dialog.txt_netmask.set_text(self.format_entry("netmask"))
|
||||
self.advanced_dialog.txt_gateway.set_text(self.format_entry("gateway"))
|
||||
self.advanced_dialog.txt_dns_1.set_text(self.format_entry("dns1"))
|
||||
self.advanced_dialog.txt_dns_2.set_text(self.format_entry("dns2"))
|
||||
self.advanced_dialog.txt_dns_3.set_text(self.format_entry("dns3"))
|
||||
self.advanced_dialog.prof_name = profile_name
|
||||
|
||||
is_default = wired.GetWiredProperty("default")
|
||||
self.chkbox_default_profile.set_active(stringToBoolean(is_default))
|
||||
|
||||
def format_entry(self, label):
|
||||
""" Help method for fetching/formatting wired properties. """
|
||||
return noneToBlankString(wired.GetWiredProperty(label))
|
||||
|
||||
|
||||
class WirelessNetworkEntry(NetworkEntry):
|
||||
def __init__(self, networkID, dbus_ifaces):
|
||||
""" Build the wireless network entry. """
|
||||
NetworkEntry.__init__(self, dbus_ifaces)
|
||||
|
||||
self.networkID = networkID
|
||||
self.image.set_padding(0, 0)
|
||||
self.image.set_alignment(.5, 0)
|
||||
self.image.set_size_request(60, -1)
|
||||
self.image.set_from_icon_name("network-wired", 6)
|
||||
self.essid = wireless.GetWirelessProperty(networkID, "essid")
|
||||
print "ESSID : " + self.essid
|
||||
# Make the combo box.
|
||||
self.lbl_strength = GreyLabel()
|
||||
self.lbl_encryption = GreyLabel()
|
||||
self.lbl_mac = GreyLabel()
|
||||
self.lbl_channel = GreyLabel()
|
||||
self.lbl_mode = GreyLabel()
|
||||
self.hbox_status = gtk.HBox(False, 5)
|
||||
self.chkbox_autoconnect = gtk.CheckButton(language['automatic_connect'])
|
||||
|
||||
# Set the values of the network info labels.
|
||||
self.set_signal_strength(wireless.GetWirelessProperty(networkID,
|
||||
'quality'),
|
||||
wireless.GetWirelessProperty(networkID,
|
||||
'strength'))
|
||||
self.set_mac_address(wireless.GetWirelessProperty(networkID, 'bssid'))
|
||||
self.set_mode(wireless.GetWirelessProperty(networkID, 'mode'))
|
||||
self.set_channel(wireless.GetWirelessProperty(networkID, 'channel'))
|
||||
self.set_encryption(wireless.GetWirelessProperty(networkID,
|
||||
'encryption'),
|
||||
wireless.GetWirelessProperty(networkID,
|
||||
'encryption_method'))
|
||||
|
||||
# The the expander label.
|
||||
self.expander.set_use_markup(True)
|
||||
|
||||
self.expander.set_label(self._escape(self.essid) + " " +
|
||||
self.lbl_strength.get_label() + " " +
|
||||
self.lbl_encryption.get_label() + " " +
|
||||
self.lbl_mac.get_label())
|
||||
|
||||
# Pack the network status HBox.
|
||||
self.hbox_status.pack_start(self.lbl_strength, True, True)
|
||||
self.hbox_status.pack_start(self.lbl_encryption, True, True)
|
||||
self.hbox_status.pack_start(self.lbl_mac, True, True)
|
||||
self.hbox_status.pack_start(self.lbl_mode, True, True)
|
||||
self.hbox_status.pack_start(self.lbl_channel, True, True)
|
||||
|
||||
# Add the wireless network specific parts to the NetworkEntry
|
||||
# VBox objects.
|
||||
self.vbox_top.pack_start(self.chkbox_autoconnect, False, False)
|
||||
self.vbox_top.pack_start(self.hbox_status, True, True)
|
||||
|
||||
if stringToBoolean(self.format_entry(networkID, "automatic")):
|
||||
self.chkbox_autoconnect.set_active(True)
|
||||
else:
|
||||
self.chkbox_autoconnect.set_active(False)
|
||||
|
||||
# Connect signals.
|
||||
self.chkbox_autoconnect.connect("toggled", self.update_autoconnect)
|
||||
self.script_button.connect("button-press-event", self.edit_scripts)
|
||||
|
||||
# Show everything
|
||||
self.show_all()
|
||||
self.advanced_dialog = WirelessSettingsDialog(networkID)
|
||||
self.wifides = self.connect("destroy", self.destroy_called)
|
||||
|
||||
def _escape(self, val):
|
||||
return val.replace("&", "&").replace("<", "<").\
|
||||
replace(">",">").replace("'", "'").replace('"', """)
|
||||
|
||||
def destroy_called(self, *args):
|
||||
""" Clean up everything.
|
||||
|
||||
This might look excessive, but it was the only way to prevent
|
||||
memory leakage.
|
||||
|
||||
"""
|
||||
self.disconnect(self.wifides)
|
||||
self.advanced_dialog.destroy_called()
|
||||
del self.advanced_dialog
|
||||
for obj in vars(self):
|
||||
if hasattr(obj, "destroy"):
|
||||
obj.destroy()
|
||||
|
||||
if hasattr(obj, '__del__'):
|
||||
obj.__del__()
|
||||
else:
|
||||
del obj
|
||||
super(WirelessNetworkEntry, self).destroy_called()
|
||||
self.destroy()
|
||||
del self
|
||||
|
||||
def set_signal_strength(self, strength, dbm_strength):
|
||||
""" Set the signal strength displayed in the WirelessNetworkEntry. """
|
||||
if strength is not None:
|
||||
strength = int(strength)
|
||||
else:
|
||||
strength = -1
|
||||
if dbm_strength is not None:
|
||||
dbm_strength = int(dbm_strength)
|
||||
else:
|
||||
dbm_strength = -100
|
||||
display_type = daemon.GetSignalDisplayType()
|
||||
if daemon.GetWPADriver() == 'ralink legacy' or display_type == 1:
|
||||
# Use the -xx dBm signal strength to display a signal icon
|
||||
# I'm not sure how accurately the dBm strength is being
|
||||
# "converted" to strength bars, so suggestions from people
|
||||
# for a better way would be welcome.
|
||||
if dbm_strength >= -60:
|
||||
signal_img = 'signal-100.png'
|
||||
elif dbm_strength >= -70:
|
||||
signal_img = 'signal-75.png'
|
||||
elif dbm_strength >= -80:
|
||||
signal_img = 'signal-50.png'
|
||||
else:
|
||||
signal_img = 'signal-25.png'
|
||||
ending = "dBm"
|
||||
disp_strength = str(dbm_strength)
|
||||
else:
|
||||
# Uses normal link quality, should be fine in most cases
|
||||
if strength > 75:
|
||||
signal_img = 'signal-100.png'
|
||||
elif strength > 50:
|
||||
signal_img = 'signal-75.png'
|
||||
elif strength > 25:
|
||||
signal_img = 'signal-50.png'
|
||||
else:
|
||||
signal_img = 'signal-25.png'
|
||||
ending = "%"
|
||||
disp_strength = str(strength)
|
||||
|
||||
self.image.set_from_file(wpath.images + signal_img)
|
||||
self.lbl_strength.set_label(disp_strength + ending)
|
||||
|
||||
def update_connect_button(self, state, apbssid):
|
||||
""" Update the connection/disconnect button for this entry. """
|
||||
if not apbssid:
|
||||
apbssid = wireless.GetApBssid()
|
||||
if state == misc.WIRELESS and \
|
||||
apbssid == wireless.GetWirelessProperty(self.networkID, "bssid"):
|
||||
self.disconnect_button.show()
|
||||
self.connect_button.hide()
|
||||
else:
|
||||
self.disconnect_button.hide()
|
||||
self.connect_button.show()
|
||||
|
||||
def set_mac_address(self, address):
|
||||
""" Set the MAC address for the WirelessNetworkEntry. """
|
||||
self.lbl_mac.set_label(str(address))
|
||||
|
||||
def set_encryption(self, on, ttype):
|
||||
""" Set the encryption value for the WirelessNetworkEntry. """
|
||||
if on and ttype:
|
||||
self.lbl_encryption.set_label(str(ttype))
|
||||
if on and not ttype:
|
||||
self.lbl_encryption.set_label(language['secured'])
|
||||
if not on:
|
||||
self.lbl_encryption.set_label(language['unsecured'])
|
||||
|
||||
def set_channel(self, channel):
|
||||
""" Set the channel value for the WirelessNetworkEntry. """
|
||||
self.lbl_channel.set_label(language['channel'] + ' ' + str(channel))
|
||||
|
||||
def set_mode(self, mode):
|
||||
""" Set the mode value for the WirelessNetworkEntry. """
|
||||
self.lbl_mode.set_label(str(mode))
|
||||
|
||||
def format_entry(self, networkid, label):
|
||||
""" Helper method for fetching/formatting wireless properties. """
|
||||
return noneToBlankString(wireless.GetWirelessProperty(networkid, label))
|
||||
|
||||
def edit_scripts(self, widget=None, event=None):
|
||||
""" Launch the script editting dialog. """
|
||||
try:
|
||||
sudo_prog = misc.choose_sudo_prog()
|
||||
msg = "You must enter your password to configure scripts"
|
||||
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
|
||||
msg_flag = "-m"
|
||||
else:
|
||||
msg_flag = "--caption"
|
||||
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
|
||||
str(self.networkID), "wireless"])
|
||||
except IOError:
|
||||
error("Could not find a graphical sudo program." + \
|
||||
" Script editor could no be launched.")
|
||||
|
||||
def update_autoconnect(self, widget=None):
|
||||
""" Called when the autoconnect checkbox is toggled. """
|
||||
wireless.SetWirelessProperty(self.networkID, "automatic",
|
||||
noneToString(self.chkbox_autoconnect.
|
||||
get_active()))
|
||||
config.SaveWirelessNetworkProperty(self.networkID, "automatic")
|
||||
933
wicd/networking.py
Normal file
933
wicd/networking.py
Normal file
@@ -0,0 +1,933 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" networking - Provides wrappers for common network operations
|
||||
|
||||
This module provides wrappers of the common network tasks as well as
|
||||
threads to perform the actual connecting to networks.
|
||||
|
||||
class Controller() -- Parent class to Wireless and Wired
|
||||
class ConnectThread() -- Parent class to WirelessConnectThread and
|
||||
WiredConnectThread
|
||||
class Wireless() -- Wrapper for various wireless functions
|
||||
class Wired() -- Wrapper for various wired functions
|
||||
class WirelessConnectThread() -- Connection thread for wireless
|
||||
interface
|
||||
class WiredConnectThread() -- Connection thread for wired
|
||||
interface
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 Dan O'Reilly
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#
|
||||
# Much thanks to wieman01 for help and support with various types of encyption.
|
||||
# Also thanks to foxy123, yopnono, and the many others who reported bugs helped
|
||||
# and helped keep this project moving.
|
||||
#
|
||||
|
||||
import re
|
||||
import threading
|
||||
import thread
|
||||
import time
|
||||
|
||||
import wicd.misc as misc
|
||||
import wicd.wnettools as wnettools
|
||||
import wicd.wpath as wpath
|
||||
|
||||
if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
|
||||
class Controller(object):
|
||||
""" Parent class for the different interface types. """
|
||||
def __init__(self):
|
||||
""" Initialise the class. """
|
||||
self.global_dns_1 = None
|
||||
self.global_dns_2 = None
|
||||
self.global_dns_3 = None
|
||||
self._wired_interface = None
|
||||
self._wireless_interface = None
|
||||
self._dhcp_client = None
|
||||
self._flush_tool = None
|
||||
self._debug = None
|
||||
self.connecting_thread = None
|
||||
self.before_script = None
|
||||
self.after_script = None
|
||||
self.disconnect_script = None
|
||||
self.driver = None
|
||||
self.wiface = None
|
||||
self.liface = None
|
||||
|
||||
def set_wireless_iface(self, value):
|
||||
self._wireless_interface = value
|
||||
if self.wiface:
|
||||
self.wiface.SetInterface(value)
|
||||
|
||||
def get_wireless_iface(self):
|
||||
return self._wireless_interface
|
||||
|
||||
def set_wired_iface(self, value):
|
||||
self._wired_interface = value
|
||||
if self.liface:
|
||||
self.liface.SetInterface(value)
|
||||
|
||||
def get_wired_iface(self):
|
||||
return self._wired_interface
|
||||
|
||||
def set_debug(self, value):
|
||||
self._debug = value
|
||||
if self.wiface:
|
||||
self.wiface.SetDebugMode(value)
|
||||
if self.liface:
|
||||
self.liface.SetDebugMode(value)
|
||||
|
||||
def get_debug(self):
|
||||
return self._debug
|
||||
|
||||
def set_dhcp_client(self, value):
|
||||
self._dhcp_client = value
|
||||
if self.wiface:
|
||||
self.wiface.DHCP_CLIENT = value
|
||||
self.wiface.CheckDHCP()
|
||||
if self.liface:
|
||||
self.liface.DHCP_CLIENT = value
|
||||
self.liface.CheckDHCP()
|
||||
|
||||
def get_dhcp_client(self):
|
||||
return self._dhcp_client
|
||||
|
||||
def set_flush_tool(self, value):
|
||||
self._flush_tool = value
|
||||
if self.wiface:
|
||||
self.wiface.flush_tool = value
|
||||
if self.liface:
|
||||
self.liface.flush_tool = value
|
||||
|
||||
def get_flush_tool(self):
|
||||
return self._flush_tool
|
||||
|
||||
wireless_interface = property(get_wireless_iface, set_wireless_iface)
|
||||
wired_interface = property(get_wired_iface, set_wired_iface)
|
||||
debug = property(get_debug, set_debug)
|
||||
flush_tool = property(get_flush_tool, set_flush_tool)
|
||||
dhcp_client = property(get_dhcp_client, set_dhcp_client)
|
||||
|
||||
|
||||
class ConnectThread(threading.Thread):
|
||||
""" A class to perform network connections in a multi-threaded way.
|
||||
|
||||
Useless on it's own, this class provides the generic functions
|
||||
necessary for connecting using a separate thread.
|
||||
|
||||
"""
|
||||
|
||||
is_connecting = None
|
||||
connecting_thread = None
|
||||
should_die = False
|
||||
lock = thread.allocate_lock()
|
||||
|
||||
def __init__(self, network, wireless, wired, before_script, after_script,
|
||||
disconnect_script, gdns1, gdns2, gdns3, wiface, liface, debug):
|
||||
""" Initialise the required object variables and the thread.
|
||||
|
||||
Keyword arguments:
|
||||
network -- the network to connect to
|
||||
wireless -- name of the wireless interface
|
||||
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
|
||||
gdns1 -- global DNS server 1
|
||||
gdns2 -- global DNS server 2
|
||||
gdns3 -- global DNS server 3
|
||||
debug -- debug mode status
|
||||
|
||||
"""
|
||||
threading.Thread.__init__(self)
|
||||
self.network = network
|
||||
self.wireless_interface = wireless
|
||||
self.wired_interface = wired
|
||||
self.is_connecting = False
|
||||
self.is_aborted = False
|
||||
self.abort_msg = None
|
||||
self.before_script = before_script
|
||||
self.after_script = after_script
|
||||
self.disconnect_script = disconnect_script
|
||||
self.should_die = False
|
||||
self.abort_reason = ""
|
||||
|
||||
self.global_dns_1 = gdns1
|
||||
self.global_dns_2 = gdns2
|
||||
self.global_dns_3 = gdns3
|
||||
|
||||
self.wiface = wiface
|
||||
self.liface = liface
|
||||
|
||||
self.connecting_message = None
|
||||
self.debug = debug
|
||||
|
||||
self.SetStatus('interface_down')
|
||||
|
||||
|
||||
def SetStatus(self, status):
|
||||
""" Set the threads current status message in a thread-safe way.
|
||||
|
||||
Keyword arguments:
|
||||
status -- the current connection status
|
||||
|
||||
"""
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self.connecting_message = status
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
||||
def GetStatus(self):
|
||||
""" Get the threads current status message in a thread-safe way.
|
||||
|
||||
Returns:
|
||||
The current connection status.
|
||||
|
||||
"""
|
||||
self.lock.acquire()
|
||||
try:
|
||||
message = self.connecting_message
|
||||
finally:
|
||||
self.lock.release()
|
||||
return message
|
||||
|
||||
def reset_ip_addresses(self, wiface, liface):
|
||||
""" Resets the IP addresse for both wired/wireless interfaces.
|
||||
|
||||
Sets a false ip so that when we set the real one, the correct
|
||||
routing entry is created.
|
||||
|
||||
"""
|
||||
print 'Setting false IP...'
|
||||
self.SetStatus('resetting_ip_address')
|
||||
wiface.SetAddress('0.0.0.0')
|
||||
liface.SetAddress('0.0.0.0')
|
||||
|
||||
def put_iface_down(self, iface):
|
||||
""" Puts the given interface down. """
|
||||
print 'Putting interface down'
|
||||
self.SetStatus('interface_down')
|
||||
iface.Down()
|
||||
|
||||
def run_script_if_needed(self, script, msg):
|
||||
""" Execute a given script if needed.
|
||||
|
||||
Keyword arguments:
|
||||
script -- the script to execute, or None/'' if there isn't one.
|
||||
msg -- the name of the script to display in the log.
|
||||
|
||||
"""
|
||||
if script:
|
||||
print 'Executing %s script' % (msg)
|
||||
misc.ExecuteScript(script)
|
||||
|
||||
def flush_routes(self, wiface, liface):
|
||||
""" Flush the routes for both wired/wireless interfaces. """
|
||||
self.SetStatus('flushing_routing_table')
|
||||
print 'Flushing the routing table...'
|
||||
wiface.FlushRoutes()
|
||||
liface.FlushRoutes()
|
||||
|
||||
def set_broadcast_address(self, iface):
|
||||
""" Set the broadcast address for the given interface. """
|
||||
if not self.network.get('broadcast') == None:
|
||||
self.SetStatus('setting_broadcast_address')
|
||||
print 'Setting the broadcast address...' + self.network['broadcast']
|
||||
iface.SetAddress(broadcast=self.network['broadcast'])
|
||||
|
||||
def set_ip_address(self, iface):
|
||||
""" Set the IP address for the given interface.
|
||||
|
||||
Assigns a static IP if one is requested, otherwise calls DHCP.
|
||||
|
||||
"""
|
||||
if self.network.get('ip'):
|
||||
self.SetStatus('setting_static_ip')
|
||||
print 'Setting static IP : ' + self.network['ip']
|
||||
iface.SetAddress(self.network['ip'], self.network['netmask'])
|
||||
print 'Setting default gateway : ' + self.network['gateway']
|
||||
iface.SetDefaultRoute(self.network['gateway'])
|
||||
else:
|
||||
# Run dhcp...
|
||||
self.SetStatus('running_dhcp')
|
||||
print "Running DHCP"
|
||||
dhcp_status = iface.StartDHCP()
|
||||
if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']:
|
||||
self.abort_connection(dhcp_status)
|
||||
return
|
||||
|
||||
def set_dns_addresses(self):
|
||||
""" Set the DNS address(es).
|
||||
|
||||
If static DNS servers or global DNS servers are specified, set them.
|
||||
Otherwise do nothing.
|
||||
|
||||
"""
|
||||
if self.network.get('use_global_dns'):
|
||||
wnettools.SetDNS(misc.Noneify(self.global_dns_1),
|
||||
misc.Noneify(self.global_dns_2),
|
||||
misc.Noneify(self.global_dns_3))
|
||||
elif self.network.get('use_static_dns') and (self.network.get('dns1') or
|
||||
self.network.get('dns2') or self.network.get('dns3')):
|
||||
self.SetStatus('setting_static_dns')
|
||||
wnettools.SetDNS(self.network.get('dns1'), self.network.get('dns2'),
|
||||
self.network.get('dns3'))
|
||||
|
||||
def connect_aborted(self, reason):
|
||||
""" Sets the thread status to aborted in a thread-safe way.
|
||||
|
||||
Sets the status to aborted, and also delays returning for
|
||||
a few seconds to make sure the message is readable
|
||||
|
||||
"""
|
||||
if self.abort_reason:
|
||||
reason = self.abort_reason
|
||||
self.SetStatus(reason)
|
||||
self.is_aborted = True
|
||||
self.abort_msg = reason
|
||||
self.is_connecting = False
|
||||
print 'exiting connection thread'
|
||||
|
||||
def abort_connection(self, reason=""):
|
||||
""" Schedule a connection abortion for the given reason. """
|
||||
self.abort_reason = reason
|
||||
self.should_die = True
|
||||
|
||||
def release_dhcp_clients(self, wiface, liface):
|
||||
""" Release all running dhcp clients. """
|
||||
print "Releasing DHCP leases..."
|
||||
wiface.ReleaseDHCP()
|
||||
liface.ReleaseDHCP()
|
||||
|
||||
def stop_dhcp_clients(self, iface):
|
||||
""" Stop and running DHCP clients, as well as wpa_supplicant. """
|
||||
print 'Stopping wpa_supplicant and any DHCP clients'
|
||||
iface.StopWPA()
|
||||
wnettools.StopDHCP()
|
||||
|
||||
def abort_if_needed(self):
|
||||
""" Abort the thread is it has been requested. """
|
||||
if self.should_die:
|
||||
self.connect_aborted('aborted')
|
||||
thread.exit()
|
||||
|
||||
def put_iface_up(self, iface):
|
||||
""" Bring up given interface. """
|
||||
print 'Putting interface up...'
|
||||
self.SetStatus('interface_up')
|
||||
iface.Up()
|
||||
|
||||
|
||||
class Wireless(Controller):
|
||||
""" A wrapper for common wireless interface functions. """
|
||||
|
||||
def __init__(self):
|
||||
""" Initialize the class. """
|
||||
Controller.__init__(self)
|
||||
self._wpa_driver = None
|
||||
self.wiface = wnettools.WirelessInterface(self.wireless_interface,
|
||||
self.debug, self.wpa_driver)
|
||||
|
||||
def set_wpa_driver(self, value):
|
||||
self._wpa_driver = value
|
||||
if self.wiface:
|
||||
self.SetWPADriver(value)
|
||||
|
||||
def get_wpa_driver(self): return self._wpa_driver
|
||||
|
||||
wpa_driver = property(get_wpa_driver, set_wpa_driver)
|
||||
|
||||
|
||||
#def LoadInterfaces(self, dhcp_client, flush_tool):
|
||||
# """ Load the wnettools controls for the wired/wireless interfaces. """
|
||||
# #self.wiface = wnettools.WirelessInterface(self.wireless_interface,
|
||||
# # self.debug, self.wpa_driver)
|
||||
# self.dhcp_client = dhcp_client
|
||||
# self.flush_tool = flush_tool
|
||||
|
||||
def Scan(self, essid=None):
|
||||
""" Scan for available wireless networks.
|
||||
|
||||
Keyword arguments:
|
||||
essid -- The essid of a hidden network
|
||||
|
||||
Returns:
|
||||
A list of available networks sorted by strength.
|
||||
|
||||
"""
|
||||
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
|
||||
else:
|
||||
if x['strength'] < y['strength']:
|
||||
return 1
|
||||
elif x['strength'] > y['strength']:
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
if not self.wireless_interface: return []
|
||||
|
||||
wiface = self.wiface
|
||||
|
||||
# Prepare the interface for scanning
|
||||
wiface.Up()
|
||||
|
||||
# If there is a hidden essid then set it now, so that when it is
|
||||
# scanned it will be recognized.
|
||||
essid = misc.Noneify(essid)
|
||||
if essid is not None:
|
||||
print 'Setting hidden essid' + essid
|
||||
wiface.SetEssid(essid)
|
||||
|
||||
aps = wiface.GetNetworks()
|
||||
aps.sort(cmp=comp, reverse=True)
|
||||
|
||||
return aps
|
||||
|
||||
def Connect(self, network, debug=False):
|
||||
""" Spawn a connection thread to connect to the network.
|
||||
|
||||
Keyword arguments:
|
||||
network -- network to connect to
|
||||
|
||||
"""
|
||||
if not self.wireless_interface: return False
|
||||
|
||||
self.connecting_thread = WirelessConnectThread(network,
|
||||
self.wireless_interface, self.wired_interface,
|
||||
self.wpa_driver, self.before_script, self.after_script,
|
||||
self.disconnect_script, self.global_dns_1,
|
||||
self.global_dns_2, self.global_dns_3, self.wiface, self.liface,
|
||||
debug)
|
||||
self.connecting_thread.setDaemon(True)
|
||||
self.connecting_thread.start()
|
||||
return True
|
||||
|
||||
def GetSignalStrength(self, iwconfig=None, fast=False):
|
||||
""" Get signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The current signal strength.
|
||||
|
||||
"""
|
||||
return self.wiface.GetSignalStrength(iwconfig, fast)
|
||||
|
||||
def GetDBMStrength(self, iwconfig=None, fast=False):
|
||||
""" Get the dBm signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The current dBm signal strength.
|
||||
|
||||
"""
|
||||
return self.wiface.GetDBMStrength(iwconfig, fast)
|
||||
|
||||
def GetCurrentNetwork(self, iwconfig=None, fast=False):
|
||||
""" Get current network name.
|
||||
|
||||
Returns:
|
||||
The name of the currently connected network.
|
||||
|
||||
"""
|
||||
return self.wiface.GetCurrentNetwork(iwconfig, fast)
|
||||
|
||||
def GetIP(self, fast=False):
|
||||
""" Get the IP of the interface.
|
||||
|
||||
Returns:
|
||||
The IP address of the interface in dotted notation.
|
||||
|
||||
"""
|
||||
return self.wiface.GetIP(fast)
|
||||
|
||||
def GetBSSID(self, fast=True):
|
||||
""" Get the BSSID of the current access point.
|
||||
|
||||
Returns:
|
||||
The MAC Adress of the active access point as a string, or
|
||||
None the BSSID can't be found.
|
||||
|
||||
"""
|
||||
return self.wiface.GetBSSID(fast)
|
||||
|
||||
def GetIwconfig(self):
|
||||
""" Get the out of iwconfig. """
|
||||
return self.wiface.GetIwconfig()
|
||||
|
||||
def IsUp(self):
|
||||
""" Calls the IsUp method for the wireless interface.
|
||||
|
||||
Returns:
|
||||
True if the interface is up, False otherwise.
|
||||
|
||||
"""
|
||||
return self.wiface.IsUp()
|
||||
|
||||
def CreateAdHocNetwork(self, essid, channel, ip, enctype, key,
|
||||
enc_used, ics):
|
||||
""" Create an ad-hoc wireless network.
|
||||
|
||||
Keyword arguments:
|
||||
essid -- essid of the ad-hoc network
|
||||
channel -- channel of the ad-hoc network
|
||||
ip -- ip of the ad-hoc network
|
||||
enctype -- unused
|
||||
key -- key of the ad-hoc network
|
||||
enc_used -- encrytion enabled on ad-hoc network
|
||||
ics -- enable internet connection sharing
|
||||
|
||||
"""
|
||||
wiface = self.wiface
|
||||
print 'Creating ad-hoc network'
|
||||
print 'Killing dhclient and wpa_supplicant'
|
||||
wnettools.StopDHCP()
|
||||
wiface.StopWPA()
|
||||
print 'Putting wireless interface down'
|
||||
wiface.Down()
|
||||
print 'Setting mode, channel, and essid'
|
||||
wiface.SetMode('ad-hoc')
|
||||
wiface.SetChannel(channel)
|
||||
wiface.SetEssid(essid)
|
||||
# Right now it just assumes you're using WEP
|
||||
if enc_used:
|
||||
print 'Setting encryption key'
|
||||
wiface.SetKey(key)
|
||||
print 'Putting interface up'
|
||||
wiface.Up()
|
||||
# Just assume that the netmask is 255.255.255.0, it simplifies ICS
|
||||
print 'Setting IP address'
|
||||
wiface.SetAddress(ip, '255.255.255.0')
|
||||
|
||||
ip_parts = misc.IsValidIP(ip)
|
||||
|
||||
if ics and ip_parts:
|
||||
# Set up internet connection sharing here
|
||||
# Flush the forward tables
|
||||
misc.Run('iptables -F FORWARD')
|
||||
misc.Run('iptables -N fw-interfaces')
|
||||
misc.Run('iptables -N fw-open')
|
||||
misc.Run('iptables -F fw-interfaces')
|
||||
misc.Run('iptables -F fw-open')
|
||||
misc.Run('iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS \
|
||||
--clamp-mss-to-pmtu')
|
||||
misc.Run('iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT')
|
||||
misc.Run('iptables -A FORWARD -j fw-interfaces ')
|
||||
misc.Run('iptables -A FORWARD -j fw-open ')
|
||||
misc.Run('iptables -A FORWARD -j REJECT --reject-with icmp-host-unreachable')
|
||||
misc.Run('iptables -P FORWARD DROP')
|
||||
misc.Run('iptables -A fw-interfaces -i ' + self.wireless_interface + ' -j ACCEPT')
|
||||
net_ip = '.'.join(ip_parts[0:3]) + '.0'
|
||||
misc.Run('iptables -t nat -A POSTROUTING -s ' + net_ip + \
|
||||
'/255.255.255.0 -o ' + self.wired_interface + \
|
||||
' -j MASQUERADE')
|
||||
misc.Run('echo 1 > /proc/sys/net/ipv4/ip_forward') # Enable routing
|
||||
|
||||
def DetectWirelessInterface(self):
|
||||
""" Detect available wireless interfaces.
|
||||
|
||||
Returns:
|
||||
The first available wireless interface.
|
||||
|
||||
"""
|
||||
return wnettools.GetWirelessInterfaces()
|
||||
|
||||
def GetKillSwitchStatus(self):
|
||||
""" Get the current status of the Killswitch.
|
||||
|
||||
Returns:
|
||||
True if the killswitch is on, False otherwise.
|
||||
|
||||
"""
|
||||
return self.wiface.GetKillSwitchStatus()
|
||||
|
||||
def Disconnect(self):
|
||||
""" Disconnect the given iface.
|
||||
|
||||
Executes the disconnect script associated with a given interface,
|
||||
Resets it's IP address, and puts the interface down then up.
|
||||
|
||||
"""
|
||||
wiface = self.wiface
|
||||
if self.disconnect_script not in (None, ""):
|
||||
print 'Running wireless network disconnect script'
|
||||
misc.ExecuteScript(self.disconnect_script)
|
||||
|
||||
wiface.ReleaseDHCP()
|
||||
wiface.SetAddress('0.0.0.0')
|
||||
wiface.Down()
|
||||
wiface.Up()
|
||||
|
||||
def EnableInterface(self):
|
||||
""" Puts the interface up. """
|
||||
return self.wiface.Up()
|
||||
|
||||
def DisableInterface(self):
|
||||
""" Puts the interface down. """
|
||||
return self.wiface.Down()
|
||||
|
||||
def SetWPADriver(self, driver):
|
||||
""" 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.
|
||||
|
||||
This thread, when run, will perform the necessary steps to connect
|
||||
to the specified network.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, network, wireless, wired, wpa_driver,
|
||||
before_script, after_script, disconnect_script, gdns1,
|
||||
gdns2, gdns3, wiface, liface, debug=False):
|
||||
""" Initialise the thread with network information.
|
||||
|
||||
Keyword arguments:
|
||||
network -- the network to connect to
|
||||
wireless -- name of the wireless interface
|
||||
wired -- name of the wired interface
|
||||
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
|
||||
gdns1 -- global DNS server 1
|
||||
gdns2 -- global DNS server 2
|
||||
gdns3 -- global DNS server 3
|
||||
|
||||
"""
|
||||
ConnectThread.__init__(self, network, wireless, wired,
|
||||
before_script, after_script, disconnect_script, gdns1,
|
||||
gdns2, gdns3, wiface, liface, debug)
|
||||
self.wpa_driver = wpa_driver
|
||||
|
||||
|
||||
def run(self):
|
||||
""" The main function of the connection thread.
|
||||
|
||||
This function performs the necessary calls to connect to the
|
||||
specified network, using the information provided. The following
|
||||
indicates the steps taken.
|
||||
1. Run pre-connection script.
|
||||
2. Take down the interface and clean up any previous
|
||||
connections.
|
||||
3. Generate a PSK if required and authenticate.
|
||||
4. Associate with the WAP.
|
||||
5. Get/set IP address and DNS servers.
|
||||
|
||||
"""
|
||||
wiface = self.wiface
|
||||
liface = self.liface
|
||||
self.is_connecting = True
|
||||
self.is_fast = True
|
||||
|
||||
# Run pre-connection script.
|
||||
self.abort_if_needed()
|
||||
self.run_script_if_needed(self.before_script, 'pre-connection')
|
||||
self.abort_if_needed()
|
||||
|
||||
# Take down interface and clean up previous connections.
|
||||
self.put_iface_down(wiface)
|
||||
self.abort_if_needed()
|
||||
self.release_dhcp_clients(wiface, liface)
|
||||
self.reset_ip_addresses(wiface, liface)
|
||||
self.stop_dhcp_clients(wiface)
|
||||
self.abort_if_needed()
|
||||
self.flush_routes(wiface, liface)
|
||||
|
||||
# Generate PSK and authenticate if needed.
|
||||
if self.wpa_driver != 'ralink legacy':
|
||||
self.generate_psk_and_authenticate(wiface)
|
||||
|
||||
# Put interface up.
|
||||
self.abort_if_needed()
|
||||
self.SetStatus('configuring_interface')
|
||||
self.put_iface_up(wiface)
|
||||
self.abort_if_needed()
|
||||
|
||||
# Associate.
|
||||
wiface.SetMode(self.network['mode'])
|
||||
wiface.Associate(self.network['essid'], self.network['channel'],
|
||||
self.network['bssid'])
|
||||
|
||||
# Authenticate after association for Ralink legacy cards.
|
||||
if self.wpa_driver == 'ralink legacy':
|
||||
if self.network.get('key'):
|
||||
wiface.Authenticate(self.network)
|
||||
|
||||
# Validate Authentication.
|
||||
if self.network.get('enctype'):
|
||||
self.SetStatus('validating_authentication')
|
||||
if not wiface.ValidateAuthentication(time.time(),
|
||||
fast=self.is_fast):
|
||||
self.abort_connection('bad_pass')
|
||||
self.abort_if_needed()
|
||||
|
||||
# Set up gateway, IP address, and DNS servers.
|
||||
self.set_broadcast_address(wiface)
|
||||
self.abort_if_needed()
|
||||
self.set_ip_address(wiface)
|
||||
self.set_dns_addresses()
|
||||
|
||||
# Run post-connection script.
|
||||
self.abort_if_needed()
|
||||
self.run_script_if_needed(self.after_script, 'post-connection')
|
||||
|
||||
self.SetStatus('done')
|
||||
print 'Connecting thread exiting.'
|
||||
if self.debug:
|
||||
print "IP Address is: " + str(wiface.GetIP(fast=self.is_fast))
|
||||
self.is_connecting = False
|
||||
|
||||
def generate_psk_and_authenticate(self, wiface):
|
||||
""" Generates a PSK and authenticates if necessary.
|
||||
|
||||
Generates a PSK using wpa_passphrase, and starts the authentication
|
||||
process if encryption is on.
|
||||
|
||||
"""
|
||||
def _sanitize(key):
|
||||
""" Escapes characters wpa_supplicant doesn't handle properly. """
|
||||
new_key = []
|
||||
blacklist = ["$", "`", "\""]
|
||||
for c in key:
|
||||
if c in blacklist:
|
||||
new_key.append("\\" + c)
|
||||
else:
|
||||
new_key.append(c)
|
||||
return ''.join(new_key)
|
||||
|
||||
# Check to see if we need to generate a PSK (only for non-ralink
|
||||
# cards).
|
||||
if self.network.get('key'):
|
||||
self.SetStatus('generating_psk')
|
||||
|
||||
print 'Generating psk...'
|
||||
key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*',
|
||||
re.I | re.M | re.S)
|
||||
self.network['psk'] = misc.RunRegex(key_pattern,
|
||||
misc.Run(''.join(['wpa_passphrase "',
|
||||
self.network['essid'], '" "',
|
||||
_sanitize(self.network['key']), '"'])))
|
||||
|
||||
if not self.network['psk']:
|
||||
self.network['psk'] = self.network['key']
|
||||
print 'WARNING: PSK generation failed! Falling back to ' + \
|
||||
'wireless key.\nPlease report this error to the wicd ' + \
|
||||
'developers!'
|
||||
# Generate the wpa_supplicant file...
|
||||
if self.network.get('enctype'):
|
||||
self.SetStatus('generating_wpa_config')
|
||||
print 'Attempting to authenticate...'
|
||||
wiface.Authenticate(self.network)
|
||||
|
||||
|
||||
class Wired(Controller):
|
||||
""" A wrapper for common wired interface functions. """
|
||||
|
||||
def __init__(self):
|
||||
""" Initialise the class. """
|
||||
Controller.__init__(self)
|
||||
self.wpa_driver = None
|
||||
self._link_detect = None
|
||||
self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
|
||||
|
||||
def set_link_detect(self, value):
|
||||
self._link_detect = value
|
||||
if self.liface:
|
||||
self.liface.link_detect = value
|
||||
|
||||
def get_link_detect(self): return self._link_detect
|
||||
|
||||
link_detect = property(get_link_detect, set_link_detect)
|
||||
|
||||
#def LoadInterfaces(self, dhcp_client, link_tool, flush_tool):
|
||||
# """ Load the wnettools controls for the wired/wireless interfaces. """
|
||||
# #self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
|
||||
# self.dhcp_client = dhcp_client
|
||||
# self.link_detect = link_tool
|
||||
# self.flush_tool = flush_tool
|
||||
|
||||
def CheckPluggedIn(self, fast=False):
|
||||
""" Check whether the wired connection is plugged in.
|
||||
|
||||
Returns:
|
||||
The status of the physical connection link.
|
||||
|
||||
"""
|
||||
return self.liface.GetPluggedIn(fast)
|
||||
|
||||
def Connect(self, network, debug=False):
|
||||
""" Spawn a connection thread to connect to the network.
|
||||
|
||||
Keyword arguments:
|
||||
network -- network to connect to
|
||||
|
||||
"""
|
||||
if not self.wired_interface: return False
|
||||
self.connecting_thread = WiredConnectThread(network,
|
||||
self.wireless_interface, 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.wiface, self.liface,
|
||||
debug)
|
||||
self.connecting_thread.setDaemon(True)
|
||||
self.connecting_thread.start()
|
||||
return True
|
||||
|
||||
def GetIP(self, fast=False):
|
||||
""" Get the IP of the interface.
|
||||
|
||||
Returns:
|
||||
The IP address of the interface in dotted notation.
|
||||
|
||||
"""
|
||||
return self.liface.GetIP(fast)
|
||||
|
||||
def Disconnect(self):
|
||||
""" Disconnect from the network. """
|
||||
liface = self.liface
|
||||
if self.disconnect_script != None:
|
||||
print 'Running wired disconnect script'
|
||||
misc.Run(self.disconnect_script)
|
||||
|
||||
liface.ReleaseDHCP()
|
||||
liface.SetAddress('0.0.0.0')
|
||||
liface.Down()
|
||||
liface.Up()
|
||||
|
||||
def IsUp(self):
|
||||
""" Calls the IsUp method for the wired interface.
|
||||
|
||||
Returns:
|
||||
True if the interface is up, False otherwise.
|
||||
|
||||
"""
|
||||
return self.liface.IsUp()
|
||||
|
||||
def EnableInterface(self):
|
||||
""" Puts the interface up.
|
||||
|
||||
Returns:
|
||||
True if the interface was put up succesfully, False otherwise.
|
||||
|
||||
"""
|
||||
return self.liface.Up()
|
||||
|
||||
def DisableInterface(self):
|
||||
""" Puts the interface down.
|
||||
|
||||
Returns:
|
||||
True if the interface was put down succesfully, False otherwise.
|
||||
|
||||
"""
|
||||
return self.liface.Down()
|
||||
|
||||
|
||||
class WiredConnectThread(ConnectThread):
|
||||
""" A thread class to perform the connection to a wired network.
|
||||
|
||||
This thread, when run, will perform the necessary steps to connect
|
||||
to the specified network.
|
||||
|
||||
"""
|
||||
def __init__(self, network, wireless, wired,
|
||||
before_script, after_script, disconnect_script, gdns1,
|
||||
gdns2, gdns3, wiface, liface, debug=False):
|
||||
""" Initialise the thread with network information.
|
||||
|
||||
Keyword arguments:
|
||||
network -- the network to connect to
|
||||
wireless -- name of the wireless interface
|
||||
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
|
||||
gdns1 -- global DNS server 1
|
||||
gdns2 -- global DNS server 2
|
||||
gdns3 -- global DNS server 3
|
||||
|
||||
"""
|
||||
ConnectThread.__init__(self, network, wireless, wired,
|
||||
before_script, after_script, disconnect_script, gdns1,
|
||||
gdns2, gdns3, wiface, liface, debug)
|
||||
|
||||
def run(self):
|
||||
""" The main function of the connection thread.
|
||||
|
||||
This function performs the necessary calls to connect to the
|
||||
specified network, using the information provided. The following
|
||||
indicates the steps taken.
|
||||
1. Run pre-connection script.
|
||||
2. Take down the interface and clean up any previous
|
||||
connections.
|
||||
3. Bring up the interface.
|
||||
4. Get/set IP address and DNS servers.
|
||||
5. Run post-connection script.
|
||||
|
||||
"""
|
||||
wiface = self.wiface
|
||||
liface = self.liface
|
||||
|
||||
self.is_connecting = True
|
||||
#TODO pass is_fast in.
|
||||
self.is_fast = True
|
||||
|
||||
# Run pre-connection script.
|
||||
self.abort_if_needed()
|
||||
self.run_script_if_needed(self.before_script, 'pre-connection')
|
||||
self.abort_if_needed()
|
||||
|
||||
# Take down interface and clean up previous connections.
|
||||
self.put_iface_down(liface)
|
||||
self.release_dhcp_clients(wiface, liface)
|
||||
self.reset_ip_addresses(wiface, liface)
|
||||
self.stop_dhcp_clients(wiface)
|
||||
self.abort_if_needed()
|
||||
self.flush_routes(wiface, liface)
|
||||
|
||||
# Bring up interface.
|
||||
self.put_iface_up(liface)
|
||||
self.abort_if_needed()
|
||||
|
||||
# Set gateway, IP adresses, and DNS servers.
|
||||
self.set_broadcast_address(liface)
|
||||
self.abort_if_needed()
|
||||
self.set_ip_address(liface)
|
||||
self.set_dns_addresses()
|
||||
self.abort_if_needed()
|
||||
|
||||
# Run post-connection script.
|
||||
self.run_script_if_needed(self.after_script, 'post-connection')
|
||||
|
||||
self.SetStatus('done')
|
||||
print 'Connecting thread exiting.'
|
||||
if self.debug:
|
||||
print "IP Address is: " + str(liface.GetIP(fast=self.is_fast))
|
||||
self.is_connecting = False
|
||||
268
wicd/prefs.py
Normal file
268
wicd/prefs.py
Normal file
@@ -0,0 +1,268 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
""" Wicd Preferences Dialog.
|
||||
|
||||
Displays the main settings dialog window for wicd.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
import pango
|
||||
|
||||
import wicd.misc
|
||||
from wicd.misc import checkboxTextboxToggle, noneToBlankString
|
||||
|
||||
daemon = None
|
||||
wireless = None
|
||||
wired = None
|
||||
config = None
|
||||
|
||||
language = misc.get_language_list_gui()
|
||||
|
||||
class PreferencesDialog(object):
|
||||
def __init__(self, wTree, dbus):
|
||||
global daemon, wireless, wired, config
|
||||
daemon = dbus['daemon']
|
||||
wireless = dbus['wireless']
|
||||
wired = dbus['wired']
|
||||
config = dbus['config']
|
||||
self.wTree = wTree
|
||||
self.prep_settings_diag()
|
||||
self.build_preferences_diag()
|
||||
|
||||
def build_preferences_diag(self):
|
||||
def build_combobox(lbl):
|
||||
""" Sets up a ComboBox using the given widget name. """
|
||||
liststore = gtk.ListStore(gobject.TYPE_STRING)
|
||||
combobox = self.wTree.get_widget(lbl)
|
||||
combobox.clear()
|
||||
combobox.set_model(liststore)
|
||||
cell = gtk.CellRendererText()
|
||||
combobox.pack_start(cell, True)
|
||||
combobox.add_attribute(cell, 'text', 0)
|
||||
return combobox
|
||||
|
||||
def setup_label(name, lbl=""):
|
||||
widget = self.wTree.get_widget(name)
|
||||
if lbl:
|
||||
widget.set_label(language[lbl])
|
||||
return widget
|
||||
|
||||
self.dialog = self.wTree.get_widget("pref_dialog")
|
||||
self.dialog.set_title(language['preferences'])
|
||||
size = config.ReadWindowSize("pref")
|
||||
width = size[0]
|
||||
height = size[1]
|
||||
if width > -1 and height > -1:
|
||||
self.dialog.resize(int(width), int(height))
|
||||
|
||||
self.wiredcheckbox = setup_label("pref_always_check",
|
||||
'wired_always_on')
|
||||
self.wiredcheckbox.set_active(wired.GetAlwaysShowWiredInterface())
|
||||
self.reconnectcheckbox = setup_label("pref_auto_check",
|
||||
'auto_reconnect')
|
||||
self.reconnectcheckbox.set_active(daemon.GetAutoReconnect())
|
||||
self.debugmodecheckbox = setup_label("pref_debug_check",
|
||||
'use_debug_mode')
|
||||
self.debugmodecheckbox.set_active(daemon.GetDebugMode())
|
||||
self.displaytypecheckbox = setup_label("pref_dbm_check",
|
||||
'display_type_dialog')
|
||||
self.displaytypecheckbox.set_active(daemon.GetSignalDisplayType())
|
||||
self.usedefaultradiobutton = setup_label("pref_use_def_radio",
|
||||
'use_default_profile')
|
||||
self.showlistradiobutton = setup_label("pref_prompt_radio",
|
||||
'show_wired_list')
|
||||
self.lastusedradiobutton = setup_label("pref_use_last_radio",
|
||||
'use_last_used_profile')
|
||||
|
||||
# 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")
|
||||
dhcp_list = [self.dhcpautoradio, self.dhclientradio, self.dhcpcdradio,
|
||||
self.pumpradio]
|
||||
|
||||
dhcp_method = daemon.GetDHCPClient()
|
||||
dhcp_list[dhcp_method].set_active(True)
|
||||
|
||||
# Wired Link Detection Apps
|
||||
self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config')
|
||||
self.linkautoradio = setup_label("link_auto_radio")
|
||||
self.ethtoolradio = setup_label("ethtool_radio")
|
||||
self.miitoolradio = setup_label("miitool_radio")
|
||||
wired_link_list = [self.linkautoradio, self.ethtoolradio,
|
||||
self.miitoolradio]
|
||||
wired_link_method = daemon.GetLinkDetectionTool()
|
||||
wired_link_list[wired_link_method].set_active(True)
|
||||
|
||||
# Route Flushing Apps
|
||||
self.flushautoradio = setup_label("flush_auto_radio",
|
||||
'wicd_auto_config')
|
||||
self.ipflushradio = setup_label("ip_flush_radio")
|
||||
self.routeflushradio = setup_label("route_flush_radio")
|
||||
flush_list = [self.flushautoradio, self.ipflushradio,
|
||||
self.routeflushradio]
|
||||
flush_method = daemon.GetFlushTool()
|
||||
flush_list[flush_method].set_active(True)
|
||||
|
||||
if wired.GetWiredAutoConnectMethod() == 1:
|
||||
self.usedefaultradiobutton.set_active(True)
|
||||
elif wired.GetWiredAutoConnectMethod() == 2:
|
||||
self.showlistradiobutton.set_active(True)
|
||||
elif wired.GetWiredAutoConnectMethod() == 3:
|
||||
self.lastusedradiobutton.set_active(True)
|
||||
|
||||
self.entryWirelessInterface = self.wTree.get_widget("pref_wifi_entry")
|
||||
self.entryWirelessInterface.set_text(daemon.GetWirelessInterface())
|
||||
|
||||
self.entryWiredInterface = self.wTree.get_widget("pref_wired_entry")
|
||||
self.entryWiredInterface.set_text(daemon.GetWiredInterface())
|
||||
|
||||
# Replacement for the combo box hack
|
||||
self.wpadrivercombo = build_combobox("pref_wpa_combobox")
|
||||
self.wpadrivers = ["wext", "hostap", "madwifi", "atmel", "ndiswrapper",
|
||||
"ipw", "ralink legacy"]
|
||||
found = False
|
||||
def_driver = daemon.GetWPADriver()
|
||||
for i, x in enumerate(self.wpadrivers):
|
||||
if x == def_driver: #and not found:
|
||||
found = True
|
||||
user_driver_index = i
|
||||
self.wpadrivercombo.remove_text(i)
|
||||
self.wpadrivercombo.append_text(x)
|
||||
|
||||
# Set the active choice here. Doing it before all the items are
|
||||
# added the combobox causes the choice to be reset.
|
||||
if found:
|
||||
self.wpadrivercombo.set_active(user_driver_index)
|
||||
else:
|
||||
# Use wext as default, since normally it is the correct driver.
|
||||
self.wpadrivercombo.set_active(0)
|
||||
|
||||
# Set up global DNS stuff
|
||||
self.useGlobalDNSCheckbox = setup_label("pref_global_check",
|
||||
'use_global_dns')
|
||||
|
||||
self.dns1Entry = self.wTree.get_widget("pref_dns1_entry")
|
||||
self.dns2Entry = self.wTree.get_widget("pref_dns2_entry")
|
||||
self.dns3Entry = self.wTree.get_widget("pref_dns3_entry")
|
||||
|
||||
self.useGlobalDNSCheckbox.connect("toggled", checkboxTextboxToggle,
|
||||
(self.dns1Entry, self.dns2Entry,
|
||||
self.dns3Entry))
|
||||
|
||||
dns_addresses = daemon.GetGlobalDNSAddresses()
|
||||
self.useGlobalDNSCheckbox.set_active(daemon.GetUseGlobalDNS())
|
||||
self.dns1Entry.set_text(noneToBlankString(dns_addresses[0]))
|
||||
self.dns2Entry.set_text(noneToBlankString(dns_addresses[1]))
|
||||
self.dns3Entry.set_text(noneToBlankString(dns_addresses[2]))
|
||||
|
||||
if not daemon.GetUseGlobalDNS():
|
||||
self.dns1Entry.set_sensitive(False)
|
||||
self.dns2Entry.set_sensitive(False)
|
||||
self.dns3Entry.set_sensitive(False)
|
||||
|
||||
self.wTree.get_widget("notebook2").set_current_page(0)
|
||||
|
||||
def run(self):
|
||||
return self.dialog.run()
|
||||
|
||||
def hide(self):
|
||||
self.dialog.hide()
|
||||
|
||||
def show_all(self):
|
||||
self.show_all()
|
||||
|
||||
def save_results(self):
|
||||
daemon.SetUseGlobalDNS(self.useGlobalDNSCheckbox.get_active())
|
||||
daemon.SetGlobalDNS(self.dns1Entry.get_text(), self.dns2Entry.get_text(),
|
||||
self.dns3Entry.get_text())
|
||||
daemon.SetWirelessInterface(self.entryWirelessInterface.get_text())
|
||||
daemon.SetWiredInterface(self.entryWiredInterface.get_text())
|
||||
daemon.SetWPADriver(self.wpadrivers[self.wpadrivercombo.get_active()])
|
||||
wired.SetAlwaysShowWiredInterface(self.wiredcheckbox.get_active())
|
||||
daemon.SetAutoReconnect(self.reconnectcheckbox.get_active())
|
||||
daemon.SetDebugMode(self.debugmodecheckbox.get_active())
|
||||
daemon.SetSignalDisplayType(self.displaytypecheckbox.get_active())
|
||||
if self.showlistradiobutton.get_active():
|
||||
wired.SetWiredAutoConnectMethod(2)
|
||||
elif self.lastusedradiobutton.get_active():
|
||||
wired.SetWiredAutoConnectMethod(3)
|
||||
else:
|
||||
wired.SetWiredAutoConnectMethod(1)
|
||||
|
||||
# External Programs Tab
|
||||
if self.dhcpautoradio.get_active():
|
||||
dhcp_client = misc.AUTO
|
||||
elif self.dhclientradio.get_active():
|
||||
dhcp_client = misc.DHCLIENT
|
||||
elif self.dhcpcdradio.get_active():
|
||||
dhcp_client = misc.DHCPCD
|
||||
else:
|
||||
dhcp_client = misc.PUMP
|
||||
daemon.SetDHCPClient(dhcp_client)
|
||||
|
||||
if self.linkautoradio.get_active():
|
||||
link_tool = misc.AUTO
|
||||
elif self.ethtoolradio.get_active():
|
||||
link_tool = misc.ETHTOOL
|
||||
else:
|
||||
link_tool = misc.MIITOOL
|
||||
daemon.SetLinkDetectionTool(link_tool)
|
||||
|
||||
if self.flushautoradio.get_active():
|
||||
flush_tool = misc.AUTO
|
||||
elif self.ipflushradio.get_active():
|
||||
flush_tool = misc.IP
|
||||
else:
|
||||
flush_tool = misc.ROUTE
|
||||
daemon.SetFlushTool(flush_tool)
|
||||
|
||||
[width, height] = self.dialog.get_size()
|
||||
config.WriteWindowSize(width, height, "pref")
|
||||
|
||||
def set_label(self, glade_str, label):
|
||||
""" Sets the label for the given widget in wicd.glade. """
|
||||
self.wTree.get_widget(glade_str).set_label(label)
|
||||
|
||||
def prep_settings_diag(self):
|
||||
""" Set up anything that doesn't have to be persisted later. """
|
||||
# External Programs tab
|
||||
self.wTree.get_widget("gen_settings_label").set_label(language["gen_settings"])
|
||||
self.wTree.get_widget("ext_prog_label").set_label(language["ext_programs"])
|
||||
self.wTree.get_widget("dhcp_client_label").set_label(language["dhcp_client"])
|
||||
self.wTree.get_widget("wired_detect_label").set_label(language["wired_detect"])
|
||||
self.wTree.get_widget("route_flush_label").set_label(language["route_flush"])
|
||||
|
||||
entryWiredAutoMethod = self.wTree.get_widget("pref_wired_auto_label")
|
||||
entryWiredAutoMethod.set_label('Wired Autoconnect Setting:')
|
||||
entryWiredAutoMethod.set_alignment(0, 0)
|
||||
atrlist = pango.AttrList()
|
||||
atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
|
||||
entryWiredAutoMethod.set_attributes(atrlist)
|
||||
|
||||
self.set_label("pref_dns1_label", language['dns'] + ' ' + language['1'])
|
||||
self.set_label("pref_dns2_label", language['dns'] + ' ' + language['2'])
|
||||
self.set_label("pref_dns3_label", language['dns'] + ' ' + language['3'])
|
||||
self.set_label("pref_wifi_label", language['wireless_interface'] + ':')
|
||||
self.set_label("pref_wired_label", language['wired_interface'] + ':')
|
||||
self.set_label("pref_driver_label", language['wpa_supplicant_driver'] + ':')
|
||||
38
wicd/suspend.py
Executable file
38
wicd/suspend.py
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
""" Suspends the wicd daemon.
|
||||
|
||||
Sets a flag in the daemon that will stop it from monitoring networkg status.
|
||||
Used for when a laptop enters hibernation/suspension.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 Adam Blackburn
|
||||
# Copyright (C) 2007 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import dbus
|
||||
import dbus.service
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
|
||||
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
|
||||
|
||||
if __name__ == '__main__':
|
||||
daemon.Disconnect()
|
||||
daemon.SetForcedDisconnect(False)
|
||||
daemon.SetSuspend(True)
|
||||
|
||||
697
wicd/wicd.py
Executable file
697
wicd/wicd.py
Executable file
@@ -0,0 +1,697 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" wicd - wireless connection daemon frontend implementation
|
||||
|
||||
This module implements a usermode frontend for wicd. It updates connection
|
||||
information, provides an (optional) tray icon, and allows for launching of
|
||||
the wicd GUI and Wired Profile Chooser.
|
||||
|
||||
class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo.
|
||||
class TrayConnectionInfo() -- Child class of TrayIcon which provides
|
||||
and updates connection status.
|
||||
class TrayIconGUI() -- Child class of TrayIcon which implements the tray.
|
||||
icon itself. Parent class of StatusTrayIconGUI and EggTrayIconGUI.
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (C) 2007 - 2008 Adam Blackburn
|
||||
# Copyright (C) 2007 - 2008 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
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import sys
|
||||
import gtk
|
||||
import gobject
|
||||
import getopt
|
||||
import os
|
||||
import pango
|
||||
from dbus import DBusException
|
||||
from dbus import version as dbus_version
|
||||
|
||||
# Wicd specific imports
|
||||
import wicd.wpath as wpath
|
||||
import wicd.misc as misc
|
||||
import wicd.gui as gui
|
||||
from wicd.dbusmanager import DBusManager
|
||||
|
||||
# Import egg.trayicon if we're using an older gtk version
|
||||
if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10):
|
||||
try:
|
||||
import egg.trayicon
|
||||
USE_EGG = True
|
||||
except ImportError:
|
||||
print 'Unable to load wicd.py: Missing egg.trayicon module.'
|
||||
sys.exit(1)
|
||||
else:
|
||||
USE_EGG = False
|
||||
|
||||
if not dbus_version or (dbus_version < (0, 80, 0)):
|
||||
import dbus.glib
|
||||
else:
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
misc.RenameProcess("wicd-client")
|
||||
|
||||
if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
dbus_manager = None
|
||||
daemon = None
|
||||
wireless = None
|
||||
wired = None
|
||||
wired = None
|
||||
config = None
|
||||
|
||||
language = misc.get_language_list_tray()
|
||||
|
||||
class NetworkMenuItem(gtk.ImageMenuItem):
|
||||
def __init__(self, lbl, is_active=False):
|
||||
gtk.ImageMenuItem.__init__(self)
|
||||
self.label = gtk.Label(lbl)
|
||||
if is_active:
|
||||
atrlist = pango.AttrList()
|
||||
atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
|
||||
self.label.set_attributes(atrlist)
|
||||
self.label.set_justify(gtk.JUSTIFY_LEFT)
|
||||
self.label.set_alignment(0, 0)
|
||||
self.add(self.label)
|
||||
self.label.show()
|
||||
|
||||
|
||||
class TrayIcon:
|
||||
""" Base Tray Icon class.
|
||||
|
||||
Base Class for implementing a tray icon to display network status.
|
||||
|
||||
"""
|
||||
def __init__(self, use_tray, animate):
|
||||
if USE_EGG:
|
||||
self.tr = self.EggTrayIconGUI(use_tray)
|
||||
else:
|
||||
self.tr = self.StatusTrayIconGUI(use_tray)
|
||||
self.icon_info = self.TrayConnectionInfo(self.tr, use_tray, animate)
|
||||
|
||||
|
||||
class TrayConnectionInfo:
|
||||
""" Class for updating the tray icon status. """
|
||||
def __init__(self, tr, use_tray=True, animate=True):
|
||||
""" 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.use_tray = use_tray
|
||||
self.last_sndbytes = -1
|
||||
self.last_rcvbytes = -1
|
||||
self.max_snd_gain = 10000
|
||||
self.max_rcv_gain = 10000
|
||||
self.animate = animate
|
||||
self.update_tray_icon()
|
||||
|
||||
def wired_profile_chooser(self):
|
||||
""" Launch the wired profile chooser. """
|
||||
gui.WiredProfileChooser()
|
||||
daemon.SetNeedWiredProfileChooser(False)
|
||||
|
||||
def set_wired_state(self, info):
|
||||
""" Sets the icon info for a wired state. """
|
||||
wired_ip = info[0]
|
||||
self.tr.set_from_file(wpath.images + "wired.png")
|
||||
self.tr.set_tooltip(language['connected_to_wired'].replace('$A',
|
||||
wired_ip))
|
||||
|
||||
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(strength))
|
||||
|
||||
if wireless.GetWirelessProperty(cur_net_id, "encryption"):
|
||||
lock = "-lock"
|
||||
|
||||
self.tr.set_tooltip(language['connected_to_wireless']
|
||||
.replace('$A', self.network)
|
||||
.replace('$B', sig_string)
|
||||
.replace('$C', str(wireless_ip)))
|
||||
self.set_signal_image(int(strength), lock)
|
||||
|
||||
def set_connecting_state(self, info):
|
||||
""" Sets the icon info for a connecting state. """
|
||||
if info[0] == 'wired' and len(info) == 1:
|
||||
cur_network = language['wired']
|
||||
else:
|
||||
cur_network = info[1]
|
||||
self.tr.set_tooltip(language['connecting'] + " to " +
|
||||
cur_network + "...")
|
||||
self.tr.set_from_file(wpath.images + "no-signal.png")
|
||||
|
||||
def set_not_connected_state(self, info):
|
||||
""" Set the icon info for the not connected state. """
|
||||
self.tr.set_from_file(wpath.images + "no-signal.png")
|
||||
if wireless.GetKillSwitchEnabled():
|
||||
status = (language['not_connected'] + " (" +
|
||||
language['killswitch_enabled'] + ")")
|
||||
else:
|
||||
status = language['not_connected']
|
||||
self.tr.set_tooltip(status)
|
||||
|
||||
def update_tray_icon(self, state=None, info=None):
|
||||
""" Updates the tray icon and current connection status. """
|
||||
if not self.use_tray: return False
|
||||
|
||||
if not state or not info:
|
||||
[state, info] = daemon.GetConnectionStatus()
|
||||
|
||||
if state == misc.WIRED:
|
||||
self.set_wired_state(info)
|
||||
elif state == misc.WIRELESS:
|
||||
self.set_wireless_state(info)
|
||||
elif state == misc.CONNECTING:
|
||||
self.set_connecting_state(info)
|
||||
elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
|
||||
self.set_not_connected_state(info)
|
||||
else:
|
||||
print 'Invalid state returned!!!'
|
||||
return False
|
||||
return True
|
||||
|
||||
def set_signal_image(self, wireless_signal, lock):
|
||||
""" Sets the tray icon image for an active wireless connection. """
|
||||
if self.animate:
|
||||
prefix = self.get_bandwidth_state()
|
||||
else:
|
||||
prefix = ''
|
||||
if daemon.GetSignalDisplayType() == 0:
|
||||
if wireless_signal > 75:
|
||||
signal_img = "high-signal"
|
||||
elif wireless_signal > 50:
|
||||
signal_img = "good-signal"
|
||||
elif wireless_signal > 25:
|
||||
signal_img = "low-signal"
|
||||
else:
|
||||
signal_img = "bad-signal"
|
||||
else:
|
||||
if wireless_signal >= -60:
|
||||
signal_img = "high-signal"
|
||||
elif wireless_signal >= -70:
|
||||
signal_img = "good-signal"
|
||||
elif wireless_signal >= -80:
|
||||
signal_img = "low-signal"
|
||||
else:
|
||||
signal_img = "bad-signal"
|
||||
|
||||
img_file = ''.join([wpath.images, prefix, signal_img, lock, ".png"])
|
||||
self.tr.set_from_file(img_file)
|
||||
|
||||
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(rcvbytes, self.max_rcv_gain,
|
||||
self.last_rcvbytes)
|
||||
receiving = activity[0]
|
||||
self.max_rcv_gain = activity[1]
|
||||
self.last_rcvbytes = activity[2]
|
||||
|
||||
# Figure out out transmitting data info.
|
||||
activity = self.is_network_active(sndbytes, self.max_snd_gain,
|
||||
self.last_sndbytes)
|
||||
transmitting = activity[0]
|
||||
self.max_snd_gain = activity[1]
|
||||
self.last_sndbytes = activity[2]
|
||||
|
||||
if transmitting and receiving:
|
||||
return 'both-'
|
||||
elif transmitting:
|
||||
return 'transmitting-'
|
||||
elif receiving:
|
||||
return 'receiving-'
|
||||
else:
|
||||
return 'idle-'
|
||||
|
||||
def is_network_active(self, bytes, max_gain, last_bytes):
|
||||
""" Determines if a network is active.
|
||||
|
||||
Determines if a network is active by looking at the
|
||||
number of bytes sent since the previous check. This method
|
||||
is generic, and can be used to determine activity in both
|
||||
the sending and receiving directions.
|
||||
|
||||
Returns:
|
||||
A tuple containing three elements:
|
||||
1) a boolean specifying if the network is active.
|
||||
2) an int specifying the maximum gain the network has had.
|
||||
3) an int specifying the last recorded number of bytes sent.
|
||||
|
||||
"""
|
||||
active = False
|
||||
if last_bytes == -1:
|
||||
last_bytes = bytes
|
||||
elif bytes > (last_bytes + float(max_gain / 20.0)):
|
||||
last_bytes = bytes
|
||||
active = True
|
||||
|
||||
gain = bytes - last_bytes
|
||||
if gain > max_gain:
|
||||
max_gain = gain
|
||||
return (active, max_gain, last_bytes)
|
||||
|
||||
|
||||
class TrayIconGUI:
|
||||
""" Base Tray Icon UI class.
|
||||
|
||||
Implements methods and variables used by both egg/StatusIcon
|
||||
tray icons.
|
||||
|
||||
"""
|
||||
def __init__(self, use_tray):
|
||||
menu = """
|
||||
<ui>
|
||||
<menubar name="Menubar">
|
||||
<menu action="Menu">
|
||||
<menu action="Connect">
|
||||
</menu>
|
||||
<separator/>
|
||||
<menuitem action="About"/>
|
||||
<menuitem action="Quit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>
|
||||
"""
|
||||
actions = [
|
||||
('Menu', None, 'Menu'),
|
||||
('Connect', gtk.STOCK_CONNECT, "Connect"),
|
||||
('About', gtk.STOCK_ABOUT, '_About...', None,
|
||||
'About wicd-tray-icon', self.on_about),
|
||||
('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
|
||||
self.on_quit),
|
||||
]
|
||||
actg = gtk.ActionGroup('Actions')
|
||||
actg.add_actions(actions)
|
||||
self.manager = gtk.UIManager()
|
||||
self.manager.insert_action_group(actg, 0)
|
||||
self.manager.add_ui_from_string(menu)
|
||||
self.menu = (self.manager.get_widget('/Menubar/Menu/About').
|
||||
props.parent)
|
||||
self.gui_win = None
|
||||
self.current_icon_path = None
|
||||
self.dbus_available = True
|
||||
self.use_tray = use_tray
|
||||
|
||||
def on_activate(self, data=None):
|
||||
""" Opens the wicd GUI. """
|
||||
try:
|
||||
self.toggle_wicd_gui()
|
||||
except dbus.DBusException:
|
||||
self.dbus_available = False
|
||||
gui.error(None, "Could not connect to wicd daemon. Unable to load GUI")
|
||||
|
||||
def on_quit(self, widget=None):
|
||||
""" Closes the tray icon. """
|
||||
sys.exit(0)
|
||||
|
||||
def on_about(self, data=None):
|
||||
""" Opens the About Dialog. """
|
||||
dialog = gtk.AboutDialog()
|
||||
dialog.set_name('Wicd Tray Icon')
|
||||
dialog.set_version('2.0')
|
||||
dialog.set_comments('An icon that shows your network connectivity')
|
||||
dialog.set_website('http://wicd.net')
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
def _add_item_to_menu(self, net_menu, lbl, type_,
|
||||
n_id, is_connecting, is_active):
|
||||
""" Add an item to the network list submenu. """
|
||||
def network_selected(widget, net_type, net_id):
|
||||
""" Callback method for a menu item selection. """
|
||||
if net_type == "__wired__":
|
||||
wired.ConnectWired()
|
||||
else:
|
||||
wireless.ConnectWireless(net_id)
|
||||
|
||||
item = NetworkMenuItem(lbl, is_active)
|
||||
image = gtk.Image()
|
||||
|
||||
if type_ == "__wired__":
|
||||
image.set_from_icon_name("network-wired", 2)
|
||||
else:
|
||||
pb = gtk.gdk.pixbuf_new_from_file_at_size(self._get_img(n_id),
|
||||
20, 20)
|
||||
image.set_from_pixbuf(pb)
|
||||
del pb
|
||||
item.set_image(image)
|
||||
del image
|
||||
item.connect("activate", network_selected, type_, n_id)
|
||||
net_menu.append(item)
|
||||
item.show()
|
||||
if is_connecting:
|
||||
item.set_sensitive(False)
|
||||
del item
|
||||
|
||||
def _get_img(self, net_id):
|
||||
""" Determines which image to use for the wireless entries. """
|
||||
def fix_strength(val, default):
|
||||
""" Assigns given strength to a default value if needed. """
|
||||
return val is not None and int(val) or default
|
||||
|
||||
def get_prop(prop):
|
||||
return wireless.GetWirelessProperty(net_id, prop)
|
||||
|
||||
strength = fix_strength(get_prop("quality"), -1)
|
||||
dbm_strength = fix_strength(get_prop('strength'), -100)
|
||||
|
||||
if daemon.GetWPADriver() == 'ralink legacy' or \
|
||||
daemon.GetSignalDisplayType() == 1:
|
||||
if dbm_strength >= -60:
|
||||
signal_img = 'signal-100.png'
|
||||
elif dbm_strength >= -70:
|
||||
signal_img = 'signal-75.png'
|
||||
elif dbm_strength >= -80:
|
||||
signal_img = 'signal-50.png'
|
||||
else:
|
||||
signal_img = 'signal-25.png'
|
||||
else:
|
||||
if strength > 75:
|
||||
signal_img = 'signal-100.png'
|
||||
elif strength > 50:
|
||||
signal_img = 'signal-75.png'
|
||||
elif strength > 25:
|
||||
signal_img = 'signal-50.png'
|
||||
else:
|
||||
signal_img = 'signal-25.png'
|
||||
return wpath.images + signal_img
|
||||
|
||||
def populate_network_menu(self, data=None):
|
||||
""" Populates the network list submenu. """
|
||||
def get_prop(net_id, prop):
|
||||
return wireless.GetWirelessProperty(net_id, prop)
|
||||
|
||||
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
|
||||
submenu = net_menuitem.get_submenu()
|
||||
self._clear_menu(submenu)
|
||||
|
||||
is_connecting = daemon.CheckIfConnecting()
|
||||
num_networks = wireless.GetNumberOfNetworks()
|
||||
[status, info] = daemon.GetConnectionStatus()
|
||||
|
||||
if wired.GetAlwaysShowWiredInterface() or \
|
||||
wired.CheckPluggedIn(True):
|
||||
if status == misc.WIRED:
|
||||
is_active = True
|
||||
else:
|
||||
is_active = False
|
||||
self._add_item_to_menu(submenu, "Wired Network", "__wired__",
|
||||
0, is_connecting, is_active)
|
||||
sep = gtk.SeparatorMenuItem()
|
||||
submenu.append(sep)
|
||||
sep.show()
|
||||
|
||||
if num_networks > 0:
|
||||
for x in range(0, num_networks):
|
||||
essid = get_prop(x, "essid")
|
||||
if status == misc.WIRELESS and info[1] == essid:
|
||||
is_active = True
|
||||
else:
|
||||
is_active = False
|
||||
self._add_item_to_menu(submenu, essid, "wifi", x,
|
||||
is_connecting, is_active)
|
||||
|
||||
net_menuitem.show()
|
||||
|
||||
def init_network_menu(self):
|
||||
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
|
||||
submenu = net_menuitem.get_submenu()
|
||||
self._clear_menu(submenu)
|
||||
|
||||
loading_item = gtk.MenuItem(language['scanning'] + "...")
|
||||
loading_item.set_sensitive(False)
|
||||
loading_item.show()
|
||||
submenu.append(loading_item)
|
||||
#net_menuitem.set_submenu(net_menu)
|
||||
net_menuitem.show()
|
||||
|
||||
def _clear_menu(self, menu):
|
||||
for item in menu.get_children():
|
||||
menu.remove(item)
|
||||
item.destroy()
|
||||
|
||||
def toggle_wicd_gui(self):
|
||||
""" Toggles the wicd GUI. """
|
||||
if not self.gui_win:
|
||||
self.gui_win = gui.appGui(dbus_manager)
|
||||
bus = dbus_manager.get_bus()
|
||||
bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
|
||||
'SendEndScanSignal',
|
||||
'org.wicd.daemon')
|
||||
bus.add_signal_receiver(self.gui_win.dbus_scan_started,
|
||||
'SendStartScanSignal',
|
||||
'org.wicd.daemon')
|
||||
bus.add_signal_receiver(self.gui_win.update_connect_buttons,
|
||||
'StatusChanged', 'org.wicd.daemon')
|
||||
elif not self.gui_win.is_visible:
|
||||
self.gui_win.show_win()
|
||||
else:
|
||||
self.gui_win.exit()
|
||||
return True
|
||||
|
||||
|
||||
class EggTrayIconGUI(TrayIconGUI):
|
||||
""" Tray Icon for gtk < 2.10.
|
||||
|
||||
Uses the deprecated egg.trayicon module to implement the tray icon.
|
||||
Since it relies on a deprecated module, this class is only used
|
||||
for machines running versions of GTK < 2.10.
|
||||
|
||||
"""
|
||||
def __init__(self, use_tray=True):
|
||||
"""Initializes the tray icon"""
|
||||
TrayIcon.TrayIconGUI.__init__(self, use_tray)
|
||||
self.use_tray = use_tray
|
||||
if not use_tray:
|
||||
self.toggle_wicd_gui()
|
||||
return
|
||||
|
||||
self.tooltip = gtk.Tooltips()
|
||||
self.eb = gtk.EventBox()
|
||||
self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
|
||||
self.pic = gtk.Image()
|
||||
self.tooltip.set_tip(self.eb, "Initializing wicd...")
|
||||
self.pic.set_from_file("images/no-signal.png")
|
||||
|
||||
self.eb.connect('button_press_event', self.tray_clicked)
|
||||
self.eb.add(self.pic)
|
||||
self.tray.add(self.eb)
|
||||
self.tray.show_all()
|
||||
|
||||
def tray_clicked(self, widget, event):
|
||||
""" Handles tray mouse click events. """
|
||||
if event.button == 1:
|
||||
self.toggle_wicd_gui()
|
||||
elif event.button == 3:
|
||||
self.populate_network_menu()
|
||||
self.menu.popup(None, None, None, event.button, event.time)
|
||||
|
||||
def set_from_file(self, val=None):
|
||||
""" Calls set_from_file on the gtk.Image for the tray icon. """
|
||||
if not self.use_tray: return
|
||||
self.pic.set_from_file(val)
|
||||
|
||||
def set_tooltip(self, val):
|
||||
""" Set the tooltip for this tray icon.
|
||||
|
||||
Sets the tooltip for the gtk.ToolTips associated with this
|
||||
tray icon.
|
||||
|
||||
"""
|
||||
if not self.use_tray: return
|
||||
self.tooltip.set_tip(self.eb, val)
|
||||
|
||||
|
||||
class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
|
||||
""" Class for creating the wicd tray icon on gtk > 2.10.
|
||||
|
||||
Uses gtk.StatusIcon to implement a tray icon.
|
||||
|
||||
"""
|
||||
def __init__(self, use_tray=True):
|
||||
TrayIcon.TrayIconGUI.__init__(self, use_tray)
|
||||
self.use_tray = use_tray
|
||||
if not use_tray:
|
||||
self.toggle_wicd_gui()
|
||||
return
|
||||
|
||||
gtk.StatusIcon.__init__(self)
|
||||
|
||||
self.current_icon_path = ''
|
||||
self.set_visible(True)
|
||||
self.connect('activate', self.on_activate)
|
||||
self.connect('popup-menu', self.on_popup_menu)
|
||||
self.set_from_file(wpath.images + "no-signal.png")
|
||||
self.set_tooltip("Initializing wicd...")
|
||||
|
||||
def on_popup_menu(self, status, button, timestamp):
|
||||
""" Opens the right click menu for the tray icon. """
|
||||
self.init_network_menu()
|
||||
wireless.Scan(reply_handler=self.populate_network_menu,
|
||||
error_handler=lambda x: x)
|
||||
self.menu.popup(None, None, None, button, timestamp)
|
||||
|
||||
def set_from_file(self, path = None):
|
||||
""" Sets a new tray icon picture. """
|
||||
if not self.use_tray: return
|
||||
if path != self.current_icon_path:
|
||||
self.current_icon_path = path
|
||||
gtk.StatusIcon.set_from_file(self, path)
|
||||
|
||||
|
||||
def usage():
|
||||
""" Print usage information. """
|
||||
print """
|
||||
wicd 1.50
|
||||
wireless (and wired) connection daemon front-end.
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
def setup_dbus():
|
||||
global bus, daemon, wireless, wired, config, dbus_manager
|
||||
|
||||
dbus_manager = DBusManager()
|
||||
try:
|
||||
dbus_manager.connect_to_dbus()
|
||||
except DBusException:
|
||||
print "Can't connect to the daemon, trying to start it automatically..."
|
||||
misc.PromptToStartDaemon()
|
||||
try:
|
||||
dbus_manager.connect_to_dbus()
|
||||
except DBusException:
|
||||
gui.error(None, "Could not connect to wicd's D-Bus interface. " +
|
||||
"Make sure the daemon is started.")
|
||||
sys.exit(1)
|
||||
dbus_ifaces = dbus_manager.get_dbus_ifaces()
|
||||
daemon = dbus_ifaces['daemon']
|
||||
wireless = dbus_ifaces['wireless']
|
||||
wired = dbus_ifaces['wired']
|
||||
config = dbus_ifaces['config']
|
||||
return True
|
||||
|
||||
def main(argv):
|
||||
""" The main frontend program.
|
||||
|
||||
Keyword arguments:
|
||||
argv -- The arguments passed to the script.
|
||||
|
||||
"""
|
||||
use_tray = True
|
||||
animate = True
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
|
||||
'no-animate'])
|
||||
except getopt.GetoptError:
|
||||
# Print help information and exit
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
for opt, a in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
usage()
|
||||
sys.exit(0)
|
||||
elif opt in ('-n', '--no-tray'):
|
||||
use_tray = False
|
||||
elif opt in ('-a', '--no-animate'):
|
||||
animate = False
|
||||
else:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
print 'Loading...'
|
||||
setup_dbus()
|
||||
|
||||
if not use_tray:
|
||||
the_gui = gui.appGui()
|
||||
the_gui.standalone = True
|
||||
mainloop = gobject.MainLoop()
|
||||
mainloop.run()
|
||||
sys.exit(0)
|
||||
|
||||
# Set up the tray icon GUI and backend
|
||||
tray_icon = TrayIcon(use_tray, animate)
|
||||
|
||||
# Check to see if wired profile chooser was called before icon
|
||||
# was launched (typically happens on startup or daemon restart).
|
||||
if daemon.GetNeedWiredProfileChooser():
|
||||
daemon.SetNeedWiredProfileChooser(False)
|
||||
tray_icon.icon_info.wired_profile_chooser()
|
||||
|
||||
bus = dbus_manager.get_bus()
|
||||
bus.add_signal_receiver(tray_icon.icon_info.wired_profile_chooser,
|
||||
'LaunchChooser', 'org.wicd.daemon')
|
||||
bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
|
||||
'StatusChanged', 'org.wicd.daemon')
|
||||
print 'Done.'
|
||||
|
||||
while 1:
|
||||
mainloop = gobject.MainLoop()
|
||||
try:
|
||||
mainloop.run()
|
||||
except DBusException:
|
||||
print 'Warning. Caught a D-Bus exception! Connection to daemon lost.'
|
||||
print 'Trying to reconnect...'
|
||||
sleep(10)
|
||||
try:
|
||||
setup_dbus()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
1359
wicd/wnettools.py
Normal file
1359
wicd/wnettools.py
Normal file
File diff suppressed because it is too large
Load Diff
31
wicd/wpath.py
Normal file
31
wicd/wpath.py
Normal file
@@ -0,0 +1,31 @@
|
||||
""" Path configuration and functions for the wicd daemon and gui clients.
|
||||
|
||||
chdir() -- Change directory to the location of the current file.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# The path containing the wpath.py file.
|
||||
current = os.path.dirname(os.path.realpath(__file__)) + '/'
|
||||
|
||||
# These paths can easily be modified to handle system wide installs, or
|
||||
# they can be left as is if all files remain with the source directory
|
||||
# layout.
|
||||
lib = current
|
||||
images = lib + 'images/'
|
||||
encryption = lib + 'encryption/templates/'
|
||||
bin = current
|
||||
etc = current + 'data/'
|
||||
networks = lib + 'encryption/configurations/'
|
||||
log = current + 'data/'
|
||||
|
||||
def chdir(file):
|
||||
"""Change directory to the location of the specified file.
|
||||
|
||||
Keyword arguments:
|
||||
file -- the file to switch to (usually __file__)
|
||||
|
||||
"""
|
||||
os.chdir(os.path.dirname(os.path.realpath(file)))
|
||||
|
||||
Reference in New Issue
Block a user