Coverage for lib/lottie/parsers/baseporter.py: 45%
103 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1import sys
2import os
3import pkgutil
4import argparse
5import importlib
8class Baseporter:
9 def __init__(self, name, extensions, callback, extra_options=[], generic_options=set(), slug=None):
10 self.name = name
11 self.extensions = extensions
12 self.callback = callback
13 self.extra_options = extra_options
14 self.generic_options = generic_options
15 self.slug = slug if slug is not None else extensions[0]
17 def process(self, *a, **kw):
18 return self.callback(*a, **kw)
20 def __repr__(self):
21 return "<%s %s>" % (self.__class__.__name__, self.slug)
23 def argparse_options(self, ns):
24 o_options = {}
25 for opt in self.extra_options:
26 o_options[opt.dest] = getattr(ns, opt.nsvar(self.slug))
27 for opt in self.generic_options:
28 o_options[opt] = getattr(ns, opt)
29 return o_options
32class ExtraOption:
33 def __init__(self, name, **kwargs):
34 self.name = name
35 self.kwargs = kwargs
36 if "action" not in self.kwargs:
37 self.kwargs["metavar"] = self.name
38 self.dest = kwargs.pop("dest", name)
40 def add_argument(self, slug, parser):
41 opt = "--%s-%s" % (slug, self.name.replace("_", "-"))
42 parser.add_argument(opt, dest=self.nsvar(slug), **self.kwargs)
44 def nsvar(self, slug):
45 return "%s_%s" % (slug, self.dest)
48def _add_options(parser, ie, object):
49 if not object.extra_options:
50 return
52 suf = " %sing options" % ie
53 group = parser.add_argument_group(object.name + suf)
54 for op in object.extra_options:
55 op.add_argument(object.slug, group)
58class Loader:
59 def __init__(self, module_path, module_name, ie):
60 self._loaded = False
61 self._registry = {}
62 self._module_path = os.path.dirname(module_path)
63 self._module_name = module_name.replace(".base", "")
64 self._ie = ie
65 self._failed = {}
67 def load_modules(self):
68 self._loaded = True
70 for _, modname, _ in pkgutil.iter_modules([self._module_path]):
71 if modname == "base":
72 continue
74 full_modname = "." + modname
75 try:
76 importlib.import_module(full_modname, self._module_name)
77 except ImportError as e:
78 self._failed[modname] = "cairosvg or glaxnimate" if e.name == "lottie.exporters.cairo" else e.name
80 @property
81 def failed_modules(self):
82 if not self._loaded:
83 self.load_modules()
85 return self._failed
87 @property
88 def items(self):
89 if not self._loaded:
90 self.load_modules()
91 return self._registry
93 def __iter__(self):
94 return iter(self.items.values())
96 def get(self, slug):
97 return self.items.get(slug, None)
99 def __getitem__(self, key):
100 return self.get(key)
102 def get_from_filename(self, filename):
103 return self.get_from_extension(os.path.splitext(filename)[1][1:])
105 def get_from_extension(self, ext):
106 for p in self.items.values():
107 if ext in p.extensions:
108 return p
109 return None
111 def set_options(self, parser):
112 for exporter in self.items.values():
113 _add_options(parser, self._ie, exporter)
115 def keys(self):
116 return self.items.keys()
118 def decorator(self, name, extensions, extra_options=[], generic_options=set(), slug=None):
119 def decorator(callback):
120 porter = Baseporter(name, extensions, callback, extra_options, generic_options, slug)
121 self._registry[porter.slug] = porter
122 return callback
123 return decorator
126class IoProgressReporter:
127 def report_progress(self, title, value, total):
128 sys.stderr.write("\r%s %s/%s" % (title, value, total))
129 sys.stderr.flush()
131 def report_message(self, message):
132 sys.stderr.write("\r" + message + "\n")
133 sys.stderr.flush()
136IoProgressReporter.instance = IoProgressReporter()
139def io_progress():
140 return IoProgressReporter.instance