Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/journal/model.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/journal/model.py')
-rw-r--r--src/jarabe/journal/model.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index 5285a7c..0919b52 100644
--- a/src/jarabe/journal/model.py
+++ b/src/jarabe/journal/model.py
@@ -14,6 +14,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import cPickle
import logging
import os
import errno
@@ -26,6 +27,7 @@ from stat import S_IFLNK, S_IFMT, S_IFDIR, S_IFREG
import re
from operator import itemgetter
import simplejson
+import xapian
from gettext import gettext as _
import gobject
@@ -50,6 +52,7 @@ PROPERTIES = ['activity', 'activity_id', 'buddies', 'bundle_id',
MIN_PAGES_TO_CACHE = 3
MAX_PAGES_TO_CACHE = 5
+JOURNAL_0_METADATA_DIR = '.olpc.store'
JOURNAL_METADATA_DIR = '.Sugar-Metadata'
_datastore = None
@@ -816,3 +819,118 @@ def get_documents_path():
if exception.errno != errno.ENOENT:
logging.exception('Could not run xdg-user-dir')
return None
+
+
+def _get_id(document):
+ """Get the ID for the document in the xapian database."""
+ tl = document.termlist()
+ try:
+ term = tl.skip_to('Q').term
+ if len(term) == 0 or term[0] != 'Q':
+ return None
+ return term[1:]
+ except StopIteration:
+ return None
+
+
+def convert_datastore_0_entries(root):
+ """Convert entries written by the datastore version 0.
+
+ The metadata and the preview will be written using the new
+ scheme for writing Journal entries to removable storage
+ devices.
+
+ - entries that do not have an associated file are not
+ converted.
+ - if an entry has no title we set it to Untitled and rename
+ the file accordingly, taking care of creating a unique
+ filename
+
+ """
+ try:
+ database = xapian.Database(os.path.join(root, JOURNAL_0_METADATA_DIR,
+ 'index'))
+ except xapian.DatabaseError:
+ logging.exception('Convert DS-0 Journal entries: error reading db: %s',
+ os.path.join(root, JOURNAL_0_METADATA_DIR, 'index'))
+ return
+
+ metadata_dir_path = os.path.join(root, JOURNAL_METADATA_DIR)
+ if not os.path.exists(metadata_dir_path):
+ try:
+ os.mkdir(metadata_dir_path)
+ except EnvironmentError:
+ logging.error('Convert DS-0 Journal entries: '
+ 'error creating the Journal metadata directory.')
+ return
+
+ for posting_item in database.postlist(''):
+ try:
+ document = database.get_document(posting_item.docid)
+ except xapian.DocNotFoundError, e:
+ logging.debug('Convert DS-0 Journal entries: error getting '
+ 'document %s: %s', posting_item.docid, e)
+ continue
+ _convert_entry(root, document)
+
+
+def _convert_entry(root, document):
+ try:
+ metadata_loaded = cPickle.loads(document.get_data())
+ except cPickle.PickleError, e:
+ logging.debug('Convert DS-0 Journal entries: '
+ 'error converting metadata: %s', e)
+ return
+
+ if not ('activity_id' in metadata_loaded and
+ 'mime_type' in metadata_loaded and
+ 'title' in metadata_loaded):
+ return
+
+ metadata = {}
+
+ uid = _get_id(document)
+ if uid is None:
+ return
+
+ for key, value in metadata_loaded.items():
+ metadata[str(key)] = str(value[0])
+
+ if 'uid' not in metadata:
+ metadata['uid'] = uid
+
+ filename = metadata.pop('filename', None)
+ if not filename:
+ return
+ if not os.path.exists(os.path.join(root, filename)):
+ return
+
+ if not metadata.get('title'):
+ metadata['title'] = _('Untitled')
+ fn = get_file_name(metadata['title'], metadata['mime_type'])
+ new_filename = get_unique_file_name(root, fn)
+ os.rename(os.path.join(root, filename),
+ os.path.join(root, new_filename))
+ filename = new_filename
+
+ preview_path = os.path.join(root, JOURNAL_0_METADATA_DIR,
+ 'preview', uid)
+ if os.path.exists(preview_path):
+ preview_fname = filename + '.preview'
+ new_preview_path = os.path.join(root, JOURNAL_METADATA_DIR,
+ preview_fname)
+ if not os.path.exists(new_preview_path):
+ shutil.copy(preview_path, new_preview_path)
+
+ metadata_fname = filename + '.metadata'
+ metadata_path = os.path.join(root, JOURNAL_METADATA_DIR,
+ metadata_fname)
+ if not os.path.exists(metadata_path):
+ (fh, fn) = tempfile.mkstemp(dir=root)
+ os.write(fh, simplejson.dumps(metadata))
+ os.close(fh)
+ os.rename(fn, metadata_path)
+
+ logging.debug('Convert DS-0 Journal entries: entry converted: '
+ 'file=%s metadata=%s',
+ os.path.join(root, filename), metadata)