diff options
Diffstat (limited to 'src/jarabe/journal/model.py')
-rw-r--r-- | src/jarabe/journal/model.py | 95 |
1 files changed, 60 insertions, 35 deletions
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py index 19068f2..375345a 100644 --- a/src/jarabe/journal/model.py +++ b/src/jarabe/journal/model.py @@ -18,6 +18,7 @@ import logging import os from datetime import datetime import time +import shutil import dbus import gconf @@ -95,14 +96,54 @@ class ResultSet(object): length = property(get_length) + def _get_all_files(self, dir_path): + files = [] + for entry in os.listdir(dir_path): + full_path = os.path.join(dir_path, entry) + if os.path.isdir(full_path): + files.extend(self._get_all_files(full_path)) + elif os.path.isfile(full_path): + stat = os.stat(full_path) + files.append((full_path, stat.st_mtime)) + return files + + def _query_mount_point(self, mount_point, query): + t = time.time() + + files = self._get_all_files(mount_point) + offset = int(query.get('offset', 0)) + limit = int(query.get('limit', len(files))) + + total_count = len(files) + files.sort(lambda a, b: int(b[1] - a[1])) + files = files[offset:offset + limit] + + result = [] + for file_path, timestamp_ in files: + metadata = _get_file_metadata(file_path) + result.append(metadata) + + logging.debug('_query_mount_point took %f s.' % (time.time() - t)) + + return result, total_count + def _find(self, query): mount_points = query.get('mountpoints', ['/']) if mount_points is None or len(mount_points) != 1: raise ValueError('Exactly one mount point must be specified') + if mount_points[0] == '/': - return _get_datastore().find(query, PROPERTIES, byte_arrays=True) + data_store = _get_datastore() + entries, total_count = _get_datastore().find(query, PROPERTIES, + byte_arrays=True) else: - return _query_mount_point(mount_points[0], query) + entries, total_count = self._query_mount_point(mount_points[0], + query) + + for entry in entries: + entry['mountpoint'] = mount_points[0] + + return entries, total_count def seek(self, position): self._position = position @@ -206,38 +247,6 @@ def _get_file_metadata(path): 'activity_id': '', 'icon-color': client.get_string('/desktop/sugar/user/color')} -def _get_all_files(dir_path): - files = [] - for entry in os.listdir(dir_path): - full_path = os.path.join(dir_path, entry) - if os.path.isdir(full_path): - files.extend(_get_all_files(full_path)) - elif os.path.isfile(full_path): - stat = os.stat(full_path) - files.append((full_path, stat.st_mtime)) - return files - -def _query_mount_point(mount_point, query): - t = time.time() - - files = _get_all_files(mount_point) - offset = int(query.get('offset', 0)) - limit = int(query.get('limit', len(files))) - - total_count = len(files) - files.sort(lambda a, b: int(b[1] - a[1])) - files = files[offset:offset + limit] - - result = [] - for file_path, timestamp in files: - metadata = _get_file_metadata(file_path) - metadata['mountpoint'] = mount_point - result.append(metadata) - - logging.debug('_query_mount_point took %f s.' % (time.time() - t)) - - return result, total_count - _datastore = None def _get_datastore(): global _datastore @@ -278,8 +287,10 @@ def get_file(object_id): """Returns the file for an object """ if os.path.exists(object_id): + logging.debug('get_file asked for file with path %r' % object_id) return object_id else: + logging.debug('get_file asked for entry with id %r' % object_id) return _get_datastore().get_filename(object_id) def get_unique_values(key): @@ -307,11 +318,13 @@ def copy(metadata, mount_point): metadata['mountpoint'] = mount_point del metadata['uid'] + #TODO: should we transfer ownership? return write(metadata, file_path) def write(metadata, file_path='', update_mtime=True): """Creates or updates an entry for that id """ + logging.debug('model.write %r %r %r' % (metadata, file_path, update_mtime)) if update_mtime: metadata['mtime'] = datetime.now().isoformat() metadata['timestamp'] = int(time.time()) @@ -327,10 +340,22 @@ def write(metadata, file_path='', update_mtime=True): file_path, True) else: - pass + if not os.path.exists(file_path): + raise ValueError('Entries without a file cannot be copied to ' + 'removable devices') + file_name = _get_file_name(metadata['title'], metadata['mime_type']) + destination_path = os.path.join(metadata['mountpoint'], file_name) + shutil.copy(file_path, destination_path) + object_id = destination_path return object_id +def _get_file_name(title, mime_type): + # TODO: sanitize title for common filesystems + # TODO: make as robust as possible, this function should never fail. + # TODO: don't append the same extension again and again + return '%s.%s' % (title, mime.get_primary_extension(mime_type)) + created = dispatch.Signal() updated = dispatch.Signal() deleted = dispatch.Signal() |