-
Notifications
You must be signed in to change notification settings - Fork 86
/
create_repository.py
163 lines (123 loc) · 5.36 KB
/
create_repository.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env python3
import datetime
import hashlib
import json
import zipfile
from pathlib import Path
from zipfile import ZipFile
ROOT_PATH = Path(__file__).resolve().parent
PACKAGES_JSON_PATH = ROOT_PATH / "packages.json"
RESOURCES_PATH = ROOT_PATH / "resources.zip"
REPOSITORY_JSON_PATH = ROOT_PATH / "repository.json"
METADATA_FILEAME = "metadata.json"
ICON_FILENAME = "icon.png"
REPOSITORY_BASE_URI = "https://raw.githubusercontent.com/pointhi/kicad-color-schemes/master"
READ_SIZE = 65536
def sha256_of_file(path):
file_hash = hashlib.sha256()
with path.open("rb") as f:
data = f.read(READ_SIZE)
while data:
file_hash.update(data)
data = f.read(READ_SIZE)
return file_hash.hexdigest()
def create_pcm_from_color_scheme(path, resulting_file):
with ZipFile(resulting_file, 'w', compression=zipfile.ZIP_DEFLATED) as zip:
for json_file in path.glob("*.json"):
if json_file.name == METADATA_FILEAME:
zip.write(json_file, json_file.name)
continue
zip.write(json_file, f"colors/{json_file.name}")
icon_file = path / ICON_FILENAME
if icon_file.exists():
zip.write(icon_file, f"resources/{ICON_FILENAME}")
def install_size_of_zip(zip_path):
install_size = 0
with ZipFile(zip_path, 'r') as zip:
for file in zip.filelist:
install_size += zip.getinfo(file.filename).file_size
return install_size
def create_and_get_pcm(path):
metadata_path = path / METADATA_FILEAME
if not metadata_path.exists():
return
print(f"* create schema for: {path}")
with metadata_path.open("rb") as f:
metadata_json = json.load(f)
identifier = metadata_json["identifier"]
for metadata_version in metadata_json["versions"]:
version = metadata_version['version']
pkg_name = f"{identifier}_v{version}_pcm.zip"
pkg_path = path / pkg_name
if not pkg_path.exists():
# create new package as it does not exist yet (new version)
print(f" * create package: {pkg_path}")
create_pcm_from_color_scheme(path, pkg_path)
# fill in package data
metadata_version['download_sha256'] = sha256_of_file(pkg_path)
metadata_version['download_size'] = pkg_path.stat().st_size
metadata_version['download_url'] = f"{REPOSITORY_BASE_URI}/{path.name}/{pkg_name}"
metadata_version['install_size'] = install_size_of_zip(pkg_path)
return metadata_json
def write_packages_json(package_array):
packages_data = {"packages": package_array}
with PACKAGES_JSON_PATH.open("w", encoding="utf-8") as f:
json.dump(packages_data, f, indent=4)
def write_resources_zip():
with ZipFile(RESOURCES_PATH, 'w', compression=zipfile.ZIP_DEFLATED) as zip:
for path in ROOT_PATH.iterdir():
if not path.is_dir():
continue
metadata_path = path / METADATA_FILEAME
icon_path = path / ICON_FILENAME
if not metadata_path.exists() or not icon_path.exists():
continue
with metadata_path.open("r") as f:
metadata_json = json.load(f)
identifier = metadata_json["identifier"]
zip.write(icon_path, f"{identifier}/{ICON_FILENAME}")
def write_repository_json():
packages_json_sha256 = sha256_of_file(PACKAGES_JSON_PATH)
packages_json_update_timestamp = int(PACKAGES_JSON_PATH.stat().st_mtime)
packages_json_update_time_utc = datetime.datetime.fromtimestamp(packages_json_update_timestamp, tz=datetime.timezone.utc)
repository_data = {
"$schema": "https://go.kicad.org/pcm/schemas/v1#/definitions/Repository",
"maintainer": {
"contact": {
"web": "https://github.com/pointhi/kicad-color-schemes/"
},
"name": "Thomas Pointhuber"
},
"name": "kicad-color-schemes repository by @pointhi",
"packages": {
"sha256": packages_json_sha256,
"update_time_utc": packages_json_update_time_utc.strftime("%Y-%m-%d %H:%M:%S"),
"update_timestamp": packages_json_update_timestamp,
"url": f"{REPOSITORY_BASE_URI}/packages.json"
}
}
if RESOURCES_PATH.exists():
resources_sha256 = sha256_of_file(RESOURCES_PATH)
resources_update_timestamp = int(RESOURCES_PATH.stat().st_mtime)
resources_update_time_utc = datetime.datetime.fromtimestamp(resources_update_timestamp, tz=datetime.timezone.utc)
repository_data["resources"] = {
"sha256": resources_sha256,
"update_time_utc": resources_update_time_utc.strftime("%Y-%m-%d %H:%M:%S"),
"update_timestamp": resources_update_timestamp,
"url": f"{REPOSITORY_BASE_URI}/resources.zip"
}
with REPOSITORY_JSON_PATH.open("w", encoding="utf-8") as f:
json.dump(repository_data, f, indent=4)
if __name__ == "__main__":
# create all package zip files and return the full schema of each one
schemas = []
for path in ROOT_PATH.iterdir():
if path.is_dir():
schema = create_and_get_pcm(path)
if schema:
schemas.append(schema)
schemas = sorted(schemas, key=lambda d: d['identifier'])
# write packages.json and repository.json
write_packages_json(schemas)
write_resources_zip()
write_repository_json()