Web · Wiki · Activities · Blog · Lists · Chat · Meeting · Bugs · Git · Translate · Archive · People · Donate

Commit fb038743626915f226f9733089620f94539e49bf

Optionally add extension to checked out files based on MIME type

If available, gdatastore will now use sugar.mime to guess an extension
to add to checked out files, based on their MIME type.

The outside world (including emacs) is still surprisingly focused on
file extensions rather than MIME types. By adding an extension to the
file names returned by gdatastore we help other software that has to
interface with legacy components. The alternative would be to add code
to every piece of glue code to guess the extension and rename the
file in a race-free way. Doing it in gdatastore reduces the overall
complexity of the software system.
  • Diff rendering mode:
  • inline
  • side by side

gdatastore/datastore.py

32import dbus.service32import dbus.service
33import gconf33import gconf
3434
35try:
36 from sugar import mime as sugar_mime
37except ImportError:
38 # Only used for helping legacy applications that use the file
39 # extension rather than the MIME type
40 sugar_mime = None
41
35from gdatastore.index import Index42from gdatastore.index import Index
3643
3744
541 def get_data_path(self, (tree_id, version_id), sender=None):541 def get_data_path(self, (tree_id, version_id), sender=None):
542 logging.debug('get_data_path((%r, %r), %r)', tree_id, version_id,542 logging.debug('get_data_path((%r, %r), %r)', tree_id, version_id,
543 sender)543 sender)
544 metadata = self._index.retrieve((tree_id, version_id))
544 ref_name = _format_ref(tree_id, version_id)545 ref_name = _format_ref(tree_id, version_id)
545 top_level_entries = self._git_call('ls-tree',546 top_level_entries = self._git_call('ls-tree',
546 [ref_name]).splitlines()547 [ref_name]).splitlines()
547 if len(top_level_entries) == 1 and \548 if len(top_level_entries) == 1 and \
548 top_level_entries[0].endswith('\tdata'):549 top_level_entries[0].endswith('\tdata'):
549 blob_hash = top_level_entries[0].split('\t')[0].split(' ')[2]550 blob_hash = top_level_entries[0].split('\t')[0].split(' ')[2]
550 return self._checkout_file(blob_hash)
551 mime_type = metadata.get('mime_type', '')
552 return self._checkout_file(blob_hash,
553 suffix=_guess_extension(mime_type))
551554
552 return self._checkout_dir(ref_name)555 return self._checkout_dir(ref_name)
553556
671 for entry in old_versions:671 for entry in old_versions:
672 self.delete((entry['tree_id'], entry['version_id']))672 self.delete((entry['tree_id'], entry['version_id']))
673673
674 def _checkout_file(self, blob_hash):
675 fd, file_name = tempfile.mkstemp(dir=self._checkouts_dir)
674 def _checkout_file(self, blob_hash, suffix=''):
675 fd, file_name = tempfile.mkstemp(dir=self._checkouts_dir, suffix=suffix)
676 try:676 try:
677 self._git_call('cat-file', ['blob', blob_hash], stdout_fd=fd)677 self._git_call('cat-file', ['blob', blob_hash], stdout_fd=fd)
678 finally:678 finally:
865865
866def _format_ref(tree_id, version_id):866def _format_ref(tree_id, version_id):
867 return 'refs/gdatastore/%s/%s' % (tree_id, version_id)867 return 'refs/gdatastore/%s/%s' % (tree_id, version_id)
868
869
870def _guess_extension(mime_type):
871 if sugar_mime is None:
872 return ''
873 extension = sugar_mime.get_primary_extension(mime_type)
874 if not extension:
875 return ''
876 return '.' + extension