root/sharedmimeinfo/trunk/sharedmimeinfo.py

Revision 326, 3.6 kB (checked in by athomas, 3 years ago)
  • Added lookup_ prefix to methods. Clearer.
Line 
1 import xml.dom.minidom as minidom
2 import os
3 from glob import glob
4
5 MIME_MEDIA = ('application', 'audio', 'image', 'inode', 'magic', 'message',
6               'model', 'multipart', 'text', 'video')
7
8 class InvalidMimeType(Exception):
9     """ Thrown if a MIME type is invalid. """
10
11 class InvalidMimeExtension(Exception):
12     """ Thrown if a file extension has no matching MIME type. """
13
14 class MimeType:
15     """ A representation of a MIME type. """
16     def __init__(self, description, parent, type, aliases, globs):
17         self.description, self.parent, self.type, self.aliases, self.globs = \
18             description, parent, type, aliases, globs
19
20     def __repr__(self):
21         return "<%s.%s '%s'>" % (self.__module__, self.__class__.__name__, self.type)
22
23 class SharedMimeInfo:
24     """ A Python interface to the shared-mime-info specification database
25         (http://www.freedesktop.org/Standards/shared-mime-info-spec). """
26     def __init__(self):
27         self.paths = [x for x in (os.path.expanduser('~/.local/share/mime'), '/usr/local/share/mime', '/usr/share/mime') if os.path.isdir(x)]
28         self.globs = {}
29         self.extensions = {}
30         self.aliases = {}
31         for path in self.paths:
32             # Load globs
33             try:
34                 globfile = open(os.path.join(path, 'globs'), 'r')
35                 for line in globfile:
36                     line = line.strip()
37                     if line.startswith('#') or not line:
38                         continue
39                     type, glob = line.strip().split(':')
40                     self.globs.setdefault(type, []).append(glob)
41                     self.extensions[glob] = type
42                 globfile.close()
43             except IOError:
44                 pass
45             # Load aliases
46             try:
47                 aliasfile = open(os.path.join(path, 'aliases'), 'r')
48                 for line in aliasfile:
49                     alias, target = line.strip().split()
50                     self.aliases[alias] = target
51                 aliasfile.close()
52             except IOError:
53                 pass
54
55     def _file_for_type(self, type):
56         for path in self.paths:
57             file = os.path.join(path, os.path.extsep.join([type, 'xml']))
58             if os.path.isfile(file):
59                 return file
60         raise InvalidMimeType(type)
61
62     def lookup_type(self, type):
63         """ Get a MimeType object for a MIME type. """
64         if type in self.aliases:
65             type = self.aliases[type]
66         dom = minidom.parse(self._file_for_type(type))
67         description = dom.getElementsByTagName('comment')[0].childNodes[0].data
68         parent = dom.getElementsByTagName('sub-class-of')
69         aliases = [x.attributes['type'].value for x in dom.getElementsByTagName('alias')]
70         if parent:
71             parent = parent[0].attributes['type'].value
72         else:
73             parent = None
74         return MimeType(description, parent, type, aliases, list(self.globs[type]))
75
76     def lookup_extension(self, extension):
77         """ Get a MimeType object for a file extension. """
78         try:
79             return self.type(self.extensions['*.' + extension])
80         except KeyError:
81             raise InvalidMimeExtension(extension)
82
83     def __iter__(self):
84         """ Iterate over all available MIME type names. """
85         global MIME_MEDIA
86         for path in self.paths:
87             for media in MIME_MEDIA:
88                 if os.path.isdir(os.path.join(path, media)):
89                     for type in glob(os.path.join(path, media, '*.xml')):
90                         yield '%s/%s' % (media, os.path.basename(os.path.splitext(type)[0]))
91
92     def __getitem__(self, type):
93         return self.lookup_type(type)
Note: See TracBrowser for help on using the browser.