kicad-color-schemes/create_repository.py
2021-11-06 18:34:41 +01:00

163 lines
5.4 KiB
Python

#!/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()