Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Stone <michael@laptop.org>2010-06-27 02:15:22 (GMT)
committer Michael Stone <michael@laptop.org>2010-06-27 02:27:23 (GMT)
commitd2444a0fe27de7cc9e20547e7c58de325c044b2d (patch)
tree4f0787525ff6ef5edca71417cd20c1dab62f05af
parentf8811436a773424c19fa237751bc2e9f7b192782 (diff)
Add ds2xos conversion script to export journal entries as .xos session dirs.xos
This script converts the contents of whatever datastore is accessible on the current session bus to subdirectories of the current working directory. The purpose of this conversion is to encode all the data needed to show a nice journal entry into a wire format that is easy to process with standard filesystem tools and APIs. The chosen format consists of one ".xos session dir" per journal entry. A session dir is a directory: * whose name is URL-encoded with spaces encoded as pluses * which contains a directory named ".xos": * which contains a file called "metadata.json" * which, optionally, contains an image named "preview.png" * which, optionally, contains an executable called "resume" * and which may contain any other files or directories you like When creating session dirs from pre-existing journal entries: * we do our best to come up with human-meaningful and unique names by concatenating a few bytes of the journal entry's "activity_id" field onto the journal entry's "title" field separated by an underscore, * we try to create stand-alone "resume" files and to ensure that all the data that we put into such files is shell-quoted, and * we try to hard-link any files associated with the journal entry into our session dir with names derived from the title and mime-type of the stored file.
-rwxr-xr-xdatastore/bin/ds2xos133
1 files changed, 133 insertions, 0 deletions
diff --git a/datastore/bin/ds2xos b/datastore/bin/ds2xos
new file mode 100755
index 0000000..79565ff
--- /dev/null
+++ b/datastore/bin/ds2xos
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+from __future__ import with_statement, division
+
+import sys, cgitb
+cgitb.enable(format="plain")
+cgitb.handler = sys.excepthook.handle
+
+from pprint import pprint
+from sugar.datastore import datastore as ds
+from os.path import exists, join, splitext
+from os import makedirs, rename, link, chmod
+from commands import mkarg
+from errno import EEXIST
+from urllib import quote_plus
+from jarabe.model.bundleregistry import get_registry
+from sugar import env
+import cjson
+import sugar.mime
+
+def mkdir_p(path):
+ try: makedirs(path)
+ except OSError, e:
+ if e.errno == EEXIST: pass
+ else: raise
+
+def get_bundle(md):
+ return get_registry().get_bundle(str(md['activity']))
+
+def get_command(md, bundle):
+ command = bundle.get_command().split(' ')
+ command.extend(['-b', str(md['activity'])])
+ command.extend(['-a', str(md['activity_id'])])
+
+ if 'object_id' in md and md['object_id'] != "":
+ command.extend(['-o', str(md['object_id'])])
+ if 'uri' in md and md['uri'] != "":
+ command.extend(['-u', str(md['uri'])])
+
+ # if the command is in $BUNDLE_ROOT/bin, execute the absolute path so there
+ # is no need to mangle with the shell's PATH
+ if '/' not in command[0]:
+ bin_path = join(bundle.get_path(), 'bin')
+ absolute_path = join(bin_path, command[0])
+ if exists(absolute_path):
+ command[0] = absolute_path
+
+ return [mkarg(v)[1:] for v in command]
+
+def get_environ(md, bundle):
+ ret = {}
+ bin_path = join(bundle.get_path(), 'bin')
+ activity_root = env.get_profile_path(str(md['activity']))
+
+ ret['SUGAR_BUNDLE_PATH'] = bundle.get_path()
+ ret['SUGAR_BUNDLE_ID'] = str(md['activity'])
+ ret['SUGAR_ACTIVITY_ROOT'] = activity_root
+ ret['PATH'] = bin_path
+
+ if bundle.get_path().startswith(env.get_user_activities_path()):
+ ret['SUGAR_LOCALEDIR'] = join(bundle.get_path(), 'locale')
+
+ return ret
+
+def export(e):
+ md = e.metadata.get_dictionary()
+ md['object_id'] = e.object_id
+ print md['activity_id']
+
+ title = str(md.get('title', ''))
+ if 'activity_id' in md and md['activity_id'] != "":
+ title = title + "_" + str(md.get('activity_id', '')[0:8])
+ title = quote_plus(title)
+ print title
+
+ preview = md['preview']
+ del md['preview']
+
+ final_dir = title
+ dir = final_dir + ".tmp"
+
+ if exists(final_dir):
+ print 'already exists'
+ return
+
+ xos_dir = join(dir, ".xos")
+
+ mkdir_p(xos_dir)
+
+ with open(join(xos_dir, "metadata.json"), "w") as f:
+ f.write(cjson.encode(md))
+
+ with open(join(xos_dir, "preview.png"), "w") as f:
+ f.write(preview)
+
+ if e.file_path != "":
+ base, ext = splitext(title)
+ if ext == '':
+ mime_type = md['mime_type']
+ ext = sugar.mime.get_primary_extension(mime_type)
+ if ext == None: ext = ".bin"
+ else: ext = "." + ext
+ link(e.file_path, join(dir, base + ext))
+
+ if 'activity' in md and md['activity'] != '' and \
+ 'activity_id' in md and md['activity_id'] != '':
+ bundle = get_bundle(md)
+ cmd = get_command(md, bundle)
+ env = get_environ(md, bundle)
+ resume_path = join(xos_dir, "resume")
+ with open(resume_path, "w") as f:
+ f.write("#!/bin/bash\n")
+ f.write("cd" + mkarg(str(bundle.get_path())) + "\n")
+ f.write("env ")
+ for k, v in env.iteritems():
+ if k == 'PATH':
+ f.write('%s=%s' % (mkarg(k)[1:], mkarg(v)[1:]))
+ f.write(':"$PATH"\\\n ')
+ else:
+ f.write('%s=%s\\\n ' % (mkarg(k)[1:], mkarg(v)[1:]))
+ f.write(" ".join(cmd) + "\n")
+ chmod(resume_path, 0755)
+
+ rename(dir, final_dir)
+
+def main():
+ results, count = ds.find({})
+
+ for e in results:
+ try: export(e)
+ except: cgitb.handler()
+ print
+
+main()