[Sugar-devel] [DESIGN] Downgrading activities not allowed. (SL#2164)

Aleksey Lim alsroot at member.fsf.org
Sat Oct 16 09:14:23 EDT 2010


On Sat, Oct 16, 2010 at 01:31:02PM +0530, shanjit at seeta.in wrote:
> Downgrading an activity is now made possible. When a .xo file of a version older than the currently installed version is clicked, a downgrading option is made available, by popping up of a confirmation alert. Depending upton the choice selected you can downgrade the activity.

Do we have designers feedback about should downgrade alert be a window
or regular alert in Journal (didn't find something in ML).

(btw I got noting while trying to resume older versin .xo)

> v1 -> v2. Named according to the nomenclature suggested,inline function used,signal emission condition revised,global variables removed.
> 
> v2 -> v3. Taking care of all calling of misc.resume.
> Signed-off-by: Shanjit Singh Jajmann <shanjit at seeta.in>, Anubhav Aggarwal <anubhav at seeta.in>
> ---
>  src/jarabe/journal/misc.py         |   29 +++++---
>  src/jarabe/journal/versionalert.py |  121 ++++++++++++++++++++++++++++++++++++
>  src/jarabe/model/bundleregistry.py |    9 ++-
>  3 files changed, 145 insertions(+), 14 deletions(-)
>  create mode 100644 src/jarabe/journal/versionalert.py
> 
> diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py
> index 32a2847..99ea2d4 100644
> --- a/src/jarabe/journal/misc.py
> +++ b/src/jarabe/journal/misc.py
> @@ -30,6 +30,7 @@ from sugar.graphics.xocolor import XoColor
>  from sugar import mime
>  from sugar.bundle.activitybundle import ActivityBundle
>  from sugar.bundle.contentbundle import ContentBundle
> +from sugar.bundle.bundle import AlreadyInstalledException
>  from sugar import util
>  
>  from jarabe.view import launcher
> @@ -150,6 +151,7 @@ def get_activities(metadata):
>  
>  def resume(metadata, bundle_id=None):
>      registry = bundleregistry.get_registry()
> +    version_downgrade = False
>  
>      if is_activity_bundle(metadata) and bundle_id is None:
>  
> @@ -159,20 +161,25 @@ def resume(metadata, bundle_id=None):
>          bundle = ActivityBundle(file_path)
>          if not registry.is_installed(bundle):
>              logging.debug('Installing activity bundle')
> -            registry.install(bundle)
> +            try:
> +                registry.install(bundle)
> +            except AlreadyInstalledException:
> +                v_alert = VersionAlert()
> +                v_alert.give_bundle(bundle)
> +                version_downgrade= True
>          else:
>              logging.debug('Upgrading activity bundle')
>              registry.upgrade(bundle)
> -
> -        logging.debug('activityfactory.creating bundle with id %r',
> -                        bundle.get_bundle_id())
> -        installed_bundle = registry.get_bundle(bundle.get_bundle_id())
> -        if installed_bundle:
> -            launch(installed_bundle)
> -        else:
> -            logging.error('Bundle %r is not installed.',
> -                          bundle.get_bundle_id())
> -
> +        if not version_downgrade:
> +            logging.debug('activityfactory.creating bundle with id %r',
> +                            bundle.get_bundle_id())
> +            installed_bundle = registry.get_bundle(bundle.get_bundle_id())
> +            if installed_bundle:
> +                launch(installed_bundle)
> +            else:
> +                logging.error('Bundle %r is not installed.',
> +                              bundle.get_bundle_id())
> + 
>      elif is_content_bundle(metadata) and bundle_id is None:
>  
>          logging.debug('Creating content bundle')
> diff --git a/src/jarabe/journal/versionalert.py b/src/jarabe/journal/versionalert.py
> new file mode 100644
> index 0000000..2f27a2f
> --- /dev/null
> +++ b/src/jarabe/journal/versionalert.py
> @@ -0,0 +1,121 @@
> +
> +# Copyright (C) 2008 One Laptop Per Child
> +#
> +# 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 gtk
> +from gettext import gettext as _
> +
> +from sugar.graphics import style
> +from jarabe.model import bundleregistry
> +from sugar.activity import activityfactory
> +
> +class VersionAlert(gtk.Window):
> +
> +    def __init__(self):
> +        gtk.Window.__init__(self)
> +
> +        self.set_border_width(style.LINE_WIDTH)
> +        offset = style.GRID_CELL_SIZE
> +        width = gtk.gdk.screen_width() - offset * 3
> +        height = gtk.gdk.screen_height() - offset * 8.5
> +        self.set_size_request(width, height)
> +        self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
> +        self.set_decorated(gtk.WINDOW_TOPLEVEL)
> +        self.set_resizable(False)
> +        self.set_modal(False)
> +        
> +        self._main_view = gtk.EventBox()
> +        self._vbox = gtk.VBox()
> +        self._vbox.set_spacing(style.DEFAULT_SPACING)
> +        self._vbox.set_border_width(style.GRID_CELL_SIZE - 30)
> +        self._main_view.modify_bg(gtk.STATE_NORMAL,
> +                                  style.COLOR_BLACK.get_gdk_color())
> +        self._main_view.add(self._vbox)
> +        self._vbox.show()
> +
> +        self._title = gtk.Label()
> +        self._title.modify_fg(gtk.STATE_NORMAL,
> +                              style.COLOR_WHITE.get_gdk_color())
> +        self._title.set_markup('<b>%s</b>' % _('Newer Version of the activity i'
> +                                               's found'))
> +        self._vbox.pack_start(self._title, False)
> +        self._title.show()
> +
> +	self._message = gtk.Label(_('Do you want to continue with its installat'
> +                                    'ion?'))
> +                                    
> +        self._message.modify_fg(gtk.STATE_NORMAL,
> +                              style.COLOR_WHITE.get_gdk_color())
> +        self._vbox.pack_start(self._message, False)
> +        self._message.show()
> +        
> +        self._hbox = gtk.HBox()
> +        self._hbox.set_spacing(style.DEFAULT_SPACING * 49)
> +       
> +
> +
> +        alignment = gtk.Alignment(xalign=0.5, yalign=0.5)
> +        self._hbox.pack_start(alignment, expand=False)
> +        alignment.show()
> +
> +        self._install_cancel = gtk.Button()
> +        self._install_cancel.set_label(_('Cancel'))
> +        alignment.add(self._install_cancel)
> +        self._install_cancel.show()
> +        self._install_cancel.connect('clicked', self.__install_cancel_cb)
> +
> +
> +        alignment = gtk.Alignment(xalign=0.5, yalign=0.5)
> +        self._hbox.pack_start(alignment, expand=False)
> +        alignment.show()
> +
> +        self._install_ok = gtk.Button()
> +        self._install_ok.set_label(_('  Ok  '))
> +        alignment.add(self._install_ok)
> +        self._install_ok.show()
> +        self._install_ok.connect('clicked', self.__install_ok_cb)
> +        self._vbox.pack_start(self._hbox, False)
> +        self.add(self._main_view)
> +        
> +
> +        self._main_view.show()
> +        self._hbox.show()
> +        self.connect("realize", self.__realize_cb)
> +
> +    def give_bundle(self,bundle):
> +        self.bundle = bundle     
> +        return
> +
> +    def __realize_cb(self, widget):
> +        self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
> +        self.window.set_accept_focus(True)
> +
> +    def __install_cancel_cb(self, button):
> +        '''The opener will listen on the destroy signal
> +        '''
> +        self.destroy()
> + 
> +    def __install_ok_cb(self, button):
> +        registry = bundleregistry.get_registry()
> +        registry.install(self.bundle,uid=None,force_downgrade=True)
> +        installed_bundle = registry.get_bundle(self.bundle.get_bundle_id())
> +        if installed_bundle:
> +            activityfactory.create(installed_bundle)
> +        '''The opener will listen on the destroy signal
> +        '''
> +        self.destroy()   
> +   
> +
> diff --git a/src/jarabe/model/bundleregistry.py b/src/jarabe/model/bundleregistry.py
> index 699e339..e52914b 100644
> --- a/src/jarabe/model/bundleregistry.py
> +++ b/src/jarabe/model/bundleregistry.py
> @@ -373,14 +373,17 @@ class BundleRegistry(gobject.GObject):
>                  return True
>          return False
>  
> -    def install(self, bundle, uid=None):
> +    def install(self, bundle, uid=None,force_downgrade=False):
>          activities_path = env.get_user_activities_path()
>  
>          for installed_bundle in self._bundles:
>              if bundle.get_bundle_id() == installed_bundle.get_bundle_id() and \
>                      bundle.get_activity_version() <= \
> -                        installed_bundle.get_activity_version():
> -                raise AlreadyInstalledException
> +                         installed_bundle.get_activity_version():
> +                if not force_downgrade:
> +                    raise AlreadyInstalledException
> +                else:
> +                    self.uninstall(installed_bundle, force=True)    
>              elif bundle.get_bundle_id() == installed_bundle.get_bundle_id():
>                  self.uninstall(installed_bundle, force=True)
>  
> -- 
> 1.7.2.2
> 

-- 
Aleksey


More information about the Sugar-devel mailing list