From 7e2516ca002973e1bdbeadbc179b18ff5aee9d3d Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 20:03:06 +0100 Subject: [PATCH 01/14] Snapshot 8c89bfaed7. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 35554212..e8f21b67 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +Snapshot 8c89bfaed7 + * #4503: Do some standard Tubes boilerplate in sugar.presence, so activities don't have to (smcv) * #4428 Revert to the trial-3 frame behavior (marco) From b004585cc5bf3bf56ae8e1d995a5c4e67013e75b Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 18 Oct 2007 22:22:07 +0200 Subject: [PATCH 02/14] Wep key combo by dcbw --- NEWS | 2 + shell/hardware/keydialog.py | 137 +++++++++++++++++++++++++++--------- 2 files changed, 104 insertions(+), 35 deletions(-) diff --git a/NEWS b/NEWS index e8f21b67..8c31a979 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* Add wep type combo. (dcbw) + Snapshot 8c89bfaed7 * #4503: Do some standard Tubes boilerplate in sugar.presence, so activities diff --git a/shell/hardware/keydialog.py b/shell/hardware/keydialog.py index 6b5976c3..d336ab9c 100644 --- a/shell/hardware/keydialog.py +++ b/shell/hardware/keydialog.py @@ -47,8 +47,8 @@ IW_AUTH_CIPHER_TKIP = 0x00000004 IW_AUTH_CIPHER_CCMP = 0x00000008 IW_AUTH_CIPHER_WEP104 = 0x00000010 -IW_AUTH_KEY_MGMT_802_1X = 0x1 -IW_AUTH_KEY_MGMT_PSK = 0x2 +IW_AUTH_KEY_MGMT_802_1X = 0x1 +IW_AUTH_KEY_MGMT_PSK = 0x2 def string_is_hex(key): is_hex = True @@ -95,6 +95,12 @@ class KeyDialog(gtk.Dialog): " the wireless network '%s'." % net.get_ssid()) self.vbox.pack_start(label) + self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, + gtk.STOCK_OK, gtk.RESPONSE_OK) + self.set_default_response(gtk.RESPONSE_OK) + self.set_has_separator(True) + + def add_key_entry(self): self._entry = gtk.Entry() #self._entry.props.visibility = False self._entry.connect('changed', self._update_response_sensitivity) @@ -103,14 +109,8 @@ class KeyDialog(gtk.Dialog): self.vbox.set_spacing(6) self.vbox.show_all() - self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OK, gtk.RESPONSE_OK) - self.set_default_response(gtk.RESPONSE_OK) - self._update_response_sensitivity() - self._entry.grab_focus() - self.set_has_separator(True) def _entry_activate_cb(self, entry): self.response(gtk.RESPONSE_OK) @@ -124,39 +124,70 @@ class KeyDialog(gtk.Dialog): def get_callbacks(self): return (self._async_cb, self._async_err_cb) +WEP_PASSPHRASE = 1 +WEP_HEX = 2 +WEP_ASCII = 3 + class WEPKeyDialog(KeyDialog): def __init__(self, net, async_cb, async_err_cb): KeyDialog.__init__(self, net, async_cb, async_err_cb) - self.store = gtk.ListStore(str, int) - self.store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM]) - self.store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY]) + # WEP key type + self.key_store = gtk.ListStore(str, int) + self.key_store.append(["Passphrase (128-bit)", WEP_PASSPHRASE]) + self.key_store.append(["Hex (40/128-bit)", WEP_HEX]) + self.key_store.append(["ASCII (40/128-bit)", WEP_ASCII]) - self.combo = gtk.ComboBox(self.store) + self.key_combo = gtk.ComboBox(self.key_store) cell = gtk.CellRendererText() - self.combo.pack_start(cell, True) - self.combo.add_attribute(cell, 'text', 0) - self.combo.set_active(0) + self.key_combo.pack_start(cell, True) + self.key_combo.add_attribute(cell, 'text', 0) + self.key_combo.set_active(0) + self.key_combo.connect('changed', self._key_combo_changed_cb) - self.hbox = gtk.HBox() - self.hbox.pack_start(gtk.Label(_("Authentication Type:"))) - self.hbox.pack_start(self.combo) - self.hbox.show_all() + hbox = gtk.HBox() + hbox.pack_start(gtk.Label(_("Key Type:"))) + hbox.pack_start(self.key_combo) + hbox.show_all() + self.vbox.pack_start(hbox) - self.vbox.pack_start(self.hbox) + # Key entry field + self.add_key_entry() - def create_security(self): + # WEP authentication mode + self.auth_store = gtk.ListStore(str, int) + self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM]) + self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY]) + + self.auth_combo = gtk.ComboBox(self.auth_store) + cell = gtk.CellRendererText() + self.auth_combo.pack_start(cell, True) + self.auth_combo.add_attribute(cell, 'text', 0) + self.auth_combo.set_active(0) + + hbox = gtk.HBox() + hbox.pack_start(gtk.Label(_("Authentication Type:"))) + hbox.pack_start(self.auth_combo) + hbox.show_all() + + self.vbox.pack_start(hbox) + + def _key_combo_changed_cb(self, widget): + self._update_response_sensitivity() + + def _get_security(self): key = self._entry.get_text() - if key.startswith('$:'): - key = key[2:] - elif key.startswith('s:') and ((len(key) - 2) in [5, 13]): - key = string_to_hex(key[2:]) - else: - key = hash_passphrase(key) + it = self.key_combo.get_active_iter() + (key_type, ) = self.key_store.get(it, 1) - it = self.combo.get_active_iter() - (auth_alg, ) = self.store.get(it, 1) + if key_type == WEP_PASSPHRASE: + key = hash_passphrase(key) + elif key_type == WEP_ASCII: + key = string_to_hex(key) + + it = self.auth_combo.get_active_iter() + (auth_alg, ) = self.auth_store.get(it, 1) we_cipher = None if len(key) == 26: @@ -164,17 +195,43 @@ class WEPKeyDialog(KeyDialog): elif len(key) == 10: we_cipher = IW_AUTH_CIPHER_WEP40 + return (we_cipher, key, auth_alg) + + def print_security(self): + (we_cipher, key, auth_alg) = self._get_security() + print "Cipher: %d" % we_cipher + print "Key: %s" % key + print "Auth: %d" % auth_alg + + def create_security(self): + (we_cipher, key, auth_alg) = self._get_security() from nminfo import Security return Security.new_from_args(we_cipher, (key, auth_alg)) def _update_response_sensitivity(self, ignored=None): - # As the md5 passphrase can be of any length and has no indicator, we - # cannot check for the validity of the input. - self.set_response_sensitive(gtk.RESPONSE_OK, True) + key = self._entry.get_text() + it = self.key_combo.get_active_iter() + (key_type, ) = self.key_store.get(it, 1) + + valid = False + if key_type == WEP_PASSPHRASE: + # As the md5 passphrase can be of any length and has no indicator, + # we cannot check for the validity of the input. + if len(key) > 0: + valid = True + elif key_type == WEP_ASCII: + if len(key) == 5 or len(key) == 13: + valid = string_is_ascii(key) + elif key_type == WEP_HEX: + if len(key) == 10 or len(key) == 26: + valid = string_is_hex(key) + + self.set_response_sensitive(gtk.RESPONSE_OK, valid) class WPAKeyDialog(KeyDialog): def __init__(self, net, async_cb, async_err_cb): KeyDialog.__init__(self, net, async_cb, async_err_cb) + self.add_key_entry() self.store = gtk.ListStore(str, int) self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO]) @@ -196,7 +253,7 @@ class WPAKeyDialog(KeyDialog): self.vbox.pack_start(self.hbox) - def create_security(self): + def _get_security(self): ssid = self.get_network().get_ssid() key = self._entry.get_text() is_hex = string_is_hex(key) @@ -229,8 +286,18 @@ class WPAKeyDialog(KeyDialog): if caps & NM_802_11_CAP_PROTO_WPA2: wpa_ver = IW_AUTH_WPA_VERSION_WPA2 + return (we_cipher, real_key, wpa_ver) + + def print_security(self): + (we_cipher, key, wpa_ver) = self._get_security() + print "Cipher: %d" % we_cipher + print "Key: %s" % key + print "WPA Ver: %d" % wpa_ver + + def create_security(self): + (we_cipher, key, wpa_ver) = self._get_security() from nminfo import Security - return Security.new_from_args(we_cipher, (real_key, wpa_ver, IW_AUTH_KEY_MGMT_PSK)) + return Security.new_from_args(we_cipher, (key, wpa_ver, IW_AUTH_KEY_MGMT_PSK)) def _update_response_sensitivity(self, ignored=None): key = self._entry.get_text() @@ -269,7 +336,7 @@ class FakeNet(object): def response_cb(widget, response_id): if response_id == gtk.RESPONSE_OK: - print dialog.get_options() + print dialog.print_security() else: print "canceled" widget.hide() From e8926c78447017671411dc00fe3c42a1c2947928 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 21:22:13 +0100 Subject: [PATCH 03/14] Update POTFILES.in --- po/POTFILES.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index c71aa55b..f5e3c8f2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -12,3 +12,8 @@ shell/view/devices/network/wireless.py shell/view/frame/activitybutton.py shell/view/frame/zoomtoolbar.py lib/sugar/activity/activity.py +lib/sugar/graphics/alert.py +lib/sugar/graphics/objectchooser.py +services/shell/objecttypeservice.py +shell/controlpanel/control.py +shell/view/devices/network/mesh.py From 335e5c89d007272ad388bd3aa9900fd66f6eee7b Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 21:24:24 +0100 Subject: [PATCH 04/14] Check in the .pot file --- po/sugar.pot | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 po/sugar.pot diff --git a/po/sugar.pot b/po/sugar.pot new file mode 100644 index 00000000..b4590466 --- /dev/null +++ b/po/sugar.pot @@ -0,0 +1,400 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-10-30 21:23+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../shell/intro/intro.py:67 +msgid "Name:" +msgstr "" + +#: ../shell/intro/intro.py:96 +msgid "Click to change color:" +msgstr "" + +#: ../shell/intro/intro.py:146 +msgid "Back" +msgstr "" + +#: ../shell/intro/intro.py:160 +msgid "Done" +msgstr "" + +#: ../shell/intro/intro.py:163 +msgid "Next" +msgstr "" + +#: ../shell/view/BuddyMenu.py:83 +msgid "Remove friend" +msgstr "" + +#: ../shell/view/BuddyMenu.py:86 +msgid "Make friend" +msgstr "" + +#: ../shell/view/BuddyMenu.py:92 +msgid "Invite" +msgstr "" + +#: ../shell/view/clipboardmenu.py:59 ../shell/view/frame/activitybutton.py:58 +msgid "Remove" +msgstr "" + +#: ../shell/view/clipboardmenu.py:64 +msgid "Open" +msgstr "" + +#. self._stop_item = MenuItem(_('Stop download'), 'stock-close') +#. TODO: Implement stopping downloads +#. self._stop_item.connect('activate', self._stop_item_activate_cb) +#. self.append_menu_item(self._stop_item) +#: ../shell/view/clipboardmenu.py:74 +msgid "Add to journal" +msgstr "" + +#: ../shell/view/clipboardmenu.py:200 +#, python-format +msgid "Clipboard object: %s." +msgstr "" + +#: ../shell/hardware/keydialog.py:149 +msgid "Key Type:" +msgstr "" + +#: ../shell/hardware/keydialog.py:169 +msgid "Authentication Type:" +msgstr "" + +#: ../shell/hardware/keydialog.py:250 +msgid "Encryption Type:" +msgstr "" + +#: ../shell/view/home/activitiesdonut.py:90 +msgid "Starting..." +msgstr "" + +#: ../shell/view/home/activitiesdonut.py:104 +msgid "Resume" +msgstr "" + +#: ../shell/view/home/activitiesdonut.py:111 +#: ../lib/sugar/activity/activity.py:124 +msgid "Stop" +msgstr "" + +#: ../shell/view/Shell.py:264 +msgid "Screenshot" +msgstr "" + +#: ../shell/view/home/HomeBox.py:157 +msgid "Reboot" +msgstr "" + +#: ../shell/view/home/HomeBox.py:162 +msgid "Shutdown" +msgstr "" + +#: ../shell/view/home/HomeBox.py:168 +msgid "Register" +msgstr "" + +#. Only show disconnect when there's a mesh device, because mesh takes +#. priority over the normal wireless device. NM doesn't have a "disconnect" +#. method for a device either (for various reasons) so this doesn't +#. have a good mapping +#: ../shell/view/home/MeshBox.py:87 ../shell/view/home/MeshBox.py:186 +#: ../shell/view/devices/network/wireless.py:113 +#: ../shell/view/devices/network/mesh.py:83 +msgid "Disconnect..." +msgstr "" + +#: ../shell/view/home/MeshBox.py:184 ../shell/view/devices/network/mesh.py:37 +#: ../shell/view/devices/network/mesh.py:62 +#: ../shell/view/devices/network/mesh.py:66 +msgid "Mesh Network" +msgstr "" + +#: ../shell/view/devices/battery.py:38 +msgid "My Battery life" +msgstr "" + +#: ../shell/view/devices/battery.py:94 +msgid "Battery charging" +msgstr "" + +#: ../shell/view/devices/battery.py:96 +msgid "Battery discharging" +msgstr "" + +#: ../shell/view/devices/battery.py:98 +msgid "Battery fully charged" +msgstr "" + +#: ../shell/view/devices/network/wireless.py:61 +msgid "Disconnected" +msgstr "" + +#: ../shell/view/devices/network/wireless.py:131 +msgid "Channel" +msgstr "" + +#: ../shell/view/frame/zoomtoolbar.py:42 +msgid "Neighborhood" +msgstr "" + +#: ../shell/view/frame/zoomtoolbar.py:54 +msgid "Group" +msgstr "" + +#: ../shell/view/frame/zoomtoolbar.py:66 +msgid "Home" +msgstr "" + +#: ../shell/view/frame/zoomtoolbar.py:78 +msgid "Activity" +msgstr "" + +#: ../lib/sugar/activity/activity.py:107 +msgid "Share with:" +msgstr "" + +#: ../lib/sugar/activity/activity.py:109 +msgid "Private" +msgstr "" + +#: ../lib/sugar/activity/activity.py:110 +msgid "My Neighborhood" +msgstr "" + +#: ../lib/sugar/activity/activity.py:118 +msgid "Keep" +msgstr "" + +#: ../lib/sugar/activity/activity.py:237 +msgid "Undo" +msgstr "" + +#: ../lib/sugar/activity/activity.py:242 +msgid "Redo" +msgstr "" + +#: ../lib/sugar/activity/activity.py:252 +msgid "Copy" +msgstr "" + +#: ../lib/sugar/activity/activity.py:257 +msgid "Paste" +msgstr "" + +#: ../lib/sugar/activity/activity.py:445 +#, python-format +msgid "%s Activity" +msgstr "" + +#: ../lib/sugar/graphics/alert.py:164 ../lib/sugar/graphics/alert.py:206 +msgid "Cancel" +msgstr "" + +#: ../lib/sugar/graphics/alert.py:168 +msgid "Ok" +msgstr "" + +#: ../lib/sugar/graphics/alert.py:216 +msgid "Continue" +msgstr "" + +#: ../lib/sugar/graphics/alert.py:244 +msgid "OK" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:175 +#, python-format +msgid "%d year" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:175 +#, python-format +msgid "%d years" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:176 +#, python-format +msgid "%d month" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:176 +#, python-format +msgid "%d months" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:177 +#, python-format +msgid "%d week" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:177 +#, python-format +msgid "%d weeks" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:178 +#, python-format +msgid "%d day" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:178 +#, python-format +msgid "%d days" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:179 +#, python-format +msgid "%d hour" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:179 +#, python-format +msgid "%d hours" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:180 +#, python-format +msgid "%d minute" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:180 +#, python-format +msgid "%d minutes" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:181 +#, python-format +msgid "%d second" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:181 +#, python-format +msgid "%d seconds" +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:191 +msgid " and " +msgstr "" + +#: ../lib/sugar/graphics/objectchooser.py:193 +msgid ", " +msgstr "" + +#: ../services/shell/objecttypeservice.py:37 +msgid "Text" +msgstr "" + +#: ../services/shell/objecttypeservice.py:43 +msgid "Image" +msgstr "" + +#: ../services/shell/objecttypeservice.py:46 +msgid "Audio" +msgstr "" + +#: ../services/shell/objecttypeservice.py:49 +msgid "Video" +msgstr "" + +#: ../services/shell/objecttypeservice.py:52 +msgid "Etoys project" +msgstr "" + +#: ../services/shell/objecttypeservice.py:56 +msgid "Link" +msgstr "" + +#: ../shell/controlpanel/control.py:254 +msgid "Error in specified color modifiers." +msgstr "" + +#: ../shell/controlpanel/control.py:257 +msgid "Error in specified colors." +msgstr "" + +#: ../shell/controlpanel/control.py:306 +msgid "Error in specified radio argument use on/off." +msgstr "" + +#: ../shell/controlpanel/control.py:323 ../shell/controlpanel/control.py:325 +#, python-format +msgid "get_timezone: %s" +msgstr "" + +#: ../shell/controlpanel/control.py:331 +msgid "Error in reading timezone" +msgstr "" + +#: ../shell/controlpanel/control.py:344 +#, python-format +msgid "Error copying timezone (from %s): %s" +msgstr "" + +#: ../shell/controlpanel/control.py:349 +#, python-format +msgid "Changing permission of timezone: %s" +msgstr "" + +#: ../shell/controlpanel/control.py:360 +msgid "Error timezone does not exist." +msgstr "" + +#: ../shell/controlpanel/control.py:379 +#, python-format +msgid "Could not access %s" +msgstr "" + +#: ../shell/controlpanel/control.py:415 +#, python-format +msgid "Language for code=%s could not be determined." +msgstr "" + +#: ../shell/controlpanel/control.py:424 +#, python-format +msgid "Sorry I do not speak '%s'." +msgstr "" + +#: ../shell/view/devices/network/mesh.py:105 +msgid "Connected to a School Mesh Portal" +msgstr "" + +#: ../shell/view/devices/network/mesh.py:107 +msgid "Looking for a School Mesh Portal..." +msgstr "" + +#: ../shell/view/devices/network/mesh.py:110 +msgid "Connected to an XO Mesh Portal" +msgstr "" + +#: ../shell/view/devices/network/mesh.py:112 +msgid "Looking for an XO Mesh Portal..." +msgstr "" + +#: ../shell/view/devices/network/mesh.py:115 +msgid "Connected to a Simple Mesh" +msgstr "" + +#: ../shell/view/devices/network/mesh.py:117 +msgid "Starting a Simple Mesh" +msgstr "" + +#: ../shell/view/devices/network/mesh.py:124 +msgid "Unknown Mesh" +msgstr "" From ca3c990dc12522d3305db27f1e3d2ad8922572f5 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 23:22:14 +0100 Subject: [PATCH 05/14] Handle missing TakeScreenshot method gracefully --- NEWS | 1 + shell/view/Shell.py | 5 ++++- shell/view/keyhandler.py | 22 ---------------------- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/NEWS b/NEWS index 8c31a979..a505c626 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* #4517 Do not require a TakeScreenshot method on the dbus service (marco) * Add wep type combo. (dcbw) Snapshot 8c89bfaed7 diff --git a/shell/view/Shell.py b/shell/view/Shell.py index 541fb2e5..c5c48676 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -172,7 +172,10 @@ class Shell(gobject.GObject): home_model = self._model.get_home() activity = home_model.get_active_activity() if activity: - activity.get_service().TakeScreenshot() + try: + activity.get_service().TakeScreenshot(timeout=1.0) + except dbus.DBusException, e: + logging.debug('ignoring error raised by TakeScreenshot(): %s', e) def set_zoom_level(self, level): if level == self._zoom_level: diff --git a/shell/view/keyhandler.py b/shell/view/keyhandler.py index 768b6c30..26a9fd5c 100644 --- a/shell/view/keyhandler.py +++ b/shell/view/keyhandler.py @@ -71,8 +71,6 @@ class KeyHandler(object): self._key_grabber = KeyGrabber() self._key_grabber.connect('key-pressed', self._key_pressed_cb) - self._key_grabber.connect('key-released', - self._key_released_cb) for key in _actions_table.keys(): self._key_grabber.grab(key) @@ -197,23 +195,3 @@ class KeyHandler(object): return True return False - - def _key_released_cb(self, grabber, keycode, state): - if self._keycode_pressed == keycode: - self._keycode_pressed = 0 - - if self._keystate_pressed == state: - self._keystate_pressed = 0 - - if not self._keycode_pressed and not self._keystate_pressed and \ - self._key_pressed: - gtk.gdk.keyboard_ungrab(time=0L) - - if self._key_pressed == 'f': - self._shell.get_frame().notify_key_release() - elif self._key_pressed == '0x93': - self._shell.get_frame().notify_key_release() - - return True - - return False From 5732433d3e055b98a04b7800890af045b43930fc Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 23:38:48 +0100 Subject: [PATCH 06/14] Setup the activity root with a tmp and a data dir. Save DS files in data (since tmp will be on tmpfs in rainbow) --- lib/sugar/activity/activity.py | 2 +- lib/sugar/activity/activityfactory.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/sugar/activity/activity.py b/lib/sugar/activity/activity.py index 14cadd76..55000f3b 100644 --- a/lib/sugar/activity/activity.py +++ b/lib/sugar/activity/activity.py @@ -683,7 +683,7 @@ class Activity(Window, gtk.Container): if self._jobject.file_path: self.write_file(self._jobject.file_path) else: - file_path = os.path.join(self.get_activity_root(), 'tmp', + file_path = os.path.join(self.get_activity_root(), 'data', '%i' % time.time()) self.write_file(file_path) self._owns_file = True diff --git a/lib/sugar/activity/activityfactory.py b/lib/sugar/activity/activityfactory.py index 39ebebc4..cd75edd2 100644 --- a/lib/sugar/activity/activityfactory.py +++ b/lib/sugar/activity/activityfactory.py @@ -79,7 +79,16 @@ def get_environment(activity): environ = os.environ.copy() bin_path = os.path.join(activity.path, 'bin') + activity_root = env.get_profile_path(activity.bundle_id) + if not os.path.exists(activity_root): + os.mkdir(activity_root) + + data_dir = os.path.join(activity_root, 'data') + os.mkdir(data_dir) + + tmp_dir = os.path.join(activity_root, 'tmp') + os.mkdir(tmp_dir) environ['SUGAR_BUNDLE_PATH'] = activity.path environ['SUGAR_ACTIVITY_ROOT'] = activity_root From dfb1787cd401f6c80eba26e29709c9a4a4f5f75c Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 23:43:42 +0100 Subject: [PATCH 07/14] Use a timeout of 2 seconds for TakeScreenshot to make debugging easier. --- shell/view/Shell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/view/Shell.py b/shell/view/Shell.py index c5c48676..a7005873 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -173,9 +173,9 @@ class Shell(gobject.GObject): activity = home_model.get_active_activity() if activity: try: - activity.get_service().TakeScreenshot(timeout=1.0) + activity.get_service().TakeScreenshot(timeout=2.0) except dbus.DBusException, e: - logging.debug('ignoring error raised by TakeScreenshot(): %s', e) + logging.debug('Error raised by TakeScreenshot(): %s', e) def set_zoom_level(self, level): if level == self._zoom_level: From 63d88df04012ee923cce24905f5f914cae3b9c31 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 23:51:36 +0100 Subject: [PATCH 08/14] Fix distcheck --- po/POTFILES.in | 1 - po/sugar.pot | 28 +------ services/shell/objecttypeservice.py | 125 ---------------------------- 3 files changed, 2 insertions(+), 152 deletions(-) delete mode 100644 services/shell/objecttypeservice.py diff --git a/po/POTFILES.in b/po/POTFILES.in index f5e3c8f2..aafd1e87 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,6 +14,5 @@ shell/view/frame/zoomtoolbar.py lib/sugar/activity/activity.py lib/sugar/graphics/alert.py lib/sugar/graphics/objectchooser.py -services/shell/objecttypeservice.py shell/controlpanel/control.py shell/view/devices/network/mesh.py diff --git a/po/sugar.pot b/po/sugar.pot index b4590466..3cd5557e 100644 --- a/po/sugar.pot +++ b/po/sugar.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-30 21:23+0100\n" +"POT-Creation-Date: 2007-10-30 23:51+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -94,7 +94,7 @@ msgstr "" msgid "Stop" msgstr "" -#: ../shell/view/Shell.py:264 +#: ../shell/view/Shell.py:267 msgid "Screenshot" msgstr "" @@ -297,30 +297,6 @@ msgstr "" msgid ", " msgstr "" -#: ../services/shell/objecttypeservice.py:37 -msgid "Text" -msgstr "" - -#: ../services/shell/objecttypeservice.py:43 -msgid "Image" -msgstr "" - -#: ../services/shell/objecttypeservice.py:46 -msgid "Audio" -msgstr "" - -#: ../services/shell/objecttypeservice.py:49 -msgid "Video" -msgstr "" - -#: ../services/shell/objecttypeservice.py:52 -msgid "Etoys project" -msgstr "" - -#: ../services/shell/objecttypeservice.py:56 -msgid "Link" -msgstr "" - #: ../shell/controlpanel/control.py:254 msgid "Error in specified color modifiers." msgstr "" diff --git a/services/shell/objecttypeservice.py b/services/shell/objecttypeservice.py deleted file mode 100644 index c4910f78..00000000 --- a/services/shell/objecttypeservice.py +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# 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, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import dbus -import dbus.service -import gnomevfs -import gtk - -from gettext import gettext as _ - -import bundleregistry - -_REGISTRY_IFACE = "org.laptop.ObjectTypeRegistry" -_REGISTRY_PATH = "/org/laptop/ObjectTypeRegistry" - -class ObjectTypeRegistry(dbus.service.Object): - def __init__(self): - bus = dbus.SessionBus() - bus_name = dbus.service.BusName(_REGISTRY_IFACE, bus=bus) - dbus.service.Object.__init__(self, bus_name, _REGISTRY_PATH) - - self._types = {} - - self._add_primitive('Text', _('Text'), 'text-x-generic', - ['text/plain', 'text/rtf', 'application/pdf', - 'application/x-pdf', 'text/html', - 'application/vnd.oasis.opendocument.text', - 'application/rtf', 'text/rtf']) - - self._add_primitive('Image', _('Image'), 'image-x-generic', - ['image/png', 'image/gif', 'image/jpeg']) - - self._add_primitive('Audio', _('Audio'), 'audio-x-generic', - ['audio/ogg', 'audio/x-wav', 'audio/wav']) - - self._add_primitive('Video', _('Video'), 'video-x-generic', - ['video/ogg', 'application/ogg']) - - self._add_primitive('Etoys project', _('Etoys project'), - 'application-x-squeak-project', - ['application/x-squeak-project']) - - self._add_primitive('Link', _('Link'), - 'text-uri-list', - ['text/x-moz-url', 'text/uri-list']) - - self._activity_registry = bundleregistry.get_registry() - for bundle in self._activity_registry: - self._add_activity(self._activity_registry, bundle) - self._activity_registry.connect('bundle-added', self._add_activity) - - def _add_primitive(self, type_id, name, icon, mime_types): - object_type = {'type_id': type_id, - 'name': name, - 'icon': icon, - 'mime_types': mime_types} - self._types[type_id] = object_type - - def _add_activity(self, activity_registry, bundle): - mime_types = bundle.get_mime_types() - if mime_types is None: - return - - icon_theme = gtk.icon_theme_get_default() - for mime_type in mime_types: - if self._get_type_for_mime(mime_type) is not None: - continue - - name = gnomevfs.mime_get_description(mime_type) - if name is None: - continue - - icon = mime_type.replace('/', '-') - if icon_theme.lookup_icon(icon, gtk.ICON_SIZE_BUTTON, 0) is None: - continue - - object_type = {'type_id': mime_type, - 'name': name, - 'icon': icon, - 'mime_types': [mime_type]} - self._types[mime_type] = object_type - - def _get_type_for_mime(self, mime_type): - for object_type in self._types.values(): - if mime_type in object_type['mime_types']: - return object_type - return None - - @dbus.service.method(_REGISTRY_IFACE, - in_signature="s", out_signature="a{sv}") - def GetType(self, type_id): - if self._types.has_key(type_id): - return self._types[type_id] - else: - return {} - - @dbus.service.method(_REGISTRY_IFACE, - in_signature="s", out_signature="a{sv}") - def GetTypeForMIME(self, mime_type): - object_type = self._get_type_for_mime(mime_type) - if object_type: - return object_type - else: - return {} - -_instance = None - -def get_instance(): - global _instance - if not _instance: - _instance = ObjectTypeRegistry() - return _instance From b72f00e30beff60e2ec551c4ed57d048061f1716 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Wed, 31 Oct 2007 00:05:16 +0100 Subject: [PATCH 09/14] Integrate control panel in the build so that I can actually distcheck. --- bin/Makefile.am | 4 +++- .../controlpanel/sugar-control => bin/sugar-control-panel | 7 +++++-- {shell => bin}/sugar-shell | 0 configure.ac | 1 + shell/Makefile.am | 4 +--- shell/controlpanel/Makefile.am | 2 ++ 6 files changed, 12 insertions(+), 6 deletions(-) rename shell/controlpanel/sugar-control => bin/sugar-control-panel (97%) rename {shell => bin}/sugar-shell (100%) create mode 100644 shell/controlpanel/Makefile.am diff --git a/bin/Makefile.am b/bin/Makefile.am index fd72139b..327df30d 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -2,8 +2,10 @@ bin_SCRIPTS = \ sugar \ sugar-activity \ sugar-backup \ + sugar-control-panel \ sugar-install-bundle \ - sugar-launch + sugar-launch \ + sugar-shell EXTRA_DIST = $(bin_SCRIPTS) sugar.in diff --git a/shell/controlpanel/sugar-control b/bin/sugar-control-panel similarity index 97% rename from shell/controlpanel/sugar-control rename to bin/sugar-control-panel index 4bee092d..d978fed7 100755 --- a/shell/controlpanel/sugar-control +++ b/bin/sugar-control-panel @@ -17,8 +17,11 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import getopt, sys - +import sys +import getopt + +sys.path.insert(0, env.get_shell_path()) + import control def cmd_help(): diff --git a/shell/sugar-shell b/bin/sugar-shell similarity index 100% rename from shell/sugar-shell rename to bin/sugar-shell diff --git a/configure.ac b/configure.ac index 78444554..01c5645c 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,7 @@ lib/sugar/datastore/Makefile services/Makefile services/shell/Makefile shell/Makefile +shell/controlpanel/Makefile shell/intro/Makefile shell/hardware/Makefile shell/view/Makefile diff --git a/shell/Makefile.am b/shell/Makefile.am index 56649bef..4c9eac9f 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -1,6 +1,4 @@ -SUBDIRS = hardware model view intro - -bin_SCRIPTS = sugar-shell +SUBDIRS = controlpanel hardware model view intro sugardir = $(pkgdatadir)/shell sugar_PYTHON = \ diff --git a/shell/controlpanel/Makefile.am b/shell/controlpanel/Makefile.am new file mode 100644 index 00000000..353aeec0 --- /dev/null +++ b/shell/controlpanel/Makefile.am @@ -0,0 +1,2 @@ +sugardir = $(pkgdatadir)/shell/controlpanel +sugar_PYTHON = control.py From 116ebfecf694af224ad094880d7daa9ef33e0e75 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Wed, 31 Oct 2007 00:07:20 +0100 Subject: [PATCH 10/14] Snapshot b72f00e30b. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index a505c626..b4d9c05a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +Snapshot b72f00e30b + * #4517 Do not require a TakeScreenshot method on the dbus service (marco) * Add wep type combo. (dcbw) From 4ee3e65bc56d575c5bfc83d92e95cf3482ec8dd4 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Wed, 31 Oct 2007 09:59:35 +0100 Subject: [PATCH 11/14] sugar-control: Use NM for radio on/off, check for superuser --- NEWS | 2 + shell/controlpanel/control.py | 104 ++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/NEWS b/NEWS index b4d9c05a..c0d6553f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* sugar-control: Use NM for radio on/off, check for superuser (erikos) + Snapshot b72f00e30b * #4517 Do not require a TakeScreenshot method on the dbus service (marco) diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py index 89870514..28922b80 100644 --- a/shell/controlpanel/control.py +++ b/shell/controlpanel/control.py @@ -27,10 +27,15 @@ import os import string import shutil from gettext import gettext as _ +import dbus from sugar import profile from sugar.graphics.xocolor import XoColor +NM_SERVICE_NAME = 'org.freedesktop.NetworkManager' +NM_SERVICE_PATH = '/org/freedesktop/NetworkManager' +NM_SERVICE_IFACE = 'org.freedesktop.NetworkManager' +NM_ASLEEP = 1 _COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'}, 'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'}, @@ -184,25 +189,16 @@ _LANGUAGES = { 'Zulu/South_Africa': ('zu_ZA.UTF-8', 'latarcyrheb-sun16') } -_timezones = [] def _initialize(): - _timezones = _read_zonetab() + timezones = _read_zonetab() + j=0 - for timezone in _timezones: + for timezone in timezones: set_timezone.__doc__ += timezone+', ' j+=1 if j%3 == 0: set_timezone.__doc__ += '\n' - - if not os.access(_TIMEZONE_CONFIG, os.R_OK): - #Theres no /etc/sysconfig/clock file, so make one - fd = open(_TIMEZONE_CONFIG, 'w') - f.write(' The ZONE parameter is only evaluated by sugarcontrol.\n') - f.write('The timezone of the system' + - ' is defined by the contents of /etc/localtime.\n') - f.write('ZONE="America/NEW_York"\n') - f.close() keys = _LANGUAGES.keys() keys.sort() @@ -282,30 +278,50 @@ def set_nick(nick): pro.nick_name = nick pro.save() -def get_radio(state): - return '' +def get_radio(): + bus = dbus.SystemBus() + proxy = bus.get_object(NM_SERVICE_NAME, NM_SERVICE_PATH) + nm = dbus.Interface(proxy, NM_SERVICE_IFACE) + state = nm.state() + if state: + if state == NM_ASLEEP: + return _('Asleep') + else: + return _('Awake') + return _('State is unknown.') -def print_radio(self): +def print_radio(): print get_radio() def set_radio(state): """Turn Radio off state : 'on/off' """ + + # TODO: NM 0.6.x does not return a reply yet + # so we ignore it for the moment + if state == 'on': - cmd = '/sbin/iwconfig eth0 txpower on' - handle = os.popen(cmd, 'r') - print string.join(handle.readlines()) - handle.close() + dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH, + NM_SERVICE_IFACE, 'wake', '', (), + None, None) elif state == 'off': - cmd = '/sbin/iwconfig eth0 txpower off' - handle = os.popen(cmd, 'r') - print string.join(handle.readlines()) - handle.close() + dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH, + NM_SERVICE_IFACE, 'sleep', '', (), + None, None) else: print (_("Error in specified radio argument use on/off.")) - + +def _check_for_superuser(): + if os.getuid(): + print _("Permission denied. You need to be root to run this method.") + return False + return True + def get_timezone(): + if not os.access(_TIMEZONE_CONFIG, os.R_OK): + # this is what the default is for the /etc/localtime + return "America/New_York" fd = open(_TIMEZONE_CONFIG, "r") lines = fd.readlines() fd.close() @@ -331,12 +347,30 @@ def print_timezone(): print (_("Error in reading timezone")) else: print timezone - + +def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'): + fd = open (fn, 'r') + lines = fd.readlines() + fd.close() + timezones = [] + for line in lines: + if line.startswith('#'): + continue + line = line.split() + if len(line) > 1: + timezones.append(line[2]) + timezones.sort() + return timezones + def set_timezone(timezone): """Set the system timezone timezone : """ - if timezone in _timezones: + if not _check_for_superuser(): + return + + timezones = _read_zonetab() + if timezone in timezones: fromfile = os.path.join("/usr/share/zoneinfo/", timezone) try: shutil.copyfile(fromfile, "/etc/localtime") @@ -358,20 +392,6 @@ def set_timezone(timezone): fd.close() else: print (_("Error timezone does not exist.")) - -def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'): - fd = open (fn, 'r') - lines = fd.readlines() - fd.close() - timezones = [] - for line in lines: - if line.startswith('#'): - continue - line = line.split() - if len(line) > 1: - timezones.append(line[2]) - timezones.sort() - return timezones def _writeI18N(lang, sysfont): path = '/etc/sysconfig/i18n' @@ -418,11 +438,13 @@ def set_language(language): """Set the system language. languages : """ + if not _check_for_superuser(): + return if language in _LANGUAGES: _writeI18N(_LANGUAGES[language][0], _LANGUAGES[language][1]) else: print (_("Sorry I do not speak \'%s\'.")%language) - # inilialize the docstrings for the timezone and language _initialize() + From 38b87ad7cd1f7620c5c8f615bfc18b693c46053e Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Wed, 31 Oct 2007 10:36:38 +0100 Subject: [PATCH 12/14] sugar-control: add env import --- bin/sugar-control-panel | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/sugar-control-panel b/bin/sugar-control-panel index d978fed7..489cf72f 100755 --- a/bin/sugar-control-panel +++ b/bin/sugar-control-panel @@ -20,6 +20,8 @@ import sys import getopt +from sugar import env + sys.path.insert(0, env.get_shell_path()) import control From 14ffdc1d03f93e76ae0f7e483c006ce76f61dd23 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Wed, 31 Oct 2007 11:32:54 +0100 Subject: [PATCH 13/14] sugar-control: fixed some imports, cleaned some strings --- bin/sugar-control-panel | 2 +- shell/controlpanel/Makefile.am | 4 +++- shell/controlpanel/control.py | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/bin/sugar-control-panel b/bin/sugar-control-panel index 489cf72f..367372d8 100755 --- a/bin/sugar-control-panel +++ b/bin/sugar-control-panel @@ -24,7 +24,7 @@ from sugar import env sys.path.insert(0, env.get_shell_path()) -import control +from controlpanel import control def cmd_help(): print 'Usage: sugar-control [ option ] key [ args ... ] \n\ diff --git a/shell/controlpanel/Makefile.am b/shell/controlpanel/Makefile.am index 353aeec0..b7721707 100644 --- a/shell/controlpanel/Makefile.am +++ b/shell/controlpanel/Makefile.am @@ -1,2 +1,4 @@ sugardir = $(pkgdatadir)/shell/controlpanel -sugar_PYTHON = control.py +sugar_PYTHON = \ + __init__.py \ + control.py diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py index 28922b80..02ddfe38 100644 --- a/shell/controlpanel/control.py +++ b/shell/controlpanel/control.py @@ -218,7 +218,7 @@ def print_jabber(): def set_jabber(server): """Set the jabber server - server : 'olpc.collabora.co.uk' + server : e.g. 'olpc.collabora.co.uk' """ pro = profile.get_profile() pro.jabber_server = server @@ -239,11 +239,11 @@ def print_color(): print 'fill: color=%s hue=%s'%(color, hue) def set_color(stroke, fill, modstroke='medium', modfill='medium'): - """Set the system color. - fill : 'red, orange, yellow, blue, purple' - stroke : 'red, orange, yellow, blue, purple' - modstroke : 'dark, medium, light' - modfill : ''dark, medium, light' + """Set the system color by setting a fill and stroke color. + fill : [red, orange, yellow, blue, purple] + stroke : [red, orange, yellow, blue, purple] + hue stroke : [dark, medium, light] (optional) + hue fill : [dark, medium, light] (optional) """ if modstroke not in _MODIFIERS or modfill not in _MODIFIERS: @@ -272,7 +272,7 @@ def print_nick(): def set_nick(nick): """Set the nickname. - nick : 'erikos' + nick : e.g. 'walter' """ pro = profile.get_profile() pro.nick_name = nick @@ -285,16 +285,16 @@ def get_radio(): state = nm.state() if state: if state == NM_ASLEEP: - return _('Asleep') + return _('off') else: - return _('Awake') + return _('on') return _('State is unknown.') def print_radio(): print get_radio() def set_radio(state): - """Turn Radio off + """Turn Radio 'on' or 'off' state : 'on/off' """ From dbbdf7383f2c94da2135fe0855d00945eab60115 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Wed, 31 Oct 2007 11:33:45 +0100 Subject: [PATCH 14/14] sugar-control: add the init file --- shell/controlpanel/__init__.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 shell/controlpanel/__init__.py diff --git a/shell/controlpanel/__init__.py b/shell/controlpanel/__init__.py new file mode 100644 index 00000000..a9dd95ad --- /dev/null +++ b/shell/controlpanel/__init__.py @@ -0,0 +1,16 @@ +# Copyright (C) 2006-2007, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +