Fixes
[librarian.git] / src / librarian / embeds / __init__.py
1 from __future__ import unicode_literals
2
3 import importlib
4 from lxml import etree
5
6 known_types = {
7     'application/mathml+xml': 'librarian.embeds.mathml.MathML',
8     'application/x-latex': 'librarian.embeds.latex.LaTeX',
9 }
10
11
12 class Embed():
13     @classmethod
14     def transforms_to(cls, mime_types, downgrade=False):
15         matches = set()
16         for name, method in cls.__dict__.iteritems():
17             if hasattr(method, "embed_converts_to"):
18                 conv_type, conv_downgrade = method.embed_converts_to
19                 if downgrade == conv_downgrade and conv_type in mime_types:
20                     matches.add(conv_type)
21         return matches
22
23     def transform_to(self, mime_type, downgrade=False):
24         for name, method in type(self).__dict__.iteritems():
25             if hasattr(method, "embed_converts_to"):
26                 conv_type, conv_downgrade = method.embed_converts_to
27                 if downgrade == conv_downgrade and conv_type == mime_type:
28                     return method(self)
29
30
31 class DataEmbed(Embed):
32     def __init__(self, data=None):
33         self.data = data
34
35
36 class TreeEmbed(Embed):
37     def __init__(self, tree=None):
38         if isinstance(tree, etree._Element):
39             tree = etree.ElementTree(tree)
40         self.tree = tree
41
42
43 def converts_to(mime_type, downgrade=False):
44     def decorator(method):
45         method.embed_converts_to = mime_type, downgrade
46         return method
47     return decorator
48
49
50 def downgrades_to(mime_type):
51     return converts_to(mime_type, True)
52
53
54 def create_embed(mime_type, tree=None, data=None):
55     embed = known_types.get(mime_type)
56     if embed is None:
57         embed = DataEmbed if tree is None else TreeEmbed
58     else:
59         mod_name, cls_name = embed.rsplit('.', 1)
60         mod = importlib.import_module(mod_name)
61         embed = getattr(mod, cls_name)
62
63     return embed(data if tree is None else tree)