Have plugins mirror run under python 3 and use python2 only for plugins that dont parse under python3

This commit is contained in:
Kovid Goyal 2021-07-19 11:29:40 +05:30
parent a1e9b55591
commit 2003641a98
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -3,9 +3,9 @@
# License: GPLv3 Copyright: 2013, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
# Imports {{{
import argparse
import ast
import atexit
import bz2
@ -308,23 +308,7 @@ def parse_metadata(raw, namelist, zf):
raise ValueError('Could not find plugin class')
def get_plugin_info(raw):
metadata = None
with zipfile.ZipFile(io.BytesIO(raw)) as zf:
names = {x.decode('utf-8') if isinstance(x, bytes) else x : x for x in zf.namelist()}
inits = [x for x in names if x.rpartition('/')[-1] == '__init__.py']
inits.sort(key=lambda x:x.count('/'))
if inits and inits[0] == '__init__.py':
metadata = names[inits[0]]
else:
# Legacy plugin
for name, val in names.items():
if name.endswith('plugin.py'):
metadata = val
break
if metadata is None:
raise ValueError('No __init__.py found in plugin')
raw = zf.open(metadata).read()
def parse_plugin(raw, names, zf):
ans = parse_metadata(raw, names, zf)
if isinstance(ans, dict):
return ans
@ -343,6 +327,35 @@ def get_plugin_info(raw):
raise ValueError('Failed to find plugin class')
def get_plugin_info(raw_zip):
metadata = None
with zipfile.ZipFile(io.BytesIO(raw_zip)) as zf:
names = {x.decode('utf-8') if isinstance(x, bytes) else x : x for x in zf.namelist()}
inits = [x for x in names if x.rpartition('/')[-1] == '__init__.py']
inits.sort(key=lambda x:x.count('/'))
if inits and inits[0] == '__init__.py':
metadata = names[inits[0]]
else:
# Legacy plugin
for name, val in names.items():
if name.endswith('plugin.py'):
metadata = val
break
if metadata is None:
raise ValueError('No __init__.py found in plugin')
raw = zf.open(metadata).read()
try:
return parse_plugin(raw, names, zf)
except (SyntaxError, TabError, IndentationError):
with tempfile.NamedTemporaryFile(suffix='.zip') as f:
f.write(raw_zip)
f.flush()
p = subprocess.Popen(['python2', __file__, f.name], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
stdout = p.communicate(json.dumps((raw, names)).encode('utf-8'))[0]
return json.loads(stdout)
raise
# }}}
def update_plugin_from_entry(plugin, entry):
@ -597,7 +610,22 @@ def update_stats():
return stats
def py2_parse(zipfile_path):
raw, names = json.loads(sys.stdin.read())
with zipfile.ZipFile(zipfile_path) as zf:
ans = parse_plugin(raw, names, zf)
sys.stdout.write(json.dump(ans, ensure_ascii=True))
def main():
p = argparse.ArgumentParser(
description='Mirror calibre plugins from the forums. Or parse a single plugin zip file'
' if specified on the command line'
)
p.add_argument('plugin_path', nargs='?', default='', help='Path to plugin zip file to parse')
args = p.parse_args()
if args.plugin_path:
return py2_parse(args.plugin_path)
try:
os.chdir(WORKDIR)
except OSError as err: