Ticket #1636: 0001-Convert-Journal-entries-that-have-been-saved-to-a-st.patch

File 0001-Convert-Journal-entries-that-have-been-saved-to-a-st.patch, 6.1 KB (added by erikos, 12 years ago)

Convert Journal entries that have been saved to a storage device in 0.82 (branch master)

  • src/jarabe/journal/volumestoolbar.py

    From b5cdd7a722fdbfddc3ddf32e1ba5843955f569d1 Mon Sep 17 00:00:00 2001
    From: Simon Schampijer <simon@schampijer.de>
    Date: Tue, 8 Feb 2011 12:19:30 -0500
    Subject: [PATCH] Convert Journal entries that have been saved to a storage device in 0.82
    
    http://wiki.sugarlabs.org/go/Features/Journal_Entry_Sharing
    ---
     src/jarabe/journal/volumestoolbar.py |  124 +++++++++++++++++++++++++++++++++-
     1 files changed, 123 insertions(+), 1 deletions(-)
    
    diff --git a/src/jarabe/journal/volumestoolbar.py b/src/jarabe/journal/volumestoolbar.py
    index 2851a91..8a81119 100644
    a b  
    1 # Copyright (C) 2007, One Laptop Per Child
     1# Copyright (C) 2007, 2011, One Laptop Per Child
    22#
    33# This program is free software; you can redistribute it and/or modify
    44# it under the terms of the GNU General Public License as published by
    import gobject 
    2222import gio
    2323import gtk
    2424import gconf
     25import cPickle
     26import xapian
     27import json
     28import tempfile
     29import shutil
    2530
    2631from sugar.graphics.radiotoolbutton import RadioToolButton
    2732from sugar.graphics.palette import Palette
    from jarabe.journal import model 
    3136from jarabe.view.palettes import VolumePalette
    3237
    3338
     39_JOURNAL_0_METADATA_DIR = '.olpc.store'
     40
     41
     42def _get_id(document):
     43    """Get the ID for the document in the xapian database."""
     44    tl = document.termlist()
     45    try:
     46        term = tl.skip_to('Q').term
     47        if len(term) == 0 or term[0] != 'Q':
     48            return None
     49        return term[1:]
     50    except StopIteration:
     51        return None
     52
     53
     54def _convert_entries(root):
     55    """Converts the entries written by the datastore version 0.
     56    The metadata and the preview will be written using the new
     57    scheme for writing Journal entries to removable storage
     58    devices.
     59
     60    - entries that do not have an associated file are not
     61    converted.
     62    - if an entry has no title we set it to Untitled and rename
     63    the file accordingly, taking care of creating a unique
     64    filename
     65
     66    """
     67    try:
     68        database = xapian.Database(os.path.join(root, _JOURNAL_0_METADATA_DIR,
     69                                                'index'))
     70    except xapian.DatabaseError, e:
     71        logging.error('Convert DS-0 Journal entry. Error reading db: %s',
     72                      os.path.join(root, _JOURNAL_0_METADATA_DIR, 'index'))
     73        return
     74
     75    metadata_dir_path = os.path.join(root, model.JOURNAL_METADATA_DIR)
     76    if not os.path.exists(metadata_dir_path):
     77        os.mkdir(metadata_dir_path)
     78
     79    for i in range(1, database.get_lastdocid() + 1):
     80        try:
     81            document = database.get_document(i)
     82        except xapian.DocNotFoundError, e:
     83            logging.debug('Convert DS-0 Journal entry. ' \
     84                              'Error getting document %s: %s', i, e)
     85            continue
     86
     87        try:
     88            metadata_loaded = cPickle.loads(document.get_data())
     89        except cPickle.PickleError, e:
     90            logging.debug('Convert DS-0 Journal entry. ' \
     91                              'Error converting metadata: %s', e)
     92            continue
     93
     94        if 'activity_id' in metadata_loaded and \
     95                'mime_type' in metadata_loaded and \
     96                'title' in metadata_loaded:
     97            metadata = {}
     98
     99            uid = _get_id(document)
     100            if uid is None:
     101                continue
     102
     103            for key, value in metadata_loaded.items():
     104                metadata[str(key)] = str(value[0])
     105
     106            if 'uid' not in metadata:
     107                metadata['uid'] = uid
     108
     109            if 'filename' in metadata:
     110                filename = metadata['filename']
     111            else:
     112                continue
     113            if not os.path.exists(os.path.join(root, filename)):
     114                continue
     115
     116            if metadata['title'] == '':
     117                metadata['title'] = _('Untitled')
     118                fn = model.get_file_name(metadata['title'],
     119                                         metadata['mime_type'])
     120                new_filename = model.get_unique_file_name(root, fn)
     121                metadata['filename'] = new_filename
     122                os.rename(os.path.join(root, filename),
     123                          os.path.join(root, new_filename))
     124                filename = new_filename
     125
     126            preview_path = os.path.join(root, _JOURNAL_0_METADATA_DIR,
     127                                        'preview', uid)
     128            if os.path.exists(preview_path):
     129                preview_fname = filename + '.preview'
     130                new_preview_path = os.path.join(root,
     131                                                model.JOURNAL_METADATA_DIR,
     132                                                preview_fname)
     133                if not os.path.exists(new_preview_path):
     134                    metadata['preview'] = preview_fname
     135                    shutil.copy(preview_path, new_preview_path)
     136
     137            metadata_fname = filename + '.metadata'
     138            metadata_path = os.path.join(root, model.JOURNAL_METADATA_DIR,
     139                                         metadata_fname)
     140            if not os.path.exists(metadata_path):
     141                (fh, fn) = tempfile.mkstemp(dir=root)
     142                os.write(fh, json.dumps(metadata))
     143                os.close(fh)
     144                os.rename(fn, metadata_path)
     145
     146            logging.debug('Convert DS-0 Journal entry. Entry converted: ' \
     147                              'File=%s Metadata=%s',
     148                          os.path.join(root, filename), metadata)
     149
     150
    34151class VolumesToolbar(gtk.Toolbar):
    35152    __gtype_name__ = 'VolumesToolbar'
    36153
    class VolumesToolbar(gtk.Toolbar): 
    81198    def _add_button(self, mount):
    82199        logging.debug('VolumeToolbar._add_button: %r', mount.get_name())
    83200
     201        if os.path.exists(os.path.join(mount.get_root().get_path(),
     202                                       _JOURNAL_0_METADATA_DIR)):
     203            logging.debug('Convert DS-0 Journal entries.')
     204            gobject.idle_add(_convert_entries, mount.get_root().get_path())
     205
    84206        button = VolumeButton(mount)
    85207        button.props.group = self._volume_buttons[0]
    86208        button.connect('toggled', self._button_toggled_cb)