diff options
Diffstat (limited to 'src/jarabe/desktop')
-rw-r--r-- | src/jarabe/desktop/__init__.py | 1 | ||||
-rw-r--r-- | src/jarabe/desktop/activitieslist.py | 30 | ||||
-rw-r--r-- | src/jarabe/desktop/favoriteslayout.py | 57 | ||||
-rw-r--r-- | src/jarabe/desktop/favoritesview.py | 57 | ||||
-rw-r--r-- | src/jarabe/desktop/friendview.py | 2 | ||||
-rw-r--r-- | src/jarabe/desktop/grid.py | 11 | ||||
-rw-r--r-- | src/jarabe/desktop/groupbox.py | 6 | ||||
-rw-r--r-- | src/jarabe/desktop/homebox.py | 21 | ||||
-rw-r--r-- | src/jarabe/desktop/homewindow.py | 28 | ||||
-rw-r--r-- | src/jarabe/desktop/keydialog.py | 61 | ||||
-rw-r--r-- | src/jarabe/desktop/meshbox.py | 77 | ||||
-rw-r--r-- | src/jarabe/desktop/networkviews.py | 82 | ||||
-rw-r--r-- | src/jarabe/desktop/schoolserver.py | 65 | ||||
-rw-r--r-- | src/jarabe/desktop/snowflakelayout.py | 3 | ||||
-rw-r--r-- | src/jarabe/desktop/spreadlayout.py | 4 | ||||
-rw-r--r-- | src/jarabe/desktop/transitionbox.py | 7 |
16 files changed, 313 insertions, 199 deletions
diff --git a/src/jarabe/desktop/__init__.py b/src/jarabe/desktop/__init__.py index a9dd95a..85f6a24 100644 --- a/src/jarabe/desktop/__init__.py +++ b/src/jarabe/desktop/__init__.py @@ -13,4 +13,3 @@ # 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 - diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py index 56b3b5f..0370ef3 100644 --- a/src/jarabe/desktop/activitieslist.py +++ b/src/jarabe/desktop/activitieslist.py @@ -30,20 +30,18 @@ from sugar.graphics.icon import Icon, CellRendererIcon from sugar.graphics.xocolor import XoColor from sugar.graphics.menuitem import MenuItem from sugar.graphics.alert import Alert -from sugar.activity import activityfactory -from sugar.activity.activityhandle import ActivityHandle from jarabe.model import bundleregistry from jarabe.view.palettes import ActivityPalette -from jarabe.view import launcher from jarabe.journal import misc + class ActivitiesTreeView(gtk.TreeView): __gtype_name__ = 'SugarActivitiesTreeView' __gsignals__ = { - 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([str])) + 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([str])), } def __init__(self): @@ -154,6 +152,7 @@ class ActivitiesTreeView(gtk.TreeView): title = model[tree_iter][ListModel.COLUMN_TITLE] return title is not None and title.lower().find(self._query) > -1 + class ListModel(gtk.TreeModelSort): __gtype_name__ = 'SugarListModel' @@ -167,7 +166,7 @@ class ListModel(gtk.TreeModelSort): COLUMN_DATE_TEXT = 7 def __init__(self): - self._model = gtk.ListStore(str, bool, str, str, int, str, int, str) + self._model = gtk.ListStore(str, bool, str, str, str, str, int, str) self._model_filter = self._model.filter_new() gtk.TreeModelSort.__init__(self, self._model_filter) @@ -238,6 +237,7 @@ class ListModel(gtk.TreeModelSort): def refilter(self): self._model_filter.refilter() + class CellRendererFavorite(CellRendererIcon): __gtype_name__ = 'SugarCellRendererFavorite' @@ -252,12 +252,13 @@ class CellRendererFavorite(CellRendererIcon): self.props.prelit_stroke_color = style.COLOR_BUTTON_GREY.get_svg() self.props.prelit_fill_color = style.COLOR_BUTTON_GREY.get_svg() + class CellRendererActivityIcon(CellRendererIcon): __gtype_name__ = 'SugarCellRendererActivityIcon' __gsignals__ = { - 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([str])) + 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([str])), } def __init__(self, tree_view): @@ -290,6 +291,7 @@ class CellRendererActivityIcon(CellRendererIcon): def __erase_activated_cb(self, palette, bundle_id): self.emit('erase-activated', bundle_id) + class ActivitiesList(gtk.VBox): __gtype_name__ = 'SugarActivitiesList' @@ -373,12 +375,13 @@ class ActivitiesList(gtk.VBox): bundle = registry.get_bundle(bundle_id) registry.uninstall(bundle, delete_profile=True) + class ActivityListPalette(ActivityPalette): __gtype_name__ = 'SugarActivityListPalette' __gsignals__ = { - 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([str])) + 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([str])), } def __init__(self, activity_info): @@ -417,8 +420,8 @@ class ActivityListPalette(ActivityPalette): menu_item.show() if not os.access(activity_info.get_path(), os.W_OK) or \ - registry.is_activity_protected(self._bundle_id): - menu_item.props.sensitive = False + registry.is_activity_protected(self._bundle_id): + menu_item.props.sensitive = False def __destroy_cb(self, palette): self.disconnect(self._activity_changed_sid) @@ -432,7 +435,7 @@ class ActivityListPalette(ActivityPalette): else: label.set_text(_('Make favorite')) client = gconf.client_get_default() - xo_color = XoColor(client.get_string("/desktop/sugar/user/color")) + xo_color = XoColor(client.get_string('/desktop/sugar/user/color')) self._favorite_icon.props.xo_color = xo_color @@ -452,4 +455,3 @@ class ActivityListPalette(ActivityPalette): def __erase_activate_cb(self, menu_item): self.emit('erase-activated', self._bundle_id) - diff --git a/src/jarabe/desktop/favoriteslayout.py b/src/jarabe/desktop/favoriteslayout.py index 7b847ac..360c147 100644 --- a/src/jarabe/desktop/favoriteslayout.py +++ b/src/jarabe/desktop/favoriteslayout.py @@ -29,6 +29,7 @@ from sugar.graphics import style from jarabe.model import bundleregistry from jarabe.desktop.grid import Grid + _logger = logging.getLogger('FavoritesLayout') _CELL_SIZE = 4 @@ -89,7 +90,8 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout): if icon not in self.box.get_children(): raise ValueError('Child not in box.') - if not(hasattr(icon, 'get_bundle_id') and hasattr(icon, 'get_version')): + if not (hasattr(icon, 'get_bundle_id') and + hasattr(icon, 'get_version')): logging.debug('Not an activity icon %r', icon) return @@ -109,6 +111,7 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout): def allow_dnd(self): return False + class RandomLayout(FavoritesLayout): """Lay out icons randomly; try to nudge them around to resolve overlaps.""" @@ -189,6 +192,7 @@ class RandomLayout(FavoritesLayout): def allow_dnd(self): return True + _MINIMUM_RADIUS = style.XLARGE_ICON_SIZE / 2 + style.DEFAULT_SPACING + \ style.STANDARD_ICON_SIZE * 2 _MAXIMUM_RADIUS = (gtk.gdk.screen_height() - style.GRID_CELL_SIZE) / 2 - \ @@ -239,32 +243,34 @@ class RingLayout(FavoritesLayout): self._spiral_mode = False distance = style.MEDIUM_ICON_SIZE + style.DEFAULT_SPACING * \ _ICON_SPACING_FACTORS[_ICON_SIZES.index(style.MEDIUM_ICON_SIZE)] - radius = max(children_count * distance / (2 * math.pi), _MINIMUM_RADIUS) + radius = max(children_count * distance / (2 * math.pi), + _MINIMUM_RADIUS) if radius < _MAXIMUM_RADIUS: return radius, style.MEDIUM_ICON_SIZE distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING * \ _ICON_SPACING_FACTORS[_ICON_SIZES.index(style.STANDARD_ICON_SIZE)] - radius = max(children_count * distance / (2 * math.pi), _MINIMUM_RADIUS) + radius = max(children_count * distance / (2 * math.pi), + _MINIMUM_RADIUS) if radius < _MAXIMUM_RADIUS: return radius, style.STANDARD_ICON_SIZE self._spiral_mode = True icon_size = style.STANDARD_ICON_SIZE - angle, radius = self._calculate_angle_and_radius(children_count, - icon_size) + angle_, radius = self._calculate_angle_and_radius(children_count, + icon_size) while radius > _MAXIMUM_RADIUS: i = _ICON_SIZES.index(icon_size) if i < len(_ICON_SIZES) - 1: icon_size = _ICON_SIZES[i + 1] - angle, radius = self._calculate_angle_and_radius( + angle_, radius = self._calculate_angle_and_radius( children_count, icon_size) else: break return radius, icon_size - def _calculate_position(self, radius, icon_size, icon_index, children_count, - sin=math.sin, cos=math.cos): + def _calculate_position(self, radius, icon_size, icon_index, + children_count, sin=math.sin, cos=math.cos): """ Calculate an icon position on a circle or a spiral. """ width, height = self.box.get_allocation() if self._spiral_mode: @@ -298,7 +304,7 @@ class RingLayout(FavoritesLayout): _ICON_SPACING_FACTORS[_ICON_SIZES.index(icon_size)] angle = _INITIAL_ANGLE radius = _MINIMUM_RADIUS - (icon_size * _MIMIMUM_RADIUS_ENCROACHMENT) - for i in range(icon_count): + for i_ in range(icon_count): circumference = radius * 2 * math.pi n = circumference / icon_spacing angle += (2 * math.pi / n) @@ -351,6 +357,7 @@ class RingLayout(FavoritesLayout): else: return 0 + _SUNFLOWER_CONSTANT = style.STANDARD_ICON_SIZE * .75 """Chose a constant such that STANDARD_ICON_SIZE icons are nicely spaced.""" @@ -376,6 +383,7 @@ This is the golden angle: http://en.wikipedia.org/wiki/Golden_angle Calculation: math.radians(360) / ( _GOLDEN_RATIO * _GOLDEN_RATIO ) """ + class SunflowerLayout(RingLayout): """Spiral layout based on Fibonacci ratio in phyllotaxis. @@ -403,7 +411,8 @@ class SunflowerLayout(RingLayout): return None, style.STANDARD_ICON_SIZE def adjust_index(self, i): - """Skip floret indices which end up outside the desired bounding box.""" + """Skip floret indices which end up outside the desired bounding box. + """ for idx in self.skipped_indices: if i < idx: break @@ -434,7 +443,7 @@ class SunflowerLayout(RingLayout): # removed to make room for the "active activity" icon. x = r * cos(phi) + (width - icon_size) / 2 y = r * sin(phi) + (height - icon_size - \ - (style.GRID_CELL_SIZE / 2) ) / 2 + (style.GRID_CELL_SIZE / 2)) / 2 # skip allocations outside the allocation box. # give up once we can't fit @@ -442,10 +451,12 @@ class SunflowerLayout(RingLayout): if y < 0 or y > (height - icon_size) or \ x < 0 or x > (width - icon_size): self.skipped_indices.append(index) - continue # try again + # try again + continue return x, y + class BoxLayout(RingLayout): """Lay out icons in a square around the XO man.""" @@ -478,14 +489,16 @@ class BoxLayout(RingLayout): return (90 - d) / 45. if d < 225: return -1 - return cos_d(360 - d) # mirror around 180 + # mirror around 180 + return cos_d(360 - d) cos = lambda r: cos_d(math.degrees(r)) sin = lambda r: cos_d(math.degrees(r) - 90) - return RingLayout._calculate_position\ - (self, radius, icon_size, index, children_count, - sin=sin, cos=cos) + return RingLayout._calculate_position(self, radius, icon_size, index, + children_count, sin=sin, + cos=cos) + class TriangleLayout(RingLayout): """Lay out icons in a triangle around the XO man.""" @@ -524,7 +537,8 @@ class TriangleLayout(RingLayout): return (d + 90) / 120. if d <= 90: return (90 - d) / 60. - return -cos_d(180 - d) # mirror around 90 + # mirror around 90 + return -cos_d(180 - d) sqrt_3 = math.sqrt(3) @@ -535,11 +549,12 @@ class TriangleLayout(RingLayout): return ((d + 90) / 120.) * sqrt_3 - 1 if d <= 90: return sqrt_3 - 1 - return sin_d(180 - d) # mirror around 90 + # mirror around 90 + return sin_d(180 - d) cos = lambda r: cos_d(math.degrees(r)) sin = lambda r: sin_d(math.degrees(r)) - return RingLayout._calculate_position\ - (self, radius, icon_size, index, children_count, - sin=sin, cos=cos) + return RingLayout._calculate_position(self, radius, icon_size, index, + children_count, sin=sin, + cos=cos) diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py index ac847e2..b4a4e75 100644 --- a/src/jarabe/desktop/favoritesview.py +++ b/src/jarabe/desktop/favoritesview.py @@ -30,7 +30,6 @@ from sugar.graphics.menuitem import MenuItem from sugar.graphics.alert import Alert from sugar.graphics.xocolor import XoColor from sugar.activity import activityfactory -from sugar.activity.activityhandle import ActivityHandle from sugar import dispatch from sugar.datastore import datastore @@ -38,7 +37,6 @@ from jarabe.view.palettes import JournalPalette from jarabe.view.palettes import CurrentActivityPalette, ActivityPalette from jarabe.view.buddyicon import BuddyIcon from jarabe.view.buddymenu import BuddyMenu -from jarabe.view import launcher from jarabe.model.buddy import get_owner_instance from jarabe.model import shell from jarabe.model import bundleregistry @@ -48,6 +46,7 @@ from jarabe.desktop import schoolserver from jarabe.desktop.schoolserver import RegisterError from jarabe.desktop import favoriteslayout + _logger = logging.getLogger('FavoritesView') _ICON_DND_TARGET = ('activity-icon', gtk.TARGET_SAME_WIDGET, 0) @@ -61,6 +60,9 @@ LAYOUT_MAP = {favoriteslayout.RingLayout.key: favoriteslayout.RingLayout, `FavoritesLayout` which implement the layouts. Additional information about the layout can be accessed with fields of the class.""" +_favorites_settings = None + + class FavoritesView(hippo.Canvas): __gtype_name__ = 'SugarFavoritesView' @@ -171,7 +173,8 @@ class FavoritesView(hippo.Canvas): height = allocation.height min_w_, my_icon_width = self._my_icon.get_width_request() - min_h_, my_icon_height = self._my_icon.get_height_request(my_icon_width) + min_h_, my_icon_height = self._my_icon.get_height_request( + my_icon_width) x = (width - my_icon_width) / 2 y = (height - my_icon_height - style.GRID_CELL_SIZE) / 2 self._layout.move_icon(self._my_icon, x, y, locked=True) @@ -189,7 +192,8 @@ class FavoritesView(hippo.Canvas): # TODO: Dnd methods. This should be merged somehow inside hippo-canvas. def __button_press_event_cb(self, widget, event): if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS: - self._last_clicked_icon = self._get_icon_at_coords(event.x, event.y) + self._last_clicked_icon = self._get_icon_at_coords(event.x, + event.y) if self._last_clicked_icon is not None: self._pressed_button = event.button self._press_start_x = event.x @@ -202,9 +206,9 @@ class FavoritesView(hippo.Canvas): icon_x, icon_y = icon.get_context().translate_to_widget(icon) icon_width, icon_height = icon.get_allocation() - if (x >= icon_x ) and (x <= icon_x + icon_width) and \ - (y >= icon_y ) and (y <= icon_y + icon_height) and \ - isinstance(icon, ActivityIcon): + if (x >= icon_x) and (x <= icon_x + icon_width) and \ + (y >= icon_y) and (y <= icon_y + icon_height) and \ + isinstance(icon, ActivityIcon): return icon return None @@ -273,7 +277,7 @@ class FavoritesView(hippo.Canvas): def _set_layout(self, layout): if layout not in LAYOUT_MAP: - logging.warn('Unknown favorites layout: %r' % layout) + logging.warn('Unknown favorites layout: %r', layout) layout = favoriteslayout.RingLayout.key assert layout in LAYOUT_MAP @@ -326,7 +330,7 @@ class FavoritesView(hippo.Canvas): alert.props.title = _('Registration Successful') alert.props.msg = _('You are now registered ' \ 'with your school server.') - self._my_icon.remove_register_menu() + self._my_icon.set_registered() ok_icon = Icon(icon_name='dialog-ok') alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon) @@ -386,7 +390,7 @@ class ActivityIcon(CanvasIcon): break def _get_last_activity_async(self, bundle_id, properties): - query = {'activity': bundle_id} + query = {'activity': bundle_id} datastore.find(query, sorting=['+timestamp'], limit=self._MAX_RESUME_ENTRIES, properties=properties, @@ -394,8 +398,8 @@ class ActivityIcon(CanvasIcon): error_handler=self.__get_last_activity_error_handler_cb) def __get_last_activity_reply_handler_cb(self, entries, total_count): - # If there's a problem with the DS index, we may get entries not related - # to this activity. + # If there's a problem with the DS index, we may get entries not + # related to this activity. checked_entries = [] for entry in entries: if entry['activity'] == self.bundle_id: @@ -506,6 +510,7 @@ class ActivityIcon(CanvasIcon): self._resume_mode = resume_mode self._update() + class FavoritePalette(ActivityPalette): __gtype_name__ = 'SugarFavoritePalette' @@ -554,6 +559,7 @@ class FavoritePalette(ActivityPalette): if entry is not None: self.emit('entry-activate', entry) + class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem): def __init__(self): CanvasIcon.__init__(self, cache=True) @@ -592,13 +598,15 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem): self._home_activity = home_activity self._update() + class OwnerIcon(BuddyIcon): __gtype_name__ = 'SugarFavoritesOwnerIcon' __gsignals__ = { - 'register-activate' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) + 'register-activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([])), } + def __init__(self, size): BuddyIcon.__init__(self, buddy=get_owner_instance(), size=size) @@ -614,11 +622,16 @@ class OwnerIcon(BuddyIcon): client = gconf.client_get_default() backup_url = client.get_string('/desktop/sugar/backup_url') + if not backup_url: self._register_menu = MenuItem(_('Register'), 'media-record') - self._register_menu.connect('activate', self.__register_activate_cb) - palette.menu.append(self._register_menu) - self._register_menu.show() + else: + self._register_menu = MenuItem(_('Register again'), + 'media-record') + + self._register_menu.connect('activate', self.__register_activate_cb) + palette.menu.append(self._register_menu) + self._register_menu.show() return palette @@ -628,12 +641,17 @@ class OwnerIcon(BuddyIcon): def __register_activate_cb(self, menuitem): self.emit('register-activate') - def remove_register_menu(self): + def set_registered(self): self.palette.menu.remove(self._register_menu) + self._register_menu = MenuItem(_('Register again'), 'media-record') + self._register_menu.connect('activate', self.__register_activate_cb) + self.palette.menu.append(self._register_menu) + self._register_menu.show() + class FavoritesSetting(object): - _FAVORITES_KEY = "/desktop/sugar/desktop/favorites_layout" + _FAVORITES_KEY = '/desktop/sugar/desktop/favorites_layout' def __init__(self): client = gconf.client_get_default() @@ -659,7 +677,6 @@ class FavoritesSetting(object): layout = property(get_layout, set_layout) -_favorites_settings = None def get_settings(): global _favorites_settings diff --git a/src/jarabe/desktop/friendview.py b/src/jarabe/desktop/friendview.py index 53b8f5e..8dab35f 100644 --- a/src/jarabe/desktop/friendview.py +++ b/src/jarabe/desktop/friendview.py @@ -23,6 +23,7 @@ from sugar.graphics import style from jarabe.view.buddyicon import BuddyIcon from jarabe.model import bundleregistry + class FriendView(hippo.CanvasBox): def __init__(self, buddy, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) @@ -81,4 +82,3 @@ class FriendView(hippo.CanvasBox): def __buddy_notify_color_cb(self, buddy, pspec): # TODO: shouldn't this change self._buddy_icon instead? self._activity_icon.props.xo_color = buddy.props.color - diff --git a/src/jarabe/desktop/grid.py b/src/jarabe/desktop/grid.py index f3412c9..eab4033 100644 --- a/src/jarabe/desktop/grid.py +++ b/src/jarabe/desktop/grid.py @@ -22,17 +22,19 @@ import gtk from sugar import _sugarext + _PLACE_TRIALS = 20 _MAX_WEIGHT = 255 _REFRESH_RATE = 200 _MAX_COLLISIONS_PER_REFRESH = 20 + class Grid(_sugarext.Grid): __gsignals__ = { - 'child-changed' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) + 'child-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), } + def __init__(self, width, height): gobject.GObject.__init__(self) @@ -185,7 +187,8 @@ class Grid(_sugarext.Grid): for c in self._children: intersection = child_rect.intersect(self._child_rects[c]) if c != child and intersection.width > 0: - if c not in self._locked_children and c not in self._collisions: + if (c not in self._locked_children and + c not in self._collisions): collision_found = True self._collisions.append(c) diff --git a/src/jarabe/desktop/groupbox.py b/src/jarabe/desktop/groupbox.py index 89043fe..ed8f8ae 100644 --- a/src/jarabe/desktop/groupbox.py +++ b/src/jarabe/desktop/groupbox.py @@ -30,10 +30,12 @@ from jarabe.model import friends from jarabe.desktop.friendview import FriendView from jarabe.desktop.spreadlayout import SpreadLayout + class GroupBox(hippo.Canvas): __gtype_name__ = 'SugarGroupBox' + def __init__(self): - logging.debug("STARTUP: Loading the group view") + logging.debug('STARTUP: Loading the group view') gobject.GObject.__init__(self) @@ -47,7 +49,7 @@ class GroupBox(hippo.Canvas): self._box.set_layout(self._layout) client = gconf.client_get_default() - color = XoColor(client.get_string("/desktop/sugar/user/color")) + color = XoColor(client.get_string('/desktop/sugar/user/color')) self._owner_icon = CanvasIcon(icon_name='computer-xo', cache=True, xo_color=color) diff --git a/src/jarabe/desktop/homebox.py b/src/jarabe/desktop/homebox.py index 85279ff..661326e 100644 --- a/src/jarabe/desktop/homebox.py +++ b/src/jarabe/desktop/homebox.py @@ -30,16 +30,18 @@ from sugar.graphics.icon import Icon from jarabe.desktop import favoritesview from jarabe.desktop.activitieslist import ActivitiesList + _FAVORITES_VIEW = 0 _LIST_VIEW = 1 _AUTOSEARCH_TIMEOUT = 1000 + class HomeBox(gtk.VBox): __gtype_name__ = 'SugarHomeBox' def __init__(self): - logging.debug("STARTUP: Loading the home view") + logging.debug('STARTUP: Loading the home view') gobject.GObject.__init__(self) @@ -57,7 +59,7 @@ class HomeBox(gtk.VBox): def show_software_updates_alert(self): alert = Alert() updater_icon = Icon(icon_name='module-updater', - pixel_size = style.STANDARD_ICON_SIZE) + pixel_size=style.STANDARD_ICON_SIZE) alert.props.icon = updater_icon updater_icon.show() alert.props.title = _('Software Update') @@ -125,7 +127,7 @@ class HomeBox(gtk.VBox): else: raise ValueError('Invalid view: %r' % view) - _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes + _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes def resume(self): pass @@ -144,16 +146,15 @@ class HomeBox(gtk.VBox): def set_resume_mode(self, resume_mode): self._favorites_view.set_resume_mode(resume_mode) + class HomeToolbar(gtk.Toolbar): __gtype_name__ = 'SugarHomeToolbar' __gsignals__ = { - 'query-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, + 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([str])), - 'view-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([object])) + 'view-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([object])), } def __init__(self): @@ -239,13 +240,14 @@ class HomeToolbar(gtk.Toolbar): if self._autosearch_timer: gobject.source_remove(self._autosearch_timer) self._autosearch_timer = gobject.timeout_add(_AUTOSEARCH_TIMEOUT, - self.__autosearch_timer_cb) + self.__autosearch_timer_cb) def __autosearch_timer_cb(self): self._autosearch_timer = None self.search_entry.activate() return False + class FavoritesButton(RadioToolButton): __gtype_name__ = 'SugarFavoritesButton' @@ -295,4 +297,3 @@ class FavoritesButton(RadioToolButton): def _update_icon(self): self.props.named_icon = favoritesview.LAYOUT_MAP[self._layout]\ .icon_name - diff --git a/src/jarabe/desktop/homewindow.py b/src/jarabe/desktop/homewindow.py index fec4289..07deff7 100644 --- a/src/jarabe/desktop/homewindow.py +++ b/src/jarabe/desktop/homewindow.py @@ -16,6 +16,7 @@ import logging +import gobject import gtk from sugar.graphics import style @@ -28,11 +29,15 @@ from jarabe.desktop.transitionbox import TransitionBox from jarabe.model.shell import ShellModel from jarabe.model import shell -_HOME_PAGE = 0 -_GROUP_PAGE = 1 -_MESH_PAGE = 2 + +_HOME_PAGE = 0 +_GROUP_PAGE = 1 +_MESH_PAGE = 2 _TRANSITION_PAGE = 3 +_instance = None + + class HomeWindow(gtk.Window): def __init__(self): logging.debug('STARTUP: Loading the desktop window') @@ -75,7 +80,7 @@ class HomeWindow(gtk.Window): self.__zoom_level_changed_cb) def _deactivate_view(self, level): - group = palettegroup.get_group("default") + group = palettegroup.get_group('default') group.popdown() if level == ShellModel.ZOOM_HOME: self._home_box.suspend() @@ -183,11 +188,22 @@ class HomeWindow(gtk.Window): def get_home_box(self): return self._home_box -_instance = None + def busy_during_delayed_action(self, action): + """Use busy cursor during execution of action, scheduled via idle_add. + """ + def action_wrapper(old_cursor): + try: + action() + finally: + self.get_window().set_cursor(old_cursor) + + old_cursor = self.get_window().get_cursor() + self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) + gobject.idle_add(action_wrapper, old_cursor) + def get_instance(): global _instance if not _instance: _instance = HomeWindow() return _instance - diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py index 1e6d17a..6241b9b 100644 --- a/src/jarabe/desktop/keydialog.py +++ b/src/jarabe/desktop/keydialog.py @@ -24,8 +24,14 @@ import dbus from jarabe.model import network from jarabe.model.network import Secrets + IW_AUTH_ALG_OPEN_SYSTEM = 'open' -IW_AUTH_ALG_SHARED_KEY = 'shared' +IW_AUTH_ALG_SHARED_KEY = 'shared' + +WEP_PASSPHRASE = 1 +WEP_HEX = 2 +WEP_ASCII = 3 + def string_is_hex(key): is_hex = True @@ -34,6 +40,7 @@ def string_is_hex(key): is_hex = False return is_hex + def string_is_ascii(string): try: string.encode('ascii') @@ -41,12 +48,14 @@ def string_is_ascii(string): except UnicodeEncodeError: return False + def string_to_hex(passphrase): key = '' for c in passphrase: key += '%02x' % ord(c) return key + def hash_passphrase(passphrase): # passphrase must have a length of 64 if len(passphrase) > 64: @@ -57,16 +66,18 @@ def hash_passphrase(passphrase): passphrase = hashlib.md5(passphrase).digest() return string_to_hex(passphrase)[:26] + class CanceledKeyRequestError(dbus.DBusException): def __init__(self): dbus.DBusException.__init__(self) self._dbus_error_name = network.NM_SETTINGS_IFACE + '.CanceledError' + class KeyDialog(gtk.Dialog): def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): gtk.Dialog.__init__(self, flags=gtk.DIALOG_MODAL) - self.set_title("Wireless Key Required") + self.set_title('Wireless Key Required') self._settings = settings self._response = response @@ -108,9 +119,6 @@ class KeyDialog(gtk.Dialog): def get_response_object(self): return self._response -WEP_PASSPHRASE = 1 -WEP_HEX = 2 -WEP_ASCII = 3 class WEPKeyDialog(KeyDialog): def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, @@ -120,9 +128,9 @@ class WEPKeyDialog(KeyDialog): # 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.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.key_combo = gtk.ComboBox(self.key_store) cell = gtk.CellRendererText() @@ -132,7 +140,7 @@ class WEPKeyDialog(KeyDialog): self.key_combo.connect('changed', self._key_combo_changed_cb) hbox = gtk.HBox() - hbox.pack_start(gtk.Label(_("Key Type:"))) + hbox.pack_start(gtk.Label(_('Key Type:'))) hbox.pack_start(self.key_combo) hbox.show_all() self.vbox.pack_start(hbox) @@ -142,8 +150,8 @@ class WEPKeyDialog(KeyDialog): # WEP authentication mode self.auth_store = gtk.ListStore(str, str) - self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM]) - self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY]) + 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() @@ -152,7 +160,7 @@ class WEPKeyDialog(KeyDialog): self.auth_combo.set_active(0) hbox = gtk.HBox() - hbox.pack_start(gtk.Label(_("Authentication Type:"))) + hbox.pack_start(gtk.Label(_('Authentication Type:'))) hbox.pack_start(self.auth_combo) hbox.show_all() @@ -179,8 +187,8 @@ class WEPKeyDialog(KeyDialog): def print_security(self): (key, auth_alg) = self._get_security() - print "Key: %s" % key - print "Auth: %d" % auth_alg + print 'Key: %s' % key + print 'Auth: %d' % auth_alg def create_security(self): (key, auth_alg) = self._get_security() @@ -209,6 +217,7 @@ class WEPKeyDialog(KeyDialog): self.set_response_sensitive(gtk.RESPONSE_OK, valid) + class WPAKeyDialog(KeyDialog): def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): @@ -217,7 +226,7 @@ class WPAKeyDialog(KeyDialog): self.add_key_entry() self.store = gtk.ListStore(str) - self.store.append([_("WPA & WPA2 Personal")]) + self.store.append([_('WPA & WPA2 Personal')]) self.combo = gtk.ComboBox(self.store) cell = gtk.CellRendererText() @@ -226,7 +235,7 @@ class WPAKeyDialog(KeyDialog): self.combo.set_active(0) self.hbox = gtk.HBox() - self.hbox.pack_start(gtk.Label(_("Wireless Security:"))) + self.hbox.pack_start(gtk.Label(_('Wireless Security:'))) self.hbox.pack_start(self.combo) self.hbox.show_all() @@ -246,21 +255,21 @@ class WPAKeyDialog(KeyDialog): from subprocess import Popen, PIPE p = Popen(['wpa_passphrase', ssid, key], stdout=PIPE) for line in p.stdout: - if line.strip().startswith("psk="): + if line.strip().startswith('psk='): real_key = line.strip()[4:] if p.wait() != 0: - raise RuntimeError("Error hashing passphrase") + raise RuntimeError('Error hashing passphrase') if real_key and len(real_key) != 64: real_key = None if not real_key: - raise RuntimeError("Invalid key") + raise RuntimeError('Invalid key') return real_key def print_security(self): key = self._get_security() - print "Key: %s" % key + print 'Key: %s' % key def create_security(self): secrets = Secrets(self._settings) @@ -281,6 +290,7 @@ class WPAKeyDialog(KeyDialog): self.set_response_sensitive(gtk.RESPONSE_OK, valid) return False + def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): if wpa_flags == network.NM_802_11_AP_SEC_NONE and \ rsn_flags == network.NM_802_11_AP_SEC_NONE: @@ -290,13 +300,15 @@ def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): key_dialog = WPAKeyDialog(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response) - key_dialog.connect("response", _key_dialog_response_cb) - key_dialog.connect("destroy", _key_dialog_destroy_cb) + key_dialog.connect('response', _key_dialog_response_cb) + key_dialog.connect('destroy', _key_dialog_destroy_cb) key_dialog.show_all() + def _key_dialog_destroy_cb(key_dialog, data=None): _key_dialog_response_cb(key_dialog, gtk.RESPONSE_CANCEL) + def _key_dialog_response_cb(key_dialog, response_id): response = key_dialog.get_response_object() secrets = None @@ -308,10 +320,9 @@ def _key_dialog_response_cb(key_dialog, response_id): response.set_error(CanceledKeyRequestError()) elif response_id == gtk.RESPONSE_OK: if not secrets: - raise RuntimeError("Invalid security arguments.") + raise RuntimeError('Invalid security arguments.') response.set_secrets(secrets) else: - raise RuntimeError("Unhandled key dialog response %d" % response_id) + raise RuntimeError('Unhandled key dialog response %d' % response_id) key_dialog.destroy() - diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py index 036f00a..ad4b873 100644 --- a/src/jarabe/desktop/meshbox.py +++ b/src/jarabe/desktop/meshbox.py @@ -47,6 +47,7 @@ from jarabe.model.olpcmesh import OlpcMeshManager from jarabe.model.adhoc import get_adhoc_manager_instance from jarabe.journal import misc + _NM_SERVICE = 'org.freedesktop.NetworkManager' _NM_IFACE = 'org.freedesktop.NetworkManager' _NM_PATH = '/org/freedesktop/NetworkManager' @@ -59,6 +60,9 @@ _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active' _AP_ICON_NAME = 'network-wireless' _OLPC_MESH_ICON_NAME = 'network-mesh' +_AUTOSEARCH_TIMEOUT = 1000 + + class ActivityView(hippo.CanvasBox): def __init__(self, model): hippo.CanvasBox.__init__(self) @@ -115,7 +119,7 @@ class ActivityView(hippo.CanvasBox): return p def has_buddy_icon(self, key): - return self._icons.has_key(key) + return key in self._icons def __buddy_added_cb(self, activity, buddy): self._add_buddy(buddy) @@ -148,16 +152,13 @@ class ActivityView(hippo.CanvasBox): if hasattr(icon, 'set_filter'): icon.set_filter(query) -_AUTOSEARCH_TIMEOUT = 1000 - class MeshToolbar(gtk.Toolbar): __gtype_name__ = 'MeshToolbar' __gsignals__ = { - 'query-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([str])) + 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([str])), } def __init__(self): @@ -225,16 +226,18 @@ class DeviceObserver(gobject.GObject): 'access-point-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), 'access-point-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) + ([gobject.TYPE_PYOBJECT])), } + def __init__(self, device): gobject.GObject.__init__(self) self._bus = dbus.SystemBus() self.device = device wireless = dbus.Interface(device, _NM_WIRELESS_IFACE) - wireless.GetAccessPoints(reply_handler=self._get_access_points_reply_cb, - error_handler=self._get_access_points_error_cb) + wireless.GetAccessPoints( + reply_handler=self._get_access_points_reply_cb, + error_handler=self._get_access_points_error_cb) self._bus.add_signal_receiver(self.__access_point_added_cb, signal_name='AccessPointAdded', @@ -315,13 +318,12 @@ class NetworkManagerObserver(object): # FIXME It would be better to do all of this async, but I cannot think # of a good way to. NM could really use some love here. - netmgr_props = dbus.Interface( - self._netmgr, 'org.freedesktop.DBus.Properties') + netmgr_props = dbus.Interface(self._netmgr, dbus.PROPERTIES_IFACE) active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections') for conn_o in active_connections_o: obj = self._bus.get_object(_NM_IFACE, conn_o) - props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') + props = dbus.Interface(obj, dbus.PROPERTIES_IFACE) state = props.Get(_NM_ACTIVE_CONN_IFACE, 'State') if state == network.NM_ACTIVE_CONNECTION_STATE_ACTIVATING: ap_o = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject') @@ -333,8 +335,8 @@ class NetworkManagerObserver(object): settings = kwargs['connection'].get_settings() net.create_keydialog(settings, kwargs['response']) if not found: - logging.error('Could not determine AP for' - ' specific object %s' % conn_o) + logging.error('Could not determine AP for specific object' + ' %s', conn_o) def __get_devices_reply_cb(self, devices_o): for dev_o in devices_o: @@ -345,7 +347,7 @@ class NetworkManagerObserver(object): def _check_device(self, device_o): device = self._bus.get_object(_NM_SERVICE, device_o) - props = dbus.Interface(device, 'org.freedesktop.DBus.Properties') + props = dbus.Interface(device, dbus.PROPERTIES_IFACE) device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') if device_type == network.DEVICE_TYPE_802_11_WIRELESS: @@ -399,7 +401,7 @@ class MeshBox(gtk.VBox): __gtype_name__ = 'SugarMeshBox' def __init__(self): - logging.debug("STARTUP: Loading the mesh view") + logging.debug('STARTUP: Loading the mesh view') gobject.GObject.__init__(self) @@ -520,56 +522,59 @@ class MeshBox(gtk.VBox): # add AP to its corresponding network icon on the desktop, # creating one if it doesn't already exist def _add_ap_to_network(self, ap): - hash = ap.network_hash() - if hash in self.wireless_networks: - self.wireless_networks[hash].add_ap(ap) + hash_value = ap.network_hash() + if hash_value in self.wireless_networks: + self.wireless_networks[hash_value].add_ap(ap) else: # this is a new network icon = WirelessNetworkView(ap) - self.wireless_networks[hash] = icon + self.wireless_networks[hash_value] = icon self._layout.add(icon) if hasattr(icon, 'set_filter'): icon.set_filter(self._query) - def _remove_net_if_empty(self, net, hash): + def _remove_net_if_empty(self, net, hash_value): # remove a network if it has no APs left if net.num_aps() == 0: net.disconnect() self._layout.remove(net) - del self.wireless_networks[hash] + del self.wireless_networks[hash_value] - def _ap_props_changed_cb(self, ap, old_hash): + def _ap_props_changed_cb(self, ap, old_hash_value): # if we have mesh hardware, ignore OLPC mesh networks that appear as # normal wifi networks if len(self._mesh) > 0 and ap.mode == network.NM_802_11_MODE_ADHOC \ - and ap.name == "olpc-mesh": - logging.debug("ignoring OLPC mesh IBSS") + and ap.name == 'olpc-mesh': + logging.debug('ignoring OLPC mesh IBSS') ap.disconnect() return if self._adhoc_manager is not None and \ network.is_sugar_adhoc_network(ap.name) and \ ap.mode == network.NM_802_11_MODE_ADHOC: - if old_hash is None: # new Ad-hoc network finished initializing + if old_hash_value is None: + # new Ad-hoc network finished initializing self._adhoc_manager.add_access_point(ap) # we are called as well in other cases but we do not need to # act here as we don't display signal strength for Ad-hoc networks return - if old_hash is None: # new AP finished initializing + if old_hash_value is None: + # new AP finished initializing self._add_ap_to_network(ap) return - hash = ap.network_hash() - if old_hash == hash: + hash_value = ap.network_hash() + if old_hash_value == hash_value: # no change in network identity, so just update signal strengths - self.wireless_networks[hash].update_strength() + self.wireless_networks[hash_value].update_strength() return # properties change includes a change of the identity of the network # that it is on. so create this as a new network. - self.wireless_networks[old_hash].remove_ap(ap) - self._remove_net_if_empty(self.wireless_networks[old_hash], old_hash) + self.wireless_networks[old_hash_value].remove_ap(ap) + self._remove_net_if_empty(self.wireless_networks[old_hash_value], + old_hash_value) self._add_ap_to_network(ap) def add_access_point(self, device, ap_o): @@ -597,7 +602,7 @@ class MeshBox(gtk.VBox): # it's not an error if the AP isn't found, since we might have ignored # it (e.g. olpc-mesh adhoc network) - logging.debug('Can not remove access point %s' % ap_o) + logging.debug('Can not remove access point %s', ap_o) def add_adhoc_networks(self, device): if self._adhoc_manager is None: @@ -631,15 +636,15 @@ class MeshBox(gtk.VBox): # the OLPC mesh can be recognised as a "normal" wifi network. remove # any such normal networks if they have been created - for hash, net in self.wireless_networks.iteritems(): + for hash_value, net in self.wireless_networks.iteritems(): if not net.is_olpc_mesh(): continue - logging.debug("removing OLPC mesh IBSS") + logging.debug('removing OLPC mesh IBSS') net.remove_all_aps() net.disconnect() self._layout.remove(net) - del self.wireless_networks[hash] + del self.wireless_networks[hash_value] def disable_olpc_mesh(self, mesh_device): for icon in self._mesh: diff --git a/src/jarabe/desktop/networkviews.py b/src/jarabe/desktop/networkviews.py index 87f182f..99d46b6 100644 --- a/src/jarabe/desktop/networkviews.py +++ b/src/jarabe/desktop/networkviews.py @@ -41,6 +41,7 @@ from jarabe.model.network import IP4Config from jarabe.model.network import WirelessSecurity from jarabe.model.adhoc import get_adhoc_manager_instance + _NM_SERVICE = 'org.freedesktop.NetworkManager' _NM_IFACE = 'org.freedesktop.NetworkManager' _NM_PATH = '/org/freedesktop/NetworkManager' @@ -74,7 +75,6 @@ class WirelessNetworkView(CanvasPulsingIcon): self._rsn_flags = initial_ap.rsn_flags self._device_caps = 0 self._device_state = None - self._connection = None self._color = None if self._mode == network.NM_802_11_MODE_ADHOC and \ @@ -100,23 +100,9 @@ class WirelessNetworkView(CanvasPulsingIcon): self._palette = self._create_palette() self.set_palette(self._palette) self._palette_icon.props.xo_color = self._color + self._update_badge() - if self._mode != network.NM_802_11_MODE_ADHOC: - if network.find_connection_by_ssid(self._name) is not None: - self.props.badge_name = "emblem-favorite" - self._palette_icon.props.badge_name = "emblem-favorite" - elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY: - self.props.badge_name = "emblem-locked" - self._palette_icon.props.badge_name = "emblem-locked" - else: - self.props.badge_name = None - self._palette_icon.props.badge_name = None - else: - self.props.badge_name = None - self._palette_icon.props.badge_name = None - - interface_props = dbus.Interface(self._device, - 'org.freedesktop.DBus.Properties') + interface_props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE) interface_props.Get(_NM_DEVICE_IFACE, 'State', reply_handler=self.__get_device_state_reply_cb, error_handler=self.__get_device_state_error_cb) @@ -160,6 +146,7 @@ class WirelessNetworkView(CanvasPulsingIcon): self._device_state = new_state self._update_state() self._update_icon() + self._update_badge() def __update_active_ap(self, ap_path): if ap_path in self._access_points: @@ -192,6 +179,7 @@ class WirelessNetworkView(CanvasPulsingIcon): self._device_state = state self._update_state() self._update_color() + self._update_badge() def __get_device_state_error_cb(self, err): logging.error('Error getting the device state: %s', err) @@ -222,6 +210,21 @@ class WirelessNetworkView(CanvasPulsingIcon): icon = self._palette.props.icon icon.props.icon_name = icon_name + def _update_badge(self): + if self._mode != network.NM_802_11_MODE_ADHOC: + if network.find_connection_by_ssid(self._name) is not None: + self.props.badge_name = 'emblem-favorite' + self._palette_icon.props.badge_name = 'emblem-favorite' + elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY: + self.props.badge_name = 'emblem-locked' + self._palette_icon.props.badge_name = 'emblem-locked' + else: + self.props.badge_name = None + self._palette_icon.props.badge_name = None + else: + self.props.badge_name = None + self._palette_icon.props.badge_name = None + def _update_state(self): if self._active_ap is not None: state = self._device_state @@ -262,24 +265,30 @@ class WirelessNetworkView(CanvasPulsingIcon): self.props.base_color = self._color def _disconnect_activate_cb(self, item): - pass + if self._mode == network.NM_802_11_MODE_INFRA: + connection = network.find_connection_by_ssid(self._name) + if connection: + connection.disable_autoconnect() + + ap_paths = self._access_points.keys() + network.disconnect_access_points(ap_paths) def _add_ciphers_from_flags(self, flags, pairwise): ciphers = [] if pairwise: if flags & network.NM_802_11_AP_SEC_PAIR_TKIP: - ciphers.append("tkip") + ciphers.append('tkip') if flags & network.NM_802_11_AP_SEC_PAIR_CCMP: - ciphers.append("ccmp") + ciphers.append('ccmp') else: if flags & network.NM_802_11_AP_SEC_GROUP_WEP40: - ciphers.append("wep40") + ciphers.append('wep40') if flags & network.NM_802_11_AP_SEC_GROUP_WEP104: - ciphers.append("wep104") + ciphers.append('wep104') if flags & network.NM_802_11_AP_SEC_GROUP_TKIP: - ciphers.append("tkip") + ciphers.append('tkip') if flags & network.NM_802_11_AP_SEC_GROUP_CCMP: - ciphers.append("ccmp") + ciphers.append('ccmp') return ciphers def _get_security(self): @@ -363,7 +372,7 @@ class WirelessNetworkView(CanvasPulsingIcon): netmgr.ActivateConnection(network.SETTINGS_SERVICE, connection.path, self._device.object_path, - "/", + '/', reply_handler=self.__activate_reply_cb, error_handler=self.__activate_error_cb) @@ -380,7 +389,8 @@ class WirelessNetworkView(CanvasPulsingIcon): def create_keydialog(self, settings, response): keydialog.create(self._name, self._flags, self._wpa_flags, - self._rsn_flags, self._device_caps, settings, response) + self._rsn_flags, self._device_caps, settings, + response) def update_strength(self): if self._active_ap is not None: @@ -419,7 +429,7 @@ class WirelessNetworkView(CanvasPulsingIcon): def is_olpc_mesh(self): return self._mode == network.NM_802_11_MODE_ADHOC \ - and self.name == "olpc-mesh" + and self.name == 'olpc-mesh' def remove_all_aps(self): for ap in self._access_points.values(): @@ -438,6 +448,7 @@ class WirelessNetworkView(CanvasPulsingIcon): path=self._device.object_path, dbus_interface=_NM_WIRELESS_IFACE) + class SugarAdhocView(CanvasPulsingIcon): """To mimic the mesh behavior on devices where mesh hardware is not available we support the creation of an Ad-hoc network on @@ -483,7 +494,7 @@ class SugarAdhocView(CanvasPulsingIcon): icon_name=self._ICON_NAME + str(self._channel), icon_size=style.STANDARD_ICON_SIZE) - palette_ = palette.Palette(_("Ad-hoc Network %d") % self._channel, + palette_ = palette.Palette(_('Ad-hoc Network %d') % self._channel, icon=self._palette_icon) self._connect_item = MenuItem(_('Connect'), 'dialog-ok') @@ -517,9 +528,6 @@ class SugarAdhocView(CanvasPulsingIcon): else: icon_name = self._ICON_NAME + str(self._channel) - self.props.base_color = self._state_color - self._palette_icon.props.xo_color = self._state_color - if icon_name is not None: self.props.icon_name = icon_name icon = self._palette.props.icon @@ -549,6 +557,7 @@ class SugarAdhocView(CanvasPulsingIcon): def _update_color(self): if self._greyed_out: + self.props.pulsing = False self.props.base_color = XoColor('#D5D5D5,#D5D5D5') else: self.props.base_color = self._state_color @@ -557,12 +566,12 @@ class SugarAdhocView(CanvasPulsingIcon): if channel == self._channel: if has_members == True: self._state_color = profile.get_color() - self.props.base_color = self._state_color - self._palette_icon.props.xo_color = self._state_color else: color = '%s,%s' % (profile.get_color().get_stroke_color(), style.COLOR_TRANSPARENT.get_svg()) self._state_color = XoColor(color) + + if not self._greyed_out: self.props.base_color = self._state_color self._palette_icon.props.xo_color = self._state_color @@ -584,14 +593,12 @@ class OlpcMeshView(CanvasPulsingIcon): self._greyed_out = False self._name = '' self._device_state = None - self._connection = None self._active = False device = mesh_mgr.mesh_device self.connect('button-release-event', self.__button_release_event_cb) - interface_props = dbus.Interface(device, - 'org.freedesktop.DBus.Properties') + interface_props = dbus.Interface(device, dbus.PROPERTIES_IFACE) interface_props.Get(_NM_DEVICE_IFACE, 'State', reply_handler=self.__get_device_state_reply_cb, error_handler=self.__get_device_state_error_cb) @@ -616,7 +623,7 @@ class OlpcMeshView(CanvasPulsingIcon): self.set_palette(self._palette) def _create_palette(self): - _palette = palette.Palette(_("Mesh Network %d") % self._channel) + _palette = palette.Palette(_('Mesh Network %d') % self._channel) self._connect_item = MenuItem(_('Connect'), 'dialog-ok') self._connect_item.connect('activate', self.__connect_activate_cb) @@ -712,4 +719,3 @@ class OlpcMeshView(CanvasPulsingIcon): signal_name='PropertiesChanged', path=device_object_path, dbus_interface=_NM_OLPC_MESH_IFACE) - diff --git a/src/jarabe/desktop/schoolserver.py b/src/jarabe/desktop/schoolserver.py index a05f56c..aea2357 100644 --- a/src/jarabe/desktop/schoolserver.py +++ b/src/jarabe/desktop/schoolserver.py @@ -16,8 +16,9 @@ import logging from gettext import gettext as _ -from xmlrpclib import ServerProxy, Error +import xmlrpclib import socket +import httplib import os from string import ascii_uppercase import random @@ -29,15 +30,17 @@ import gconf from sugar import env from sugar.profile import get_profile -REGISTER_URL = 'http://schoolserver:8080/' +_REGISTER_URL = 'http://schoolserver:8080/' +_REGISTER_TIMEOUT = 8 -def generate_serial_number(): + +def _generate_serial_number(): """ Generates a serial number based on 3 random uppercase letters and the last 8 digits of the current unix seconds. """ serial_part1 = [] - for y_ in range(3) : + for y_ in range(3): serial_part1.append(random.choice(ascii_uppercase)) serial_part1 = ''.join(serial_part1) @@ -46,7 +49,8 @@ def generate_serial_number(): return serial -def store_identifiers(serial_number, uuid, backup_url): + +def _store_identifiers(serial_number, uuid_, backup_url): """ Stores the serial number, uuid and backup_url in the identifier folder inside the profile directory so that these identifiers can be used for backup. """ @@ -64,7 +68,7 @@ def store_identifiers(serial_number, uuid, backup_url): if os.path.exists(os.path.join(identifier_path, 'uuid')): os.remove(os.path.join(identifier_path, 'uuid')) uuid_file = open(os.path.join(identifier_path, 'uuid'), 'w') - uuid_file.write(uuid) + uuid_file.write(uuid_) uuid_file.close() if os.path.exists(os.path.join(identifier_path, 'backup_url')): @@ -73,33 +77,56 @@ def store_identifiers(serial_number, uuid, backup_url): backup_url_file.write(backup_url) backup_url_file.close() + class RegisterError(Exception): pass -def register_laptop(url=REGISTER_URL): + +class _TimeoutHTTP(httplib.HTTP): + + def __init__(self, host='', port=None, strict=None, timeout=None): + if port == 0: + port = None + # FIXME: Depending on undocumented internals that can break between + # Python releases. Please have a look at SL #2350 + self._setup(self._connection_class(host, + port, strict, timeout=_REGISTER_TIMEOUT)) + + +class _TimeoutTransport(xmlrpclib.Transport): + + def make_connection(self, host): + host, extra_headers, x509_ = self.get_host_info(host) + return _TimeoutHTTP(host, timeout=_REGISTER_TIMEOUT) + + +def register_laptop(url=_REGISTER_URL): profile = get_profile() client = gconf.client_get_default() - if have_ofw_tree(): - sn = read_ofw('mfg-data/SN') - uuid_ = read_ofw('mfg-data/U#') + if _have_ofw_tree(): + sn = _read_ofw('mfg-data/SN') + uuid_ = _read_ofw('mfg-data/U#') sn = sn or 'SHF00000000' uuid_ = uuid_ or '00000000-0000-0000-0000-000000000000' else: - sn = generate_serial_number() + sn = _generate_serial_number() uuid_ = str(uuid.uuid1()) - setting_name = '/desktop/sugar/collaboration/jabber_server' - jabber_server = client.get_string(setting_name) - store_identifiers(sn, uuid_, jabber_server) + + setting_name = '/desktop/sugar/collaboration/jabber_server' + jabber_server = client.get_string(setting_name) + _store_identifiers(sn, uuid_, jabber_server) + + if jabber_server: url = 'http://' + jabber_server + ':8080/' nick = client.get_string('/desktop/sugar/user/nick') - server = ServerProxy(url) + server = xmlrpclib.ServerProxy(url, _TimeoutTransport()) try: data = server.register(sn, nick, uuid_, profile.pubkey) - except (Error, TypeError, socket.error): + except (xmlrpclib.Error, TypeError, socket.error): logging.exception('Registration: cannot connect to server') raise RegisterError(_('Cannot connect to the server.')) @@ -114,10 +141,12 @@ def register_laptop(url=REGISTER_URL): return True -def have_ofw_tree(): + +def _have_ofw_tree(): return os.path.exists('/ofw') -def read_ofw(path): + +def _read_ofw(path): path = os.path.join('/ofw', path) if not os.path.exists(path): return None diff --git a/src/jarabe/desktop/snowflakelayout.py b/src/jarabe/desktop/snowflakelayout.py index 5782cff..e4963ba 100644 --- a/src/jarabe/desktop/snowflakelayout.py +++ b/src/jarabe/desktop/snowflakelayout.py @@ -21,11 +21,14 @@ import hippo from sugar.graphics import style + _BASE_DISTANCE = style.zoom(25) _CHILDREN_FACTOR = style.zoom(3) + class SnowflakeLayout(gobject.GObject, hippo.CanvasLayout): __gtype_name__ = 'SugarSnowflakeLayout' + def __init__(self): gobject.GObject.__init__(self) self._nflakes = 0 diff --git a/src/jarabe/desktop/spreadlayout.py b/src/jarabe/desktop/spreadlayout.py index ffc5bc7..9200361 100644 --- a/src/jarabe/desktop/spreadlayout.py +++ b/src/jarabe/desktop/spreadlayout.py @@ -22,10 +22,13 @@ from sugar.graphics import style from jarabe.desktop.grid import Grid + _CELL_SIZE = 4.0 + class SpreadLayout(gobject.GObject, hippo.CanvasLayout): __gtype_name__ = 'SugarSpreadLayout' + def __init__(self): gobject.GObject.__init__(self) self._box = None @@ -80,4 +83,3 @@ class SpreadLayout(gobject.GObject, hippo.CanvasLayout): def _grid_child_changed_cb(self, grid, child): child.emit_request_changed() - diff --git a/src/jarabe/desktop/transitionbox.py b/src/jarabe/desktop/transitionbox.py index cf9e0d6..4042044 100644 --- a/src/jarabe/desktop/transitionbox.py +++ b/src/jarabe/desktop/transitionbox.py @@ -23,6 +23,7 @@ from sugar.graphics import animator from jarabe.model.buddy import get_owner_instance from jarabe.view.buddyicon import BuddyIcon + class _Animation(animator.Animation): def __init__(self, icon, start_size, end_size): animator.Animation.__init__(self, 0.0, 1.0) @@ -35,8 +36,10 @@ class _Animation(animator.Animation): d = (self.end_size - self.start_size) * current self._icon.props.size = self.start_size + d + class _Layout(gobject.GObject, hippo.CanvasLayout): __gtype_name__ = 'SugarTransitionBoxLayout' + def __init__(self): gobject.GObject.__init__(self) self._box = None @@ -60,12 +63,12 @@ class _Layout(gobject.GObject, hippo.CanvasLayout): y + (height - child_height) / 2, child_width, child_height, origin_changed) + class TransitionBox(hippo.Canvas): __gtype_name__ = 'SugarTransitionBox' __gsignals__ = { - 'completed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) + 'completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), } def __init__(self): |