| 39 | _JOURNAL_0_METADATA_DIR = '.olpc.store' |
| 40 | |
| 41 | |
| 42 | def _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 | |
| 54 | def _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 | |