File indexing completed on 2025-01-19 03:59:54

0001 import sys
0002 import os
0003 import pkgutil
0004 import argparse
0005 import importlib
0006 
0007 
0008 class Baseporter:
0009     def __init__(self, name, extensions, callback, extra_options=[], generic_options=set(), slug=None):
0010         self.name = name
0011         self.extensions = extensions
0012         self.callback = callback
0013         self.extra_options = extra_options
0014         self.generic_options = generic_options
0015         self.slug = slug if slug is not None else extensions[0]
0016 
0017     def process(self, *a, **kw):
0018         return self.callback(*a, **kw)
0019 
0020     def __repr__(self):
0021         return "<%s %s>" % (self.__class__.__name__, self.slug)
0022 
0023     def argparse_options(self, ns):
0024         o_options = {}
0025         for opt in self.extra_options:
0026             o_options[opt.dest] = getattr(ns, opt.nsvar(self.slug))
0027         for opt in self.generic_options:
0028             o_options[opt] = getattr(ns, opt)
0029         return o_options
0030 
0031 
0032 class ExtraOption:
0033     def __init__(self, name, **kwargs):
0034         self.name = name
0035         self.kwargs = kwargs
0036         if "action" not in self.kwargs:
0037             self.kwargs["metavar"] = self.name
0038         self.dest = kwargs.pop("dest", name)
0039 
0040     def add_argument(self, slug, parser):
0041         opt = "--%s-%s" % (slug, self.name.replace("_", "-"))
0042         parser.add_argument(opt, dest=self.nsvar(slug), **self.kwargs)
0043 
0044     def nsvar(self, slug):
0045         return "%s_%s" % (slug, self.dest)
0046 
0047 
0048 def _add_options(parser, ie, object):
0049     if not object.extra_options:
0050         return
0051 
0052     suf = " %sing options" % ie
0053     group = parser.add_argument_group(object.name + suf)
0054     for op in object.extra_options:
0055         op.add_argument(object.slug, group)
0056 
0057 
0058 class Loader:
0059     def __init__(self, module_path, module_name, ie):
0060         self._loaded = False
0061         self._registry = {}
0062         self._module_path = os.path.dirname(module_path)
0063         self._module_name = module_name.replace(".base", "")
0064         self._ie = ie
0065         self._failed = {}
0066 
0067     def load_modules(self):
0068         self._loaded = True
0069 
0070         for _, modname, _ in pkgutil.iter_modules([self._module_path]):
0071             if modname == "base":
0072                 continue
0073 
0074             full_modname = "." + modname
0075             try:
0076                 importlib.import_module(full_modname, self._module_name)
0077             except ImportError as e:
0078                 self._failed[modname] = e.name
0079 
0080     @property
0081     def failed_modules(self):
0082         if not self._loaded:
0083             self.load_modules()
0084 
0085         return self._failed
0086 
0087     @property
0088     def items(self):
0089         if not self._loaded:
0090             self.load_modules()
0091         return self._registry
0092 
0093     def __iter__(self):
0094         return iter(self.items.values())
0095 
0096     def get(self, slug):
0097         return self.items.get(slug, None)
0098 
0099     def __getitem__(self, key):
0100         return self.get(key)
0101 
0102     def get_from_filename(self, filename):
0103         return self.get_from_extension(os.path.splitext(filename)[1][1:])
0104 
0105     def get_from_extension(self, ext):
0106         for p in self.items.values():
0107             if ext in p.extensions:
0108                 return p
0109         return None
0110 
0111     def set_options(self, parser):
0112         for exporter in self.items.values():
0113             _add_options(parser, self._ie, exporter)
0114 
0115     def keys(self):
0116         return self.items.keys()
0117 
0118     def decorator(self, name, extensions, extra_options=[], generic_options=set(), slug=None):
0119         def decorator(callback):
0120             porter = Baseporter(name, extensions, callback, extra_options, generic_options, slug)
0121             self._registry[porter.slug] = porter
0122             return callback
0123         return decorator
0124 
0125 
0126 class IoProgressReporter:
0127     def report_progress(self, title, value, total):
0128         sys.stderr.write("\r%s %s/%s" % (title, value, total))
0129         sys.stderr.flush()
0130 
0131     def report_message(self, message):
0132         sys.stderr.write("\r" + message + "\n")
0133         sys.stderr.flush()
0134 
0135 
0136 IoProgressReporter.instance = IoProgressReporter()
0137 
0138 
0139 def io_progress():
0140     return IoProgressReporter.instance