forked from xxyzz/WordDumb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unzip.py
125 lines (103 loc) · 4.06 KB
/
unzip.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python3
import json
import pickle
import platform
import shutil
import subprocess
import sys
import zipfile
from pathlib import Path
from calibre.constants import is64bit, ismacos, iswindows
from calibre.utils.config import config_dir
PLUGIN_PATH = Path(config_dir).joinpath('plugins/WordDumb.zip')
PY_VERSION = '.'.join(platform.python_version_tuple()[:2])
LIBS_PATH = Path(config_dir).joinpath(f"plugins/worddumb-libs-py{PY_VERSION}")
def load_json_or_pickle(filepath, is_json):
with zipfile.ZipFile(PLUGIN_PATH) as zf:
with zf.open(filepath) as f:
if is_json:
return json.load(f)
else:
return pickle.load(f)
def wiki_cache_path(lang):
return Path(config_dir).joinpath(f'plugins/worddumb-wikipedia/{lang}.json')
def load_wiki_cache(lang):
cache_path = wiki_cache_path(lang)
if cache_path.exists():
with cache_path.open() as f:
return json.load(f)
else:
return {}
def save_wiki_cache(cache_dic, lang):
cache_path = wiki_cache_path(lang)
if not cache_path.exists():
if not cache_path.parent.exists():
cache_path.parent.mkdir()
cache_path.touch()
with cache_path.open('w') as f:
json.dump(cache_dic, f)
def install_libs(model, create_ww, create_x, notif):
if create_ww:
libs_path = str(PLUGIN_PATH.joinpath('libs')) # flashtext
if libs_path not in sys.path:
sys.path.insert(0, libs_path)
if create_x:
if (reinstall := False if LIBS_PATH.exists() else True):
for old_path in LIBS_PATH.parent.glob('worddumb-libs-py*'):
old_path.rename(LIBS_PATH)
for pkg, value in load_json_or_pickle('data/spacy.json', True).items():
pip_install(pkg, value['version'], value['compiled'],
reinstall=reinstall, notif=notif)
model_v = '3.2.0'
url = 'https://github.com/explosion/spacy-models/releases/download/'
url += f'{model}-{model_v}/{model}-{model_v}-py3-none-any.whl'
pip_install(model, model_v, url=url, notif=notif)
install_extra_deps(model, notif)
if LIBS_PATH not in sys.path:
sys.path.insert(0, str(LIBS_PATH))
def pip_install(pkg, pkg_version, compiled=False, url=None,
reinstall=False, notif=None):
pattern = f"{pkg.replace('-', '_')}-{pkg_version}*"
if not any(LIBS_PATH.glob(pattern)) or (reinstall and compiled):
if notif:
notif.put((0, f'Installing {pkg}'))
args = pip_args(pkg, pkg_version, compiled, url)
if iswindows:
subprocess.run(args, check=True, capture_output=True, text=True,
creationflags=subprocess.CREATE_NO_WINDOW)
else:
subprocess.run(args, check=True, capture_output=True, text=True)
def pip_args(pkg, pkg_version, compiled, url):
py = 'python3'
if iswindows:
py = 'py' if shutil.which('py') else 'python'
elif ismacos:
# stupid macOS loses PATH when calibre is not launched in terminal
if platform.machine() == 'arm64':
py = '/opt/homebrew/bin/python3'
else:
py = '/usr/local/bin/python3'
if not Path(py).exists():
py = '/usr/bin/python3' # command line tools
args = [py, '-m', 'pip', 'install', '-U', '-t', LIBS_PATH, '--no-deps']
if compiled:
args.extend(['--python-version', PY_VERSION])
if iswindows:
args.append('--platform')
if is64bit:
args.append('win_amd64')
else:
raise Exception('32BIT_CALIBRE')
if url:
args.append(url)
elif pkg_version:
args.append(f'{pkg}=={pkg_version}')
else:
args.append(pkg)
return args
def install_extra_deps(model, notif):
# https://spacy.io/usage/models#languages
data = load_json_or_pickle('data/spacy_extra.json', True)
if (lang := model[:2]) in data:
for pkg, value in data[lang].items():
pip_install(pkg, value['version'], value['compiled'], notif=notif)