[Sugar-devel] [RFC] Content support

Daniel Drake dsd at laptop.org
Sat Jun 29 13:54:13 EDT 2013


Hi,

Content bundles have long been both a crucial part of the OLPC-Sugar
offering, and a pain through having some deficiencies.
http://wiki.laptop.org/go/Creating_a_collection

They are important because it is the only easy way for a deployment to
add pre-made content to Sugar (e.g. books). The strong point of the design
here is that beyond a not-too-strange library.info metadata file, you
do not have to interact with anything too technical (e.g. python) beyond
the HTML content itself. It is something that seems to fall within
capabilities of deployment teams without much difficulty, whereas activity
development is often a painful step up.

They are quite widely used and in my experience visiting deployments
"how do we add our content to the laptop" is a very frequent question - I
always ran training sessions on content bundles in response.

However they are a pain because Sugar never really supported them very well.
Sugar can launch them from the Journal, but shipped content that the user
has never opened before does not exist in the Journal, so there was something
missing here.

To fill the gap, OLPC added a system (olpc-library) to produce a HTML index
of content bundles and this is the Browse homepage, but that isn't great
either - it's not part of Sugar where it should be, and users have to open
the web browser as if they are going online when they are just looking to
open some preinstalled content.

With my recent work on automatic activity updates, we had to add content
bundles to the bundle registry so that they will be updated appropriately.
Now that this is done, it is very easy to remove this deficiency. The small
patch below makes content bundles appear alongside activities, in the list
and favourites views. They are launched as expected with a click.

It does need some uninteresting tweaks in the bundle classes in
sugar-toolkit-gtk3 as well, but the real bulk of the change is here.
Any thoughts/comments?
---
 src/jarabe/desktop/activitieslist.py |  3 ---
 src/jarabe/desktop/favoritesview.py  |  7 -------
 src/jarabe/journal/misc.py           | 25 ++++++++++++-------------
 src/jarabe/model/bundleregistry.py   |  2 --
 4 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py
index 02e5f01..e369dd4 100644
--- a/src/jarabe/desktop/activitieslist.py
+++ b/src/jarabe/desktop/activitieslist.py
@@ -32,7 +32,6 @@ from sugar3.graphics.icon import Icon, CellRendererIcon
 from sugar3.graphics.xocolor import XoColor
 from sugar3.graphics.alert import Alert
 from sugar3.graphics.palettemenu import PaletteMenuItem
-from sugar3.bundle.activitybundle import ActivityBundle
 
 from jarabe.model import bundleregistry
 from jarabe.view.palettes import ActivityPalette
@@ -227,8 +226,6 @@ class ListModel(Gtk.TreeModelSort):
                 return
 
     def _add_activity(self, activity_info):
-        if not isinstance(activity_info, ActivityBundle):
-            return
         if activity_info.get_bundle_id() == 'org.laptop.JournalActivity':
             return
 
diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py
index dbdcf87..5f3bc65 100644
--- a/src/jarabe/desktop/favoritesview.py
+++ b/src/jarabe/desktop/favoritesview.py
@@ -35,7 +35,6 @@ from sugar3.graphics.xocolor import XoColor
 from sugar3.activity import activityfactory
 from sugar3 import dispatch
 from sugar3.datastore import datastore
-from sugar3.bundle.activitybundle import ActivityBundle
 
 from jarabe.view.palettes import JournalPalette
 from jarabe.view.palettes import CurrentActivityPalette
@@ -158,8 +157,6 @@ class FavoritesView(ViewContainer):
             self.set_layout(self._layout)
             registry = bundleregistry.get_registry()
             for info in registry:
-                if not isinstance(info, ActivityBundle):
-                    continue
                 if registry.is_bundle_favorite(info.get_bundle_id(),
                                                info.get_activity_version()):
                     self._add_activity(info)
@@ -292,8 +289,6 @@ class FavoritesView(ViewContainer):
         registry = bundleregistry.get_registry()
 
         for info in registry:
-            if not isinstance(info, ActivityBundle):
-                continue
             if registry.is_bundle_favorite(info.get_bundle_id(),
                                            info.get_activity_version()):
                 self._add_activity(info)
@@ -312,8 +307,6 @@ class FavoritesView(ViewContainer):
         icon.show()
 
     def __activity_added_cb(self, activity_registry, activity_info):
-        if not isinstance(activity_info, ActivityBundle):
-            return
         registry = bundleregistry.get_registry()
         if registry.is_bundle_favorite(activity_info.get_bundle_id(),
                                        activity_info.get_activity_version()):
diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py
index 160de94..6ecd37a 100644
--- a/src/jarabe/journal/misc.py
+++ b/src/jarabe/journal/misc.py
@@ -185,19 +185,7 @@ def resume(metadata, bundle_id=None, force_bundle_downgrade=False):
         uri = None
         activity_bundle_id = None
 
-        if is_activity_bundle(metadata):
-            activity_bundle_id = ds_bundle.get_bundle_id()
-        if is_content_bundle(metadata):
-            activities = _get_activities_for_mime('text/html')
-            if len(activities) == 0:
-                logging.warning('No activity can open HTML content bundles')
-                return
-
-            activity_bundle_id = activities[0].get_bundle_id()
-            uri = ds_bundle.get_start_uri()
-            logging.debug('Launching content bundle with uri %s', uri)
-
-        activity_bundle = registry.get_bundle(activity_bundle_id)
+        activity_bundle = registry.get_bundle(ds_bundle.get_bundle_id())
         if activity_bundle is not None:
             launch(activity_bundle, uri=uri)
         return
@@ -232,6 +220,17 @@ def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,
     logging.debug('launch bundle_id=%s activity_id=%s object_id=%s uri=%s',
                   bundle.get_bundle_id(), activity_id, object_id, uri)
 
+    if isinstance(bundle, ContentBundle):
+        # Content bundles are a special case: we treat them as launching
+        # Browse with a specific URI.
+        uri = bundle.get_start_uri()
+        activities = _get_activities_for_mime('text/html')
+        if len(activities) == 0:
+            logging.error("No browser available for content bundle")
+            return
+        bundle = activities[0]
+        logging.debug('Launching content bundle with uri %s', uri)
+
     shell_model = shell.get_model()
     activity = shell_model.get_activity_by_id(activity_id)
     if activity is not None:
-- 
1.8.1.4



More information about the Sugar-devel mailing list