From: Fredrik Wendt Date: Tue, 27 Jul 2010 21:39:56 +0000 (+0100) Subject: refactored for reuse and enable testing - tests are currently broken X-Git-Url: http://git.maemo.org/git/?a=commitdiff_plain;h=c01516ed0781044a687bcca1b3923b6e1fd84583;p=wifi-assistant refactored for reuse and enable testing - tests are currently broken --- diff --git a/package/src/config-gui.py b/package/src/config-gui.py deleted file mode 100644 index 3148b55..0000000 --- a/package/src/config-gui.py +++ /dev/null @@ -1,205 +0,0 @@ -import gtk, hildon, gobject -from gnome import gconf -import webbrowser -import osso - -def _(str): - return str - -_gc = gconf.client_get_default() -prefix = '/apps/maemo/wbl/launch' -GCONF_KEY_URL = '/apps/maemo/wbl/url_to_open' -GCONF_KEY_POPUP = '/apps/maemo/wbl/popup' - -program = hildon.Program.get_instance() - -# Create the main window -win = hildon.StackableWindow() - -def launch_browser(url): - osso_context = osso.Context("org.maemo.touchsearch", "1.1", False) - osso_rpc = osso.Rpc(osso_context) - osso_rpc.rpc_run_with_defaults("osso_browser", "open_new_window", (url,)) - -def show_about(x): - dialog = gtk.Dialog('About', win) - - text = "I got tired of not being able to connect easily to networks guarded by a login page, " + \ - "so I created this app to scratch that itch. It's free to use, inspect, adapt and share, " + \ - "licencsed under a BSD type license.\nI hope you enjoy it!" - about_label = gtk.Label(text) - about_label.set_line_wrap(True) - dialog.vbox.add(about_label) - - dialog.add_button(_('File a bug'), 1) - dialog.add_button(_('Donate'), 2) - dialog.add_button(_('Close'), 3) - - dialog.show_all() - result = dialog.run() - dialog.hide() - - if result == 1: - launch_browser('http://wifi-assistant.garage.maemo.org/bugs/') - if result == 2: - launch_browser('http://wifi-assistant.garage.maemo.org/donate/') - - -def show_settings(x): - checkbox = hildon.CheckButton(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT) - checkbox.set_label('Show popup when connected to a new SSID') - checkbox.set_active(_gc.get_bool(GCONF_KEY_POPUP)) - - url_label = gtk.Label('URL to open when launching browser:') # IMPROVEMENT: caption? - url_label.set_alignment(0, 0.5) - url_label.set_padding(5, 5) - url_field = hildon.Entry(gtk.HILDON_SIZE_AUTO) - url_field.set_text(_gc.get_string(GCONF_KEY_URL)) - - dialog = gtk.Dialog('Settings', win) - dialog.vbox.set_homogeneous(False) - - dialog.vbox.add(checkbox) - dialog.vbox.add(url_label) - dialog.vbox.add(url_field) - - dialog.add_button(_('Cancel'), gtk.RESPONSE_CANCEL) - dialog.add_button(_('Save'), gtk.RESPONSE_YES) - - dialog.show_all() - result = dialog.run() - dialog.hide() - - if (result == gtk.RESPONSE_YES): - _gc.set_string(GCONF_KEY_URL, url_field.get_text()) - _gc.set_bool(GCONF_KEY_POPUP, checkbox.get_active()) - - -def create_menu(): - menu = hildon.AppMenu() - - settings = hildon.GtkButton(gtk.HILDON_SIZE_AUTO) - command_id = "Settings" - settings.set_label(command_id) - settings.connect("clicked", show_settings) - menu.append(settings) - - about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO) - command_id = "About" - about.set_label(command_id) - about.connect("clicked", show_about) - menu.append(about) - - menu.show_all() - return menu - -def create_ssid_model(): - store = gtk.ListStore(str, gobject.TYPE_BOOLEAN) - - entries = _gc.all_entries(prefix) - for entry in entries: - ssidName = entry.get_key()[len(prefix) + 1:] - launchBrowser = entry.get_value().get_bool() - store.append([ssidName, launchBrowser]) - print ssidName - print launchBrowser - - return store - -def edit_ssid(ssid, parent, model, iter): - dialog = gtk.Dialog(ssid, parent) - dialog.vbox.set_homogeneous(False) - - dialog.add_button(_('No'), gtk.RESPONSE_NO) - dialog.add_button(_('Yes'), gtk.RESPONSE_YES) - - label = gtk.Label(_('After being connected to ' + ssid + ' do you wish to launch a browser?')) - label.set_line_wrap(True) - label.set_justify(gtk.JUSTIFY_LEFT) - label.set_alignment(0, 0.5) - dialog.vbox.add(label) - - dialog.show_all() - result = dialog.run() - dialog.hide() - - launchBrowser = (result == gtk.RESPONSE_YES) - _gc.set_bool('/apps/maemo/wbl/launch/' + ssid, launchBrowser) - model.set(iter, 1, launchBrowser) - - -def create_ssid_view(): - model = create_ssid_model() - view = gtk.TreeView(model) - view.set_border_width(5) - - tvcolumn = gtk.TreeViewColumn('SSID', gtk.CellRendererText(), text = 0) - tvcolumn.set_expand(True) - view.append_column(tvcolumn) - - def boolean_func(column, cell, model, iter): - if model.get_value(iter, 1): - stock_id = 'gtk-yes' - else: - stock_id = 'gtk-no' - cell.set_property('stock-id', stock_id) - - view.insert_column_with_data_func(1, 'Launch', gtk.CellRendererPixbuf(), boolean_func) - - def row_activated(treeview, path, view_column): - model = treeview.get_model() - iter = model.get_iter(path) - ssid = model.get_value(iter, 0) - print ssid - edit_ssid(ssid, win, model, iter) - - view.connect('row-activated', row_activated) - view.set_search_column(0) - tvcolumn.set_sort_column_id(0) - - return view - -def create_table(): - table = gtk.Table(rows=10, columns=2) - table.set_col_spacings(5) - table.set_row_spacings(5) - table.set_border_width(5) - - row = 0 - entries = xrange(5) - for entry in entries: - def l(i): - if (i == 0): - return "" - return "x" + l(i-1) - - ssid = "SSID " + l(row) - ssid_label = gtk.Label(ssid) - ssid_label.set_alignment(0, 0.5) - table.attach(ssid_label, 0, 1, row, row+1, xoptions=gtk.FILL) - table.attach(gtk.Label("On"), 1, 2, row, row+1, xoptions=gtk.SHRINK) - row = row + 1 - - return table - -def main(): - win.set_title("Browser Launcher Configuration") - -# pannable_area = hildon.PannableArea() - - ssid_view = create_ssid_view() - -# pannable_area.add_with_viewport(ssid_view) - -# win.add(pannable_area) - win.add(ssid_view) - - win.set_app_menu(create_menu()) - - win.connect("destroy", gtk.main_quit, None) - - win.show_all() - gtk.main() - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/package/src/daemon.py b/package/src/daemon.py deleted file mode 100644 index 276e970..0000000 --- a/package/src/daemon.py +++ /dev/null @@ -1,58 +0,0 @@ -import gtk, hildon -from gnome import gconf -import webbrowser -import osso - -def _(str): - return str - -_gc = gconf.client_get_default() -parent = gtk.Window() - -def launch_browser(): - url = _gc.get_string('/apps/maemo/wbl/url_to_open') - osso_context = osso.Context("org.maemo.touchsearch", "1.1", False) - osso_rpc = osso.Rpc(osso_context) - osso_rpc.rpc_run_with_defaults("osso_browser", "open_new_window", (url,)) - -def show_decision_dialog(ssid): - dialog = gtk.Dialog(ssid, parent) - dialog.vbox.set_homogeneous(False) - - dialog.add_button(_('No'), gtk.RESPONSE_NO) - dialog.add_button(_('Yes'), gtk.RESPONSE_YES) - - label = gtk.Label(_('New network connection established - do you wish to launch a browser?')) - label.set_line_wrap(True) - #label.set_justify(gtk.JUSTIFY_LEFT) - #label.set_alignment(0, 0.5) - dialog.vbox.add(label) - - checkbox = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT) - checkbox.set_label(_('Remember this decision')) - checkbox.set_active(True) - dialog.vbox.add(checkbox) - - dialog.show_all() - result = dialog.run() - dialog.hide() - - launchBrowser = (result == gtk.RESPONSE_YES) - if (checkbox.get_active()): - _gc.set_bool('/apps/maemo/wbl/launch/' + ssid, launchBrowser) - - return launchBrowser - -def connection_established(ssid): - value = _gc.get_without_default('/apps/maemo/wbl/launch/' + ssid) - print value - if value is None: - if show_decision_dialog(ssid): - launch_browser() - return - - if value.get_bool(): - launch_browser() - -import sys -connection_established(sys.argv[1]) diff --git a/package/src/wifi_assistant/__init__.py b/package/src/wifi_assistant/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/package/src/wifi_assistant/config-gui.py b/package/src/wifi_assistant/config-gui.py new file mode 100644 index 0000000..aa8f9f2 --- /dev/null +++ b/package/src/wifi_assistant/config-gui.py @@ -0,0 +1,164 @@ +#!/usr/bin/python2.5 +import gtk, hildon + +from launcher import Launcher +from settings import Settings + +def _(str): + return str + +class ConfigGui(): + + def __init__(self, launcher, settings): + self._launcher = launcher + self._settings = settings + self._program = hildon.Program.get_instance() + self._win = hildon.StackableWindow() + + + def main(self): + self._win.set_title(_("Wifi Jail Breakout Assistant")) + self._win.add(self._create_ssid_view(self._settings.getLaunchSettings())) + self._win.set_app_menu(self._create_menu()) + self._win.connect("destroy", gtk.main_quit, None) + self._win.show_all() + gtk.main() + + + # FIXME: refactor out + def _launch_browser(self, url): + self._launcher.openUrl(url) + + + def _show_about(self, x): + dialog = gtk.Dialog(_('About'), self._win) + text = "I got tired of not being able to connect easily to networks guarded by a login page, " + \ + "so I created this app to scratch that itch. It's free to use, inspect, adapt and share, " + \ + "licencsed under a BSD type license.\nI hope you enjoy it!" + about_label = gtk.Label(_(text)) + about_label.set_line_wrap(True) + dialog.vbox.add(about_label) + + dialog.add_button(_('File a bug'), 1) + dialog.add_button(_('Donate'), 2) + dialog.add_button(_('Close'), 3) + + dialog.show_all() + result = dialog.run() + dialog.hide() + + if result == 1: + self._launcher.openUrl(_('http://wifi-assistant.garage.maemo.org/bugs/')) + if result == 2: + self._launcher.openUrl(_('http://wifi-assistant.garage.maemo.org/donate/')) + + + def _show_settings(self, x): + checkbox = hildon.CheckButton(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT) + checkbox.set_label(_('Show popup when connected to a new SSID')) + checkbox.set_active(self._settings.getUsePopup()) + + url_label = gtk.Label(_('URL to open when launching browser:')) # IMPROVEMENT: caption? + url_label.set_alignment(0, 0.5) + url_label.set_padding(5, 5) + url_field = hildon.Entry(gtk.HILDON_SIZE_AUTO) + url_field.set_text(self._settings.getUrlToOpen()) + + dialog = gtk.Dialog(_('Settings'), self._win) + dialog.vbox.set_homogeneous(False) + + dialog.vbox.add(checkbox) + dialog.vbox.add(url_label) + dialog.vbox.add(url_field) + + dialog.add_button(_('Cancel'), gtk.RESPONSE_CANCEL) + dialog.add_button(_('Save'), gtk.RESPONSE_YES) + + dialog.show_all() + result = dialog.run() + dialog.hide() + + if result == gtk.RESPONSE_YES: + self._settings.setUrlToOpen(url_field.get_text()) + self._settings.setUsePopup(checkbox.get_active()) + + + def _create_menu(self): + menu = hildon.AppMenu() + + about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO) + about.set_label(_("About")) + about.connect("clicked", self._show_about) + menu.append(about) + + settings = hildon.GtkButton(gtk.HILDON_SIZE_AUTO) + settings.set_label(_("Settings")) + settings.connect("clicked",self._show_settings) + menu.append(settings) + + menu.show_all() + return menu + + + def _edit_ssid(self, ssid, model, iter): + dialog = gtk.Dialog(ssid, self._win) + dialog.vbox.set_homogeneous(False) + + dialog.add_button(_('No'), gtk.RESPONSE_NO) + dialog.add_button(_('Yes'), gtk.RESPONSE_YES) + + label = gtk.Label(_('After being connected to ' + ssid + ' do you wish to launch a browser?')) #FIXME: l10n + label.set_line_wrap(True) + label.set_justify(gtk.JUSTIFY_LEFT) + label.set_alignment(0, 0.5) + dialog.vbox.add(label) + + dialog.show_all() + result = dialog.run() + dialog.hide() + + launchBrowser = (result == gtk.RESPONSE_YES) + self._settings.setLaunchSetting(ssid, launchBrowser) + model.set(iter, 1, launchBrowser) + + + def _create_ssid_view(self, model): +# view = hildon.GtkTreeView(gtk.HILDON_UI_MODE_NORMAL, model) +# view = hildon.GtkTreeView(gtk.HILDON_UI_MODE_NORMAL, model) + + if len(model) == 0: + return gtk.Label(_('There are no launch settings saved for any network')) + + view = gtk.TreeView(model) + view.set_border_width(5) + + tvcolumn = gtk.TreeViewColumn(_('SSID'), gtk.CellRendererText(), text = 0) + tvcolumn.set_expand(True) + view.append_column(tvcolumn) + + def boolean_func(column, cell, model, iter): + if model.get_value(iter, 1): + stock_id = 'gtk-yes' + else: + stock_id = 'gtk-no' + cell.set_property('stock-id', stock_id) + + view.insert_column_with_data_func(1, _('Launch'), gtk.CellRendererPixbuf(), boolean_func) + + view.connect('row-activated', self._row_activated) + view.set_search_column(0) + tvcolumn.set_sort_column_id(0) + + return view + + + def _row_activated(self, treeview, path, view_column): + model = treeview.get_model() + iter = model.get_iter(path) + ssid = model.get_value(iter, 0) + self._edit_ssid(ssid, model, iter) + + +if __name__ == "__main__": + gui = ConfigGui(Launcher(), Settings()) + gui.main() diff --git a/package/src/wifi_assistant/daemon.py b/package/src/wifi_assistant/daemon.py new file mode 100644 index 0000000..b9f04f7 --- /dev/null +++ b/package/src/wifi_assistant/daemon.py @@ -0,0 +1,109 @@ +#!/usr/bin/python2.5 +import gtk, hildon +import conic +import gobject + +from launcher import Launcher +from settings import Settings + +def _(str): + return str + +class Daemon(): + + def __init__(self, launcher, settings, parent_window): + self._settings = settings + self._parent = parent_window + self._launcher = launcher + self._popup = self._settings.getUsePopup() + + + def launch_browser(self): + url = self._settings.getUrlToOpen() + self._launcher.openUrl(url) + + + def show_decision_dialog(self, ssid): + if not self._popup: + return + + dialog = gtk.Dialog(ssid, parent) + dialog.vbox.set_homogeneous(False) + + dialog.add_button(_('No'), gtk.RESPONSE_NO) + dialog.add_button(_('Yes'), gtk.RESPONSE_YES) + + label = gtk.Label(_('New network connection established - do you wish to launch a browser?')) + label.set_line_wrap(True) + #label.set_justify(gtk.JUSTIFY_LEFT) + #label.set_alignment(0, 0.5) + dialog.vbox.add(label) + + checkbox = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT) + checkbox.set_label(_('Remember this decision')) + checkbox.set_active(True) + dialog.vbox.add(checkbox) + + dialog.show_all() + result = dialog.run() + dialog.hide() + + launchBrowser = (result == gtk.RESPONSE_YES) + if checkbox.get_active(): + self._settings.setLaunchSettings(ssid, launchBrowser) + + return launchBrowser + + + def connection_established(self, ssid): + value = self._settings.getLaunchSettings(ssid) + if value is None: + if self.show_decision_dialog(ssid): + self.launch_browser() + return + + if value.get_bool(): + self.launch_browser() + + + def _connection_cb(self, connection, event): + status = event.get_status() + if status == conic.STATUS_CONNECTED: + # assemble id > name dict + iap_id_to_name = {} + iaps = connection.get_all_iaps() + for iap in iaps: + iap_id = iap.get_id() + iap_name = iap.get_name() + iap_id_to_name[iap_id] = iap_name + + # get name of network + iap_id = event.get_iap_id() + iap_name = None + if (iap_id_to_name.has_key(iap_id)): + iap_name = iap_id_to_name[iap_id] + self.connection_established(iap_name) + + + def start(self): + self._connection = conic.Connection() + self._connection.connect("connection-event", self._connection_cb) + self._connection.set_property("automatic-connection-events", True) + self._settings.addUsePopupListener(self._activateCallback) + gtk.main() + + + def stop(self): + self._settings.removeUsePopupListener(self._activateCallback) + self._connection.set_property("automatic-connection-events", False) + + + def _activateCallback(self, gconfClient, id, gconfEntry, x): + self._popup = gconfEntry.get_value().get_bool() + + +if __name__ == "__main__": + d = Daemon(Launcher(), Settings(), gtk.Window()) + + d.start() + d.stop() diff --git a/package/src/wifi_assistant/launcher.py b/package/src/wifi_assistant/launcher.py new file mode 100644 index 0000000..f8dbb5d --- /dev/null +++ b/package/src/wifi_assistant/launcher.py @@ -0,0 +1,18 @@ +#!/usr/bin/python2.5 +from gnome import gconf +import osso + +class Launcher(): + + """Opens a URL in a browser.""" + + def __init__(self): + pass + + # ---- public API __________________________________________________________ + + def openUrl(self, url): + osso_context = osso.Context("org.maemo.touchsearch", "1.1", False) + osso_rpc = osso.Rpc(osso_context) + osso_rpc.rpc_run_with_defaults("osso_browser", "open_new_window", (url,)) + \ No newline at end of file diff --git a/package/src/wifi_assistant/settings.py b/package/src/wifi_assistant/settings.py new file mode 100644 index 0000000..d2a6653 --- /dev/null +++ b/package/src/wifi_assistant/settings.py @@ -0,0 +1,104 @@ +#!/usr/bin/python2.5 +from gnome import gconf +import gtk, gobject + +class Settings(): + + def __init__(self, gconf_root_dir='/apps/maemo/wifi-assistant'): + self._gc = gconf.client_get_default() + self._gconfRootDir = gconf_root_dir + self._gconfLaunchDirectory = gconf_root_dir + '/launch' + self._gconfPopupKey = gconf_root_dir + '/daemon' + self._gconfUrlToOpen = gconf_root_dir + '/url-to-open' + self._listeners = {} + + # ---- public API __________________________________________________________ + + def getLaunchSetting(self, ssid): + """Returns True or False to indicate that the user wants a browser + launched or not, otherwise None (the ssid is not recognized)""" + + value = self._gc.get_without_default(self._get_launch_key(ssid)) + if value is None: + return None + return value.get_bool() + + + def getLaunchSettings(self): + """Returns a ListStore with one Row per SSID""" + + store = gtk.ListStore(str, gobject.TYPE_BOOLEAN) + entries = self._gc.all_entries(self._gconfLaunchDirectory) + directoryPathLength = len(self._gconfLaunchDirectory) + 1 + for entry in entries: + ssidName = entry.get_key()[directoryPathLength:] + launchBrowser = entry.get_value().get_bool() + store.append([ssidName, launchBrowser]) + + return store + + + def setLaunchSetting(self, ssid, mode): + """Saves the setting for the specified ssid. mode is True or False""" + + self._gc.set_bool(self._get_launch_key(ssid), mode) + + + def deleteLaunchSetting(self, ssid): + """Removes a setting for the specified ssid.""" + + self._gc.unset(self._get_launch_key(ssid)) + + + def addUsePopupListener(self, callback): + """Registers a listener/callback to changes on Use Daemon setting""" + + if len(self._listeners) == 0: + self._gc.add_dir(self._gconfRootDir, gconf.CLIENT_PRELOAD_NONE) + ref_id = self._gc.notify_add(self._gconfPopupKey, callback) + self._listeners[callback] = ref_id + + + def removeUsePopupListener(self, callback): + """Unregisters the listener/callback""" + + if (self._listeners.has_key(callback)): + ref_id = self._listeners.pop(callback) + self._gc.notify_remove(ref_id) + + if len(self._listeners) == 0: + self._gc.remove_dir(self._gconfRootDir) + + + def getUsePopup(self): + """Tells whether to use the daemon or not.""" + + return self._gc.get_bool(self._gconfPopupKey) is True + + + def setUsePopup(self, mode): + """mode is either True or False.""" + + self._gc.set_bool(self._gconfPopupKey, mode) + + + def getUrlToOpen(self): + """Returns the URL to open when launching a browser""" + + return self._gc.get_string(self._gconfUrlToOpen) or 'http://wifi-assistant.garage.maemo.org/ping/' + + + def setUrlToOpen(self, url): + """Sets the URL to open when launching a browser""" + + self._gc.set_string(self._gconfUrlToOpen, url) + + + # ---- private _____________________________________________________________ + + def _get_launch_key(self, ssid): + return self._gconfLaunchDirectory + '/' + ssid + + +if __name__ == "__main__": + print Settings().getLaunchSetting('limbergwendt2') diff --git a/package/test/unit/__init__.py b/package/test/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/package/test/unit/test_settings.py b/package/test/unit/test_settings.py new file mode 100644 index 0000000..593e880 --- /dev/null +++ b/package/test/unit/test_settings.py @@ -0,0 +1,71 @@ +from gnome import gconf +from wifi_assistant.settings import Settings +import unittest + +ssid = 'MyFoneraNetwork' + +callback_value = None + +class TestSettings(unittest.TestCase): + + def setUp(self): + self.gconf_dir = "/apps/unit_tests" + self.testee = Settings(self.gconf_dir) + self.gc = gconf.client_get_default() + + + # clear gconf + all_entries = self.gc.all_entries(self.gconf_dir) + for entry in all_entries: + self.gc.unset(entry.get_key()) + self.gc.suggest_sync() + all_entries = self.gc.all_entries(self.gconf_dir) + # TODO: missing from python bindnings: self.gc.recursive_unset(self.gconf_dir) + assert len(all_entries) == 0 + + + def test_normal_cycle(self): + #empty to start with - ssid unknown + assert self.testee.getLaunchSetting(ssid) == None + + # set to True - launch browser + self.testee.setLaunchSetting(ssid, True) + assert self.testee.getLaunchSetting(ssid) == True + + # changes to False + self.testee.setLaunchSetting(ssid, False) + assert self.testee.getLaunchSetting(ssid) == False + + # removes - neighbour with open WLAN moves out + self.testee.deleteLaunchSetting(ssid) + assert self.testee.getLaunchSetting(ssid) == None + + + def test_auto_popup_cycle(self): + self.testee.setUseDaemon(True) + assert self.testee.getUseDaemon() == True + + self.testee.setUseDaemon(False) + assert self.testee.getUseDaemon() == False + + + def test_url_to_open_cycle(self): + google = "http://www.google.com/" + yahoo = "http://www.yahoo.com/" + + self.testee.setUrlToOpen(google) + value = self.testee.getUrlToOpen() + assert google == value + + self.testee.setUrlToOpen(yahoo) + value = self.testee.getUrlToOpen() + assert yahoo == value + + def test_default_url_points_to_maemo_org(self): + self.gc.unset(self.testee._gconfUrlToOpen) + value = self.testee.getUrlToOpen() + assert "maemo.org" in value + + +if __name__ == '__main__': + unittest.main()