diff options
Diffstat (limited to 'src/sugar3/mime.py')
-rw-r--r-- | src/sugar3/mime.py | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/src/sugar3/mime.py b/src/sugar3/mime.py new file mode 100644 index 0000000..448585e --- /dev/null +++ b/src/sugar3/mime.py @@ -0,0 +1,268 @@ +# Copyright (C) 2006-2007, Red Hat, Inc. +# Copyright (C) 2007, One Laptop Per Child +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +"""MIME helpers based on freedesktop specification. + +STABLE. +""" + +import os +import logging +import gettext + +from sugar3 import _sugarbaseext + +_ = lambda msg: gettext.dgettext('sugar-base', msg) + +GENERIC_TYPE_TEXT = 'Text' +GENERIC_TYPE_IMAGE = 'Image' +GENERIC_TYPE_AUDIO = 'Audio' +GENERIC_TYPE_VIDEO = 'Video' +GENERIC_TYPE_LINK = 'Link' + +_extensions = {} +_globs_timestamps = [] +_generic_types = [ +{ + 'id': GENERIC_TYPE_TEXT, + 'name': _('Text'), + 'icon': 'text-x-generic', + 'types': [ + 'text/plain', 'text/rtf', 'application/pdf', 'application/x-pdf', + 'text/html', 'application/vnd.oasis.opendocument.text', + 'application/rtf', 'text/rtf', 'application/epub+zip'], +}, +{ + 'id': GENERIC_TYPE_IMAGE, + 'name': _('Image'), + 'icon': 'image-x-generic', + 'types': ['image/png', 'image/gif', 'image/jpeg'], +}, +{ + 'id': GENERIC_TYPE_AUDIO, + 'name': _('Audio'), + 'icon': 'audio-x-generic', + 'types': [ + 'audio/ogg', 'audio/x-wav', 'audio/wav', 'audio/x-vorbis+ogg', + 'audio/x-mpegurl', 'audio/mpegurl', 'audio/mpeg', 'audio/x-scpls'], +}, +{ + 'id': GENERIC_TYPE_VIDEO, + 'name': _('Video'), + 'icon': 'video-x-generic', + 'types': ['video/ogg', 'application/ogg', 'video/x-theora+ogg'], +}, +{ + 'id': GENERIC_TYPE_LINK, + 'name': _('Link'), + 'icon': 'text-uri-list', + 'types': ['text/x-moz-url', 'text/uri-list'], +}] + + +class ObjectType(object): + + def __init__(self, type_id, name, icon, mime_types): + self.type_id = type_id + self.name = name + self.icon = icon + self.mime_types = mime_types + + +def get_generic_type(type_id): + types = get_all_generic_types() + for generic_type in types: + if type_id == generic_type.type_id: + return generic_type + + +def get_all_generic_types(): + types = [] + for generic_type in _generic_types: + object_type = ObjectType(generic_type['id'], generic_type['name'], + generic_type['icon'], generic_type['types']) + types.append(object_type) + return types + + +def get_for_file(file_name): + if file_name.startswith('file://'): + file_name = file_name[7:] + + file_name = os.path.realpath(file_name) + + mime_type = _sugarbaseext.get_mime_type_for_file(file_name) + if mime_type == 'application/octet-stream': + if _file_looks_like_text(file_name): + return 'text/plain' + else: + return 'application/octet-stream' + + return mime_type + + +def get_from_file_name(file_name): + return _sugarbaseext.get_mime_type_from_file_name(file_name) + + +def get_mime_icon(mime_type): + generic_type = _get_generic_type_for_mime(mime_type) + if generic_type: + return generic_type['icon'] + + return mime_type.replace('/', '-') + + +def get_mime_description(mime_type): + generic_type = _get_generic_type_for_mime(mime_type) + if generic_type: + return generic_type['name'] + + import gio + return gio.content_type_get_description(mime_type) + + +def get_mime_parents(mime_type): + return _sugarbaseext.list_mime_parents(mime_type) + + +def get_primary_extension(mime_type): + global _extensions + global _globs_timestamps + + dirs = [] + + if 'XDG_DATA_HOME' in os.environ: + dirs.append(os.environ['XDG_DATA_HOME']) + else: + dirs.append(os.path.expanduser('~/.local/share/')) + + if 'XDG_DATA_DIRS' in os.environ: + dirs.extend(os.environ['XDG_DATA_DIRS'].split(':')) + else: + dirs.extend(['/usr/local/share/', '/usr/share/']) + + timestamps = [] + globs_path_list = [] + for f in dirs: + globs_path = os.path.join(f, 'mime', 'globs') + if os.path.exists(globs_path): + mtime = os.stat(globs_path).st_mtime + timestamps.append([globs_path, mtime]) + globs_path_list.append(globs_path) + + if timestamps != _globs_timestamps: + # Clear the old extensions list + _extensions = {} + + # FIXME Properly support these types in the system. (#4855) + _extensions['audio/ogg'] = 'ogg' + _extensions['video/ogg'] = 'ogg' + + for globs_path in globs_path_list: + globs_file = open(globs_path) + for line in globs_file.readlines(): + line = line.strip() + if not line.startswith('#'): + line_type, glob = line.split(':') + if glob.startswith('*.'): + _extensions[line_type] = glob[2:] + + _globs_timestamps = timestamps + + if mime_type in _extensions: + return _extensions[mime_type] + else: + return None + + +_MIME_TYPE_BLACK_LIST = [ + # Target used only between gtk.TextBuffer instances + 'application/x-gtk-text-buffer-rich-text', +] + + +def choose_most_significant(mime_types): + logging.debug('Choosing between %r.', mime_types) + if not mime_types: + return '' + + if 'text/uri-list' in mime_types: + return 'text/uri-list' + + for mime_category in ['image/', 'application/']: + for mime_type in mime_types: + + if mime_type.startswith(mime_category) and \ + mime_type not in _MIME_TYPE_BLACK_LIST: + # skip mozilla private types (second component starts with '_' + # or ends with '-priv') + if mime_type.split('/')[1].startswith('_') or \ + mime_type.split('/')[1].endswith('-priv'): + continue + + # take out the specifier after ';' that mozilla likes to add + mime_type = mime_type.split(';')[0] + logging.debug('Choosed %r!', mime_type) + return mime_type + + if 'text/x-moz-url' in mime_types: + logging.debug('Choosed text/x-moz-url!') + return 'text/x-moz-url' + + if 'text/html' in mime_types: + logging.debug('Choosed text/html!') + return 'text/html' + + if 'text/plain' in mime_types: + logging.debug('Choosed text/plain!') + return 'text/plain' + + logging.debug('Returning first: %r.', mime_types[0]) + return mime_types[0] + + +def split_uri_list(uri_list): + return _sugarbaseext.uri_list_extract_uris(uri_list) + + +def _file_looks_like_text(file_name): + f = open(file_name, 'r') + try: + sample = f.read(256) + finally: + f.close() + + if '\000' in sample: + return False + + for encoding in ('ascii', 'latin_1', 'utf_8', 'utf_16'): + try: + unicode(sample, encoding) + return True + except Exception: + pass + + return False + + +def _get_generic_type_for_mime(mime_type): + for generic_type in _generic_types: + if mime_type in generic_type['types']: + return generic_type + return None |