Changes

m
Line 8: Line 8:  
== Summary ==
 
== Summary ==
   −
Package Journal objects to bundles to preserve sugar related metadata.
+
* package Journal objects to bundles to preserve sugar related metadata
 +
* support composite Journal objects e.g. in case of library bundles instead of having .xol in Journal and unpacked files in ~/Library, all library files will be represented by one Journal entry, could be opened in Browse(''[Metadata]/mime_type'' should be text/html for that purpose) and could be transformed back to .xo on demand(e.g. for uploading library in Browse's pick-file field).
 +
* Object Bundles exist only out of sugar (after uploading to the Journal .xo will be removed)
    
== Owner ==
 
== Owner ==
Line 17: Line 19:  
== Current status ==
 
== Current status ==
   −
* Targeted release: 0.86
+
* Targeted release:
* Last updated: Tue Jul 21 02:18:17 UTC 2009
+
* Last updated: Mon Jul 27 05:31:42 UTC 2009
* Percentage of completion: 0%
+
* Percentage of completion: 75%
    
== Detailed Description ==
 
== Detailed Description ==
   −
* Fix issues related to name mangling of Journal objects after uploading/downloading
+
This feature is a first approach to unified format for all types of bundles(in 0.86 it will support only Journal entries and new library bundles).
* Keep objects DS metadata while transfering between user-server-user
+
 
** we can package DS object to bundles (it relates to [[Unified Bundles]])
+
Object bundle should have ''METADATA'' file in the top directory of .xo bundle.
 +
 
 +
=== METADATA file ===
 +
 
 +
This file is in [http://docs.python.org/library/configparser.html INI] format which describes how to setup bundle.
 +
 
 +
Object bundle can be installed to Journal in two forms.
 +
 
 +
* '''Each file from bundle as separate Journal entry'''<br>files from bundle will be unpacked and installed as separate Journal entries, bundle itself will be removed(similar to .xoj)<br>final Journal entries can have ''activity'' field, so they are regular Journal entries that imported to Journal(w/o ''activity'' field) or created by activities(with ''activity'' field)<br>''METADATA'' should contain ''[Entry]'' sections for each Journal entry<br>if bundle has more then one entry, sections should be parted by different suffixes e.g. ''[Entry2]'', ''[Entry.additional]'' etc.
 +
 
 +
* '''Composite Journal entry'''<br>bundle will be installed as a composite object i.e. as a directory of packaged to the bundle files that are represented by one Journal entry<br>final Journal entry can't have ''activity'' field<br>''METADATA'' should contain only one ''[Bundle]'' section
 +
 
 +
METADATA file can have one or several sections(depends on installation method) that describe metadata fields of final entry(ies) in Journal.
 +
 
 +
{| border=1 cellpadding=3 style="border: 1px solid white; border-collapse: collapse; background: #e3e4e5;"
 +
|-style="background:#787878; color: white;"
 +
! Field
 +
! Flags
 +
! Notes
 +
|-
 +
| ''entry''
 +
| mandatory
 +
| if bundle is composite, ''entry'' defines access point to composite object (e.g. index.html for library bundles);<br>otherwise it defines file which will be installed to Journal
 +
|-
 +
| ''mime_type''
 +
| mandatory
 +
| define metadata for final Journal entry
 +
|-
 +
| ''uid''
 +
| ignored
 +
|-
 +
| ''*''
 +
| optional
 +
| any [[Features/Plain_Query_Format#System_terms|system]], [[Features/Plain_Query_Format#Users_predefined_terms|users predefined]] and arbitrary Datastore field
 +
|-
 +
|}
 +
 
 +
Any field in ''METADATA'' file can have ''_file'' suffix, in that case content of this field(substring w/o ''_file'' suffix) will be fetched from file inside of the bundle.
    
== Benefit to Sugar ==
 
== Benefit to Sugar ==
   −
Let users export/import Journal objects.
+
This feature is a first approach to unified format for all types of bundles.
 +
 
 +
Current implementation is similar to [http://wiki.laptop.org/go/Journal_entry_bundles .xoj] bundles except that:
 +
* it uses INI format instead of json(to make it more user-editing friendly)
 +
* any field's value could fetched from file inside of the bundle
 +
* supports multi-object bundles
    
== Scope ==
 
== Scope ==
   −
* shell code
+
* deprecate .xol bundles
* use object bundles for input fields in Browse
+
* deprecate [http://wiki.laptop.org/go/Journal_entry_bundles .xoj] bundles
 +
* provide unified format for metadata file in .xo bundles which should support
 +
** activities, former .xo bundles (0.88)
 +
** libraries, former .xol bundles (0.86)
 +
** journal entries, former .xoj bundles (0.86)
 +
* make Browse upload object bundles when the server says so
 +
* in an ideal implementation, composite feature should come from Datastore, but since DS has been extensively hacked in 0.86-0.88 cycles, for the first time, it could be a part of shell code
 +
 
 +
==== Implementation ====
 +
 
 +
* [http://git.sugarlabs.org/projects/sugar/repos/objectbundle sugar]
 +
* [http://git.sugarlabs.org/projects/sugar-toolkit/repos/objectbundle sugar-toolkit]
 +
* [http://git.sugarlabs.org/projects/browse/repos/objectbundle Browse]
 +
 
 +
Example of PHP code which could be used on server side to unpack object bundles to get metadata (like title, description, preview etc.)
 +
 
 +
require_once('Archive/Zip.php');
 +
 +
function rmtree($dir) {
 +
    $dir = "$dir";
 +
 +
    if ($dh = opendir($dir)) {
 +
        while (FALSE !== ($item = readdir($dh))) {
 +
            if ($item != '.' && $item != '..') {
 +
                $subdir = $dir . '/' . "$item";
 +
                if (is_dir($subdir))
 +
                    rmtree($subdir);
 +
                else
 +
                    unlink($subdir);
 +
            }
 +
        }
 +
        closedir($dh);
 +
        rmdir($dir);
 +
    }
 +
}
 +
 +
function unbundle($bundle) {
 +
    $zip = new Archive_Zip($bundle);
 +
 +
    $tmpdir = tempnam('/tmp', 'sugar');
 +
    if (file_exists($tmpdir))
 +
        unlink($tmpdir);
 +
    if (!mkdir($tmpdir)) {
 +
        return null;
 +
    }
 +
 +
    $out = $zip->extract(array('add_path' => $tmpdir, 'by_name' => array('METADATA')));
 +
    if (empty($out)) {
 +
        rmtree($tmpdir);
 +
        return null;
 +
    }
 +
 +
    $metadata = parse_ini_file($out[0]['filename'], true);
 +
    if (!$metadata) {
 +
        rmtree($tmpdir);
 +
        return null;
 +
    }
 +
 +
    $result = array();
 +
 +
    foreach ($metadata as $section => $items) {
 +
        if (!(substr($section, 0, 5) == 'Entry' || $section == 'Bundle'))
 +
            continue;
 +
        foreach ($items as $name => $value) {
 +
            if (substr($name, -5) == '_file') {
 +
                $name = substr($name, 0, -5);
 +
 +
                $out = $zip->extract(array('add_path' => $tmpdir, 'by_name' => array($value)));
 +
                if (empty($out)) {
 +
                    rmtree($tmpdir);
 +
                    return null;
 +
                }
 +
 +
                $value = file_get_contents($tmpdir.'/'.$value);
 +
            }
 +
            $result[$name] = $value;
 +
        }
 +
        break;
 +
    }
 +
 +
    rmtree($tmpdir);
 +
    return $result;
 +
}
 +
 +
// example usage of unbundle() function
 +
 +
$bundle = 'foo.xo';
 +
$metadata = unbundle($bundle);
 +
 +
if (!$metadata)
 +
    echo 'Can not open '.$bundle."\n";
 +
else
 +
    foreach ($metadata as $name => $value)
 +
        echo $name.'='.$value."\n";
    
== How To Test ==
 
== How To Test ==
    +
How to test non-composite objects:
 
# Create a new TurtleArt activity
 
# Create a new TurtleArt activity
 
# Upload the new entry to the SL wiki using Browse
 
# Upload the new entry to the SL wiki using Browse
 
# Use Browse to download the entry back to Journal
 
# Use Browse to download the entry back to Journal
 
# Resume it from Journal
 
# Resume it from Journal
 +
 +
How to test composite object (unfortunately [http://dev.sugarlabs.org/ticket/1101 #1101] prevents uploading bundles with library to wiki):
 +
# Download any .xol bundle
 +
# Activate it(it should be opened in Browse)
 +
# Upload Journal entry with library to SL wiki using Browse
 +
# Download .xo with library and open it
    
== User Experience ==
 
== User Experience ==
''If this feature is noticeable by its target audience, how will their experiences change as a result?  Describe what they will see or notice.''
+
 
 +
We could have HTTP servers(see [[Features/Server Objects Sharing]]) that request .xo files, in that case Browse will provide object bundle for chosen(in ObjectChooser) Journal entry otherwise Browse will upload raw Journal entries.
    
== Dependencies ==
 
== Dependencies ==
Line 56: Line 201:  
== Documentation ==
 
== Documentation ==
   −
''Is there upstream documentation on this feature, or notes you have written yourself?  Link to that material here so other interested developers can get involved.''
+
* [http://www.mail-archive.com/sugar-devel@lists.sugarlabs.org/msg06874.html Email thread]
 +
* [[Unified Bundles]]
 +
* [[User:Alsroot/trash/Unified Objects | Unified Objects]]
 +
* [http://wiki.laptop.org/go/Journal_entry_bundles Journal entry bundles]
 +
* [http://wiki.laptop.org/go/Bundle_concepts Bundle concepts]
 +
* [http://wiki.laptop.org/go/Manifest_Specification#Contents_Manifests MANIFEST specification]
    
== Release Notes ==
 
== Release Notes ==
Line 63: Line 213:  
== Comments and Discussion ==
 
== Comments and Discussion ==
 
* See [[{{TALKPAGENAME}}|discussion tab for this feature]] <!-- This adds a link to the "discussion" tab associated with your page.  This provides the ability to have ongoing comments or conversation without bogging down the main feature page -->
 
* See [[{{TALKPAGENAME}}|discussion tab for this feature]] <!-- This adds a link to the "discussion" tab associated with your page.  This provides the ability to have ongoing comments or conversation without bogging down the main feature page -->
  −
  −
[[Category:Feature Page Incomplete]]
  −
[[Category:Feature]]