-
Notifications
You must be signed in to change notification settings - Fork 3
/
package.py
executable file
·112 lines (87 loc) · 3.09 KB
/
package.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
#!/usr/bin/env python3
import glob
import os
import re
import requests
import shutil
import subprocess
import tempfile
from urllib import request
SOURCE_FILES = [
'__init__.py',
'config.json',
]
# tuple of pypi_package_name, module_name
DEPENDENCIES_PYPI = [
('jieba', 'jieba'),
('cached_property', 'cached_property'),
('genanki', 'genanki'),
('chinesevocablist', 'chinesevocablist'),
('chineseflashcards', 'chineseflashcards'),
('pyyaml', 'yaml'),
('chevron', 'chevron'),
]
PACKAGE_CACHE_DIR = 'package_cache'
OUTPUT_FILE_NAME = "package.ankiaddon"
def prepare_package_dir_and_zip():
shutil.rmtree('package', ignore_errors=True)
os.mkdir('package')
try:
os.remove(OUTPUT_FILE_NAME)
except OSError as e:
if e.errno != 2:
raise
def copy_source_files():
for f in SOURCE_FILES:
dirname, filename = os.path.split(f)
target_dirname = os.path.join('package', dirname)
os.makedirs(target_dirname, exist_ok=True)
shutil.copy(f, target_dirname)
def retrieve_with_cache(url, dest_path):
os.makedirs(PACKAGE_CACHE_DIR, exist_ok=True)
filename = url.split('/')[-1]
cached_path = os.path.join(PACKAGE_CACHE_DIR, filename)
if not os.path.exists(cached_path):
request.urlretrieve(url, cached_path)
shutil.copy(cached_path, dest_path)
def copy_dependencies_from_pypi():
for pypi_name, mod_name in DEPENDENCIES_PYPI:
metadata = requests.get(f'https://pypi.org/pypi/{pypi_name}/json').json()
latest_release = metadata['info']['version']
url = metadata['releases'][latest_release][-1]['url']
filename = url.split('/')[-1]
tmpdir = tempfile.mkdtemp()
retrieve_with_cache(url, os.path.join(tmpdir, filename))
if filename.endswith('.zip'):
subprocess.check_output(['unzip', filename], cwd=tmpdir)
dirname = filename[:-len('.zip')]
elif filename.endswith('.tar.gz'):
subprocess.check_output(['tar', '-xzf', filename], cwd=tmpdir)
dirname = filename[:-len('.tar.gz')]
else:
raise Exception(f'Unrecognized package format! {filename}')
if mod_name == 'yaml':
shutil.move(os.path.join(tmpdir, dirname, 'lib', mod_name), 'package')
else:
try:
# this works if it's a directory
shutil.move(os.path.join(tmpdir, dirname, mod_name), 'package')
except FileNotFoundError:
# this works if it's a simple .py file
shutil.move(os.path.join(tmpdir, dirname, f'{mod_name}.py'), 'package')
def _extract_version(path):
dirname = os.path.split(path)[-1]
return re.search(r'[0-9]+(\.[0-9]+)*', dirname).group(0)
def _path_to_sort_tuple(path):
# higher is better
version_tuple = tuple(int(piece) for piece in _extract_version(path).split('.'))
# prefer a package (rank higher) if it is user (rather than system)
is_user = path.startswith(f'{os.environ["HOME"]}/.local/')
return (is_user,) + version_tuple
def create_package_zip_file():
shutil.copy('manifest.json', 'package/')
subprocess.check_call(['zip', f'../{OUTPUT_FILE_NAME}', '-r', '.'], cwd='package')
prepare_package_dir_and_zip()
copy_source_files()
copy_dependencies_from_pypi()
create_package_zip_file()