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