1
0
mirror of https://github.com/gryf/ebook-converter.git synced 2026-04-28 09:34:05 +02:00

Removed some more code

This commit is contained in:
2020-05-03 09:55:22 +02:00
parent 8f1eb9c88c
commit 1a79146bf7
2 changed files with 152 additions and 446 deletions
-205
View File
@@ -109,208 +109,3 @@ def load_translations(namespace, zfp):
namespace['_'] = getattr(trans, 'gettext')
namespace['ngettext'] = getattr(trans, 'ngettext')
class PluginLoader(object):
def __init__(self):
self.loaded_plugins = {}
self._lock = threading.RLock()
self._identifier_pat = re.compile(r'[a-zA-Z][_0-9a-zA-Z]*')
def _get_actual_fullname(self, fullname):
parts = fullname.split('.')
if parts[0] == 'calibre_plugins':
if len(parts) == 1:
return parts[0], None
plugin_name = parts[1]
with self._lock:
names = self.loaded_plugins.get(plugin_name, None)
if names is None:
raise ImportError('No plugin named %r loaded'%plugin_name)
names = names[1]
fullname = '.'.join(parts[2:])
if not fullname:
fullname = '__init__'
if fullname in names:
return fullname, plugin_name
if fullname+'.__init__' in names:
return fullname+'.__init__', plugin_name
return None, None
def find_module(self, fullname, path=None):
fullname, plugin_name = self._get_actual_fullname(fullname)
if fullname is None and plugin_name is None:
return None
return self
def load_module(self, fullname):
import_name, plugin_name = self._get_actual_fullname(fullname)
if import_name is None and plugin_name is None:
raise ImportError('No plugin named %r is loaded'%fullname)
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<calibre Plugin Loader>"
mod.__loader__ = self
if import_name.endswith('.__init__') or import_name in ('__init__',
'calibre_plugins'):
# We have a package
mod.__path__ = []
if plugin_name is not None:
# We have some actual code to load
with self._lock:
zfp, names = self.loaded_plugins.get(plugin_name, (None, None))
if names is None:
raise ImportError('No plugin named %r loaded'%plugin_name)
zinfo = names.get(import_name, None)
if zinfo is None:
raise ImportError('Plugin %r has no module named %r' %
(plugin_name, import_name))
with zipfile.ZipFile(zfp) as zf:
try:
code = zf.read(zinfo)
except:
# Maybe the zip file changed from under us
code = zf.read(zinfo.filename)
compiled = compile(code, 'calibre_plugins.%s.%s'%(plugin_name,
import_name), 'exec', dont_inherit=True)
mod.__dict__['get_resources'] = partial(get_resources, zfp)
mod.__dict__['get_icons'] = partial(get_icons, zfp)
mod.__dict__['load_translations'] = partial(load_translations, mod.__dict__, zfp)
exec(compiled, mod.__dict__)
return mod
def load(self, path_to_zip_file):
if not os.access(path_to_zip_file, os.R_OK):
raise PluginNotFound('Cannot access %r'%path_to_zip_file)
with zipfile.ZipFile(path_to_zip_file) as zf:
plugin_name = self._locate_code(zf, path_to_zip_file)
try:
ans = None
plugin_module = 'calibre_plugins.%s'%plugin_name
m = sys.modules.get(plugin_module, None)
if m is not None:
reload(m)
else:
m = importlib.import_module(plugin_module)
plugin_classes = []
for obj in m.__dict__.values():
if isinstance(obj, type) and issubclass(obj, Plugin) and \
obj.name != 'Trivial Plugin':
plugin_classes.append(obj)
if not plugin_classes:
raise InvalidPlugin('No plugin class found in %s:%s'%(
as_unicode(path_to_zip_file), plugin_name))
if len(plugin_classes) > 1:
plugin_classes.sort(key=lambda c:(getattr(c, '__module__', None) or '').count('.'))
ans = plugin_classes[0]
if ans.minimum_calibre_version > numeric_version:
raise InvalidPlugin(
'The plugin at %s needs a version of calibre >= %s' %
(as_unicode(path_to_zip_file), '.'.join(map(str,
ans.minimum_calibre_version))))
if platform not in ans.supported_platforms:
raise InvalidPlugin(
'The plugin at %s cannot be used on %s' %
(as_unicode(path_to_zip_file), platform))
return ans
except:
with self._lock:
del self.loaded_plugins[plugin_name]
raise
def _locate_code(self, zf, path_to_zip_file):
names = [x if isinstance(x, str) else x.decode('utf-8') for x in
zf.namelist()]
names = [x[1:] if x[0] == '/' else x for x in names]
plugin_name = None
for name in names:
name, ext = posixpath.splitext(name)
if name.startswith('plugin-import-name-') and ext == '.txt':
plugin_name = name.rpartition('-')[-1]
if plugin_name is None:
c = 0
while True:
c += 1
plugin_name = 'dummy%d'%c
if plugin_name not in self.loaded_plugins:
break
else:
if self._identifier_pat.match(plugin_name) is None:
raise InvalidPlugin((
'The plugin at %r uses an invalid import name: %r' %
(path_to_zip_file, plugin_name)))
pynames = [x for x in names if x.endswith('.py')]
candidates = [posixpath.dirname(x) for x in pynames if
x.endswith('/__init__.py')]
candidates.sort(key=lambda x: x.count('/'))
valid_packages = set()
for candidate in candidates:
parts = candidate.split('/')
parent = '.'.join(parts[:-1])
if parent and parent not in valid_packages:
continue
valid_packages.add('.'.join(parts))
names = OrderedDict()
for candidate in pynames:
parts = posixpath.splitext(candidate)[0].split('/')
package = '.'.join(parts[:-1])
if package and package not in valid_packages:
continue
name = '.'.join(parts)
names[name] = zf.getinfo(candidate)
# Legacy plugins
if '__init__' not in names:
for name in tuple(names):
if '.' not in name and name.endswith('plugin'):
names['__init__'] = names[name]
break
if '__init__' not in names:
raise InvalidPlugin(('The plugin in %r is invalid. It does not '
'contain a top-level __init__.py file')
% path_to_zip_file)
with self._lock:
self.loaded_plugins[plugin_name] = (path_to_zip_file, names)
return plugin_name
loader = PluginLoader()
#sys.meta_path.insert(0, loader)
if __name__ == '__main__':
from tempfile import NamedTemporaryFile
from ebook_converter.customize.ui import add_plugin
from ebook_converter import CurrentDir
path = sys.argv[-1]
with NamedTemporaryFile(suffix='.zip') as f:
with zipfile.ZipFile(f, 'w') as zf:
with CurrentDir(path):
for x in os.listdir('.'):
if x[0] != '.':
print('Adding', x)
zf.write(x)
if os.path.isdir(x):
for y in os.listdir(x):
zf.write(os.path.join(x, y))
add_plugin(f.name)
print('Added plugin from', sys.argv[-1])