From b5e913ab78e2e5a7e8d2aee34637813080d79334 Mon Sep 17 00:00:00 2001
From: Martin Langhoff <martin@laptop.org>
Date: Fri, 4 Dec 2009 19:28:35 +0000
Subject: [PATCH 2/4] Removable disk: read json formatted .metadata and .preview dlo#9657
With this patch, the full metadata record is read
- proper title is displayed
- searches cover text fields in the metadata
- entry details are displayed correctly
- drag'n'drop copy to journal works, preserves metadata
---
src/jarabe/journal/model.py | 55 +++++++++++++++++++++++++++++++++++++++----
1 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index 7814fe6..0553a44 100644
a
|
b
|
import dbus |
29 | 29 | import gconf |
30 | 30 | import gio |
31 | 31 | import json |
| 32 | import base64 |
32 | 33 | |
33 | 34 | from sugar import dispatch |
34 | 35 | from sugar import mime |
… |
… |
class InplaceResultSet(BaseResultSet): |
310 | 311 | files = self._file_list[offset:offset + limit] |
311 | 312 | |
312 | 313 | entries = [] |
313 | | for file_path, stat, mtime_ in files: |
314 | | metadata = _get_file_metadata(file_path, stat) |
| 314 | for file_path, stat, mtime_, metadata in files: |
| 315 | if metadata == False: |
| 316 | # fallback - the find should fetch md |
| 317 | metadata = _get_file_metadata(file_path, stat) |
315 | 318 | metadata['mountpoint'] = self._mount_point |
316 | 319 | entries.append(metadata) |
317 | 320 | |
… |
… |
class InplaceResultSet(BaseResultSet): |
336 | 339 | elif S_IFMT(stat.st_mode) == S_IFREG: |
337 | 340 | add_to_list = True |
338 | 341 | |
339 | | if self._regex is not None and \ |
340 | | not self._regex.match(full_path): |
| 342 | md = _get_file_metadata_from_json(dir_path, entry, |
| 343 | preview=False) |
| 344 | if self._regex is not None: |
341 | 345 | add_to_list = False |
| 346 | if self._regex.match(full_path): |
| 347 | add_to_list = True |
| 348 | elif md: |
| 349 | # match any of the text md fields |
| 350 | for f in ['fulltext', 'title', 'description', 'tags']: |
| 351 | if f in md and self._regex.match(md[f]): |
| 352 | add_to_list = True |
| 353 | break |
342 | 354 | |
343 | 355 | if None not in [self._date_start, self._date_end] and \ |
344 | 356 | (stat.st_mtime < self._date_start or |
… |
… |
class InplaceResultSet(BaseResultSet): |
351 | 363 | add_to_list = False |
352 | 364 | |
353 | 365 | if add_to_list: |
354 | | file_info = (full_path, stat, int(stat.st_mtime)) |
| 366 | file_info = (full_path, stat, int(stat.st_mtime), md) |
355 | 367 | self._file_list.append(file_info) |
356 | 368 | |
357 | 369 | self.progress.send(self) |
… |
… |
class InplaceResultSet(BaseResultSet): |
366 | 378 | self._pending_directories -= 1 |
367 | 379 | |
368 | 380 | def _get_file_metadata(path, stat): |
| 381 | # will sometimes be called for |
| 382 | # files that do have a metatada file |
| 383 | fname = os.path.basename(path) |
| 384 | dir_path = os.path.dirname(path) |
| 385 | md = _get_file_metadata_from_json(dir_path, fname, preview=True) |
| 386 | if md: |
| 387 | return md |
| 388 | |
| 389 | # make up something for files w/o metadata |
369 | 390 | client = gconf.client_get_default() |
370 | 391 | return {'uid': path, |
371 | 392 | 'title': os.path.basename(path), |
… |
… |
def _get_file_metadata(path, stat): |
376 | 397 | 'icon-color': client.get_string('/desktop/sugar/user/color'), |
377 | 398 | 'description': path} |
378 | 399 | |
| 400 | def _get_file_metadata_from_json(dir_path, fname, preview=False): |
| 401 | md = None |
| 402 | mdpath = os.path.join(dir_path, |
| 403 | '.'+fname+'.metadata') |
| 404 | md = False |
| 405 | if os.path.exists(mdpath): |
| 406 | try: |
| 407 | md = json.load(open(mdpath)) |
| 408 | md['uid'] = os.path.join(dir_path, fname) |
| 409 | except: |
| 410 | pass |
| 411 | if preview: |
| 412 | prpath = os.path.join(dir_path, |
| 413 | '.'+fname+'.preview') |
| 414 | try: |
| 415 | preview = base64.b64encode(open(prpath).read()) |
| 416 | md['preview'] = preview |
| 417 | except: |
| 418 | pass |
| 419 | else: |
| 420 | if md and 'preview' in md: |
| 421 | del(md['preview']) |
| 422 | return md |
| 423 | |
379 | 424 | _datastore = None |
380 | 425 | def _get_datastore(): |
381 | 426 | global _datastore |