[Dextrose] [PATCH v6 sugar] Downgrading activities not allowed. (SL #2164)
Aleksey Lim
alsroot at member.fsf.org
Sun Oct 24 12:23:22 EDT 2010
On Sun, Oct 24, 2010 at 12:21:13AM +0530, anubhav at seeta.in wrote:
> Activity can be downgraded on the availability of an older .xo version of an
> activity. An alert pops up on downloading an older .xo file of an activity,
> which asks the user to make a selection on whether to move to an older
> activity version or not.
>
> Co-authored-by: Anubhav Aggarwal <anubhav at seeta.in>, Shanjit Singh Jajmann <shanjit at seeta.in>
> ---
>
> v1 -> v2. Inline function used, signal emission condition revised and global
> variables removed. Recommendations by James Cameron and Aleksey Lim added.
>
> v2 -> v3. Used misc.resume.
>
> v3 -> v4. Changes in the copyright of the new file.
>
> v4 -> v5. Alert shown in the same window as the journal.
>
> v5 -> v6. Static variable removed, name of the functions changed.
> Recommendations by James Cameron and Aleksey Lim added.
>
> src/jarabe/journal/journalactivity.py | 6 ++--
> src/jarabe/journal/journalwindow.py | 33 +++++++++++++++++++
> src/jarabe/journal/misc.py | 56 +++++++++++++++++++++++++++------
> src/jarabe/model/bundleregistry.py | 7 +++-
> 4 files changed, 87 insertions(+), 15 deletions(-)
> create mode 100644 src/jarabe/journal/journalwindow.py
>
> diff --git a/src/jarabe/journal/journalactivity.py b/src/jarabe/journal/journalactivity.py
> index 44cc018..a48063b 100644
> --- a/src/jarabe/journal/journalactivity.py
> +++ b/src/jarabe/journal/journalactivity.py
> @@ -44,6 +44,7 @@ from jarabe.journal.journalentrybundle import JournalEntryBundle
> from jarabe.journal.objectchooser import ObjectChooser
> from jarabe.journal.modalalert import ModalAlert
> from jarabe.journal import model
> +from jarabe.journal.journalwindow import JournalWindow
>
> J_DBUS_SERVICE = 'org.laptop.Journal'
> J_DBUS_INTERFACE = 'org.laptop.Journal'
> @@ -102,11 +103,10 @@ class JournalActivityDBusService(dbus.service.Object):
> def ObjectChooserCancelled(self, chooser_id):
> pass
>
> -class JournalActivity(Window):
> +class JournalActivity(JournalWindow):
> def __init__(self):
> logging.debug("STARTUP: Loading the journal")
> - Window.__init__(self)
> -
> + JournalWindow.__init__(self)
> self.set_title(_('Journal'))
>
> self._main_view = None
> diff --git a/src/jarabe/journal/journalwindow.py b/src/jarabe/journal/journalwindow.py
> new file mode 100644
> index 0000000..957f1eb
> --- /dev/null
> +++ b/src/jarabe/journal/journalwindow.py
> @@ -0,0 +1,33 @@
> +#Copyright (C) 2010 Software for Education, Entertainment and Training Activities
> +#
> +# 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 sugar.graphics.window import Window
> +
> +
> +_journal_window = None
> +
> +
> +class JournalWindow(Window):
> +
> + def __init__(self):
> + global _journal_window
> + Window.__init__(self)
> + _journal_window = self
> +
> +
> +def get_journal_window():
> + return _journal_window
> diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py
> index 32a2847..388837c 100644
> --- a/src/jarabe/journal/misc.py
> +++ b/src/jarabe/journal/misc.py
> @@ -27,8 +27,10 @@ from sugar.activity import activityfactory
> from sugar.activity.activityhandle import ActivityHandle
> from sugar.graphics.icon import get_icon_file_name
> from sugar.graphics.xocolor import XoColor
> +from sugar.graphics.alert import ConfirmationAlert
> from sugar import mime
> from sugar.bundle.activitybundle import ActivityBundle
> +from sugar.bundle.bundle import AlreadyInstalledException
> from sugar.bundle.contentbundle import ContentBundle
> from sugar import util
>
> @@ -36,6 +38,7 @@ from jarabe.view import launcher
> from jarabe.model import bundleregistry, shell
> from jarabe.journal.journalentrybundle import JournalEntryBundle
> from jarabe.journal import model
> +from jarabe.journal import journalwindow
>
> def _get_icon_for_mime(mime_type):
> generic_types = mime.get_all_generic_types()
> @@ -150,6 +153,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,19 +163,24 @@ 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:
> + journal_window = journalwindow.get_journal_window()
> + _downgrade_option_alert(metadata, journal_window)
> + 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:
>
> @@ -215,6 +224,13 @@ def resume(metadata, bundle_id=None):
> launch(bundle, activity_id=activity_id, object_id=object_id,
> color=get_icon_color(metadata))
>
> +def _downgrade_install_bundle(metadata):
> + file_path = model.get_file(metadata['uid'])
> + bundle = ActivityBundle(file_path)
> + registry = bundleregistry.get_registry()
> + registry.install(bundle, force_downgrade=True)
> + resume(metadata)
> +
> def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,
> invited=False):
> if activity_id is None or not activity_id:
> @@ -239,6 +255,26 @@ def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,
> object_id=object_id, uri=uri, invited=invited)
> activityfactory.create(bundle, activity_handle)
>
> +def _downgrade_option_alert(metadata, journal_window):
> + alert = ConfirmationAlert()
> + file_path = model.get_file(metadata['uid'])
> + bundle = ActivityBundle(file_path)
> + alert.props.title = _('Older Version Of ' + bundle.get_name() \
> + + ' Activity')
> + alert.props.msg = _('Do you want to downgrade to version ' + \
> + str(bundle.get_activity_version()) + ' ?')
this usage of _() will break translation, text in _() should be a static
string, better to use something like:
alert.props.title = _('Older Version Of %(bundle_name)s Activity') % bundle.get_name()
> + alert.connect('response', _downgrade_alert_response_cb, metadata, \
> + journal_window)
> + journal_window.add_alert(alert)
> + alert.show()
> +
> +def _downgrade_alert_response_cb(alert, response_id, metadata, journal_window):
> + if response_id is gtk.RESPONSE_OK:
> + journal_window.remove_alert(alert)
> + _downgrade_install_bundle(metadata)
> + elif response_id is gtk.RESPONSE_CANCEL:
> + journal_window.remove_alert(alert)
> +
> def is_activity_bundle(metadata):
> mime_type = metadata.get('mime_type', '')
> return mime_type == ActivityBundle.MIME_TYPE or \
There is no need to pass journal_window as argument to several
methods, it can be all time get via journalwindow.get_journal_window().
Also, what about simpler scheme in case of popping up logic:
def resume(metadata, bundle_id=None):
...
if not registry.is_installed(bundle):
logging.debug('Installing activity bundle')
try:
registry.install(bundle)
except AlreadyInstalledException:
_downgrade_option_alert(bundle)
else:
logging.debug('Upgrading activity bundle')
registry.upgrade(bundle)
_install_bundle(bundle)
...
def _install_bundle(bundle):
registry = bundleregistry.get_registry()
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())
def _downgrade_option_alert(bundle)
...
def _downgrade_alert_response_cb(alert, response_id, bundle):
...
_install_bundle(bundle)
> diff --git a/src/jarabe/model/bundleregistry.py b/src/jarabe/model/bundleregistry.py
> index 699e339..06a1d3a 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
> + if not force_downgrade:
> + raise AlreadyInstalledException
> + if force_downgrade:
> + self.uninstall(installed_bundle, force=True)
> elif bundle.get_bundle_id() == installed_bundle.get_bundle_id():
> self.uninstall(installed_bundle, force=True)
>
> --
> 1.7.0.4
>
--
Aleksey
More information about the Dextrose
mailing list