<div dir="ltr"><div>One of the things that would be needed to fully support content bundles (which I have experimented with creating), would to be able to host them in ASLO, it would also be important to clarify the process of deleting a content bundle, which used to require a manual editting of some file to make it go away from the OLPC Library section in Browse.<br>

<br></div><div>I would really like ot see improved management of content bundles and I am very supportive of steps to make th4em easier to work with.<br></div><div><br></div>cjl<br></div><div class="gmail_extra"><br><br>
<div class="gmail_quote">
On Sat, Jun 29, 2013 at 1:54 PM, Daniel Drake <span dir="ltr"><<a href="mailto:dsd@laptop.org" target="_blank">dsd@laptop.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Hi,<br>
<br>
Content bundles have long been both a crucial part of the OLPC-Sugar<br>
offering, and a pain through having some deficiencies.<br>
<a href="http://wiki.laptop.org/go/Creating_a_collection" target="_blank">http://wiki.laptop.org/go/Creating_a_collection</a><br>
<br>
They are important because it is the only easy way for a deployment to<br>
add pre-made content to Sugar (e.g. books). The strong point of the design<br>
here is that beyond a not-too-strange <a href="http://library.info" target="_blank">library.info</a> metadata file, you<br>
do not have to interact with anything too technical (e.g. python) beyond<br>
the HTML content itself. It is something that seems to fall within<br>
capabilities of deployment teams without much difficulty, whereas activity<br>
development is often a painful step up.<br>
<br>
They are quite widely used and in my experience visiting deployments<br>
"how do we add our content to the laptop" is a very frequent question - I<br>
always ran training sessions on content bundles in response.<br>
<br>
However they are a pain because Sugar never really supported them very well.<br>
Sugar can launch them from the Journal, but shipped content that the user<br>
has never opened before does not exist in the Journal, so there was something<br>
missing here.<br>
<br>
To fill the gap, OLPC added a system (olpc-library) to produce a HTML index<br>
of content bundles and this is the Browse homepage, but that isn't great<br>
either - it's not part of Sugar where it should be, and users have to open<br>
the web browser as if they are going online when they are just looking to<br>
open some preinstalled content.<br>
<br>
With my recent work on automatic activity updates, we had to add content<br>
bundles to the bundle registry so that they will be updated appropriately.<br>
Now that this is done, it is very easy to remove this deficiency. The small<br>
patch below makes content bundles appear alongside activities, in the list<br>
and favourites views. They are launched as expected with a click.<br>
<br>
It does need some uninteresting tweaks in the bundle classes in<br>
sugar-toolkit-gtk3 as well, but the real bulk of the change is here.<br>
Any thoughts/comments?<br>
---<br>
 src/jarabe/desktop/activitieslist.py |  3 ---<br>
 src/jarabe/desktop/favoritesview.py  |  7 -------<br>
 src/jarabe/journal/misc.py           | 25 ++++++++++++-------------<br>
 src/jarabe/model/bundleregistry.py   |  2 --<br>
 4 files changed, 12 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py<br>
index 02e5f01..e369dd4 100644<br>
--- a/src/jarabe/desktop/activitieslist.py<br>
+++ b/src/jarabe/desktop/activitieslist.py<br>
@@ -32,7 +32,6 @@ from sugar3.graphics.icon import Icon, CellRendererIcon<br>
 from sugar3.graphics.xocolor import XoColor<br>
 from sugar3.graphics.alert import Alert<br>
 from sugar3.graphics.palettemenu import PaletteMenuItem<br>
-from sugar3.bundle.activitybundle import ActivityBundle<br>
<br>
 from jarabe.model import bundleregistry<br>
 from jarabe.view.palettes import ActivityPalette<br>
@@ -227,8 +226,6 @@ class ListModel(Gtk.TreeModelSort):<br>
                 return<br>
<br>
     def _add_activity(self, activity_info):<br>
-        if not isinstance(activity_info, ActivityBundle):<br>
-            return<br>
         if activity_info.get_bundle_id() == 'org.laptop.JournalActivity':<br>
             return<br>
<br>
diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py<br>
index dbdcf87..5f3bc65 100644<br>
--- a/src/jarabe/desktop/favoritesview.py<br>
+++ b/src/jarabe/desktop/favoritesview.py<br>
@@ -35,7 +35,6 @@ from sugar3.graphics.xocolor import XoColor<br>
 from sugar3.activity import activityfactory<br>
 from sugar3 import dispatch<br>
 from sugar3.datastore import datastore<br>
-from sugar3.bundle.activitybundle import ActivityBundle<br>
<br>
 from jarabe.view.palettes import JournalPalette<br>
 from jarabe.view.palettes import CurrentActivityPalette<br>
@@ -158,8 +157,6 @@ class FavoritesView(ViewContainer):<br>
             self.set_layout(self._layout)<br>
             registry = bundleregistry.get_registry()<br>
             for info in registry:<br>
-                if not isinstance(info, ActivityBundle):<br>
-                    continue<br>
                 if registry.is_bundle_favorite(info.get_bundle_id(),<br>
                                                info.get_activity_version()):<br>
                     self._add_activity(info)<br>
@@ -292,8 +289,6 @@ class FavoritesView(ViewContainer):<br>
         registry = bundleregistry.get_registry()<br>
<br>
         for info in registry:<br>
-            if not isinstance(info, ActivityBundle):<br>
-                continue<br>
             if registry.is_bundle_favorite(info.get_bundle_id(),<br>
                                            info.get_activity_version()):<br>
                 self._add_activity(info)<br>
@@ -312,8 +307,6 @@ class FavoritesView(ViewContainer):<br>
         icon.show()<br>
<br>
     def __activity_added_cb(self, activity_registry, activity_info):<br>
-        if not isinstance(activity_info, ActivityBundle):<br>
-            return<br>
         registry = bundleregistry.get_registry()<br>
         if registry.is_bundle_favorite(activity_info.get_bundle_id(),<br>
                                        activity_info.get_activity_version()):<br>
diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py<br>
index 160de94..6ecd37a 100644<br>
--- a/src/jarabe/journal/misc.py<br>
+++ b/src/jarabe/journal/misc.py<br>
@@ -185,19 +185,7 @@ def resume(metadata, bundle_id=None, force_bundle_downgrade=False):<br>
         uri = None<br>
         activity_bundle_id = None<br>
<br>
-        if is_activity_bundle(metadata):<br>
-            activity_bundle_id = ds_bundle.get_bundle_id()<br>
-        if is_content_bundle(metadata):<br>
-            activities = _get_activities_for_mime('text/html')<br>
-            if len(activities) == 0:<br>
-                logging.warning('No activity can open HTML content bundles')<br>
-                return<br>
-<br>
-            activity_bundle_id = activities[0].get_bundle_id()<br>
-            uri = ds_bundle.get_start_uri()<br>
-            logging.debug('Launching content bundle with uri %s', uri)<br>
-<br>
-        activity_bundle = registry.get_bundle(activity_bundle_id)<br>
+        activity_bundle = registry.get_bundle(ds_bundle.get_bundle_id())<br>
         if activity_bundle is not None:<br>
             launch(activity_bundle, uri=uri)<br>
         return<br>
@@ -232,6 +220,17 @@ def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,<br>
     logging.debug('launch bundle_id=%s activity_id=%s object_id=%s uri=%s',<br>
                   bundle.get_bundle_id(), activity_id, object_id, uri)<br>
<br>
+    if isinstance(bundle, ContentBundle):<br>
+        # Content bundles are a special case: we treat them as launching<br>
+        # Browse with a specific URI.<br>
+        uri = bundle.get_start_uri()<br>
+        activities = _get_activities_for_mime('text/html')<br>
+        if len(activities) == 0:<br>
+            logging.error("No browser available for content bundle")<br>
+            return<br>
+        bundle = activities[0]<br>
+        logging.debug('Launching content bundle with uri %s', uri)<br>
+<br>
     shell_model = shell.get_model()<br>
     activity = shell_model.get_activity_by_id(activity_id)<br>
     if activity is not None:<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.4<br>
<br>
_______________________________________________<br>
Sugar-devel mailing list<br>
<a href="mailto:Sugar-devel@lists.sugarlabs.org">Sugar-devel@lists.sugarlabs.org</a><br>
<a href="http://lists.sugarlabs.org/listinfo/sugar-devel" target="_blank">http://lists.sugarlabs.org/listinfo/sugar-devel</a><br>
</font></span></blockquote></div><br></div>