2021-03-24 17:26:38 +01:00
|
|
|
"""Functions that help us generate and use info.json files.
|
|
|
|
"""
|
|
|
|
import json
|
|
|
|
from collections.abc import Mapping
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
import hjson
|
|
|
|
import jsonschema
|
|
|
|
from milc import cli
|
|
|
|
|
|
|
|
|
|
|
|
def json_load(json_file):
|
|
|
|
"""Load a json file from disk.
|
|
|
|
|
|
|
|
Note: file must be a Path object.
|
|
|
|
"""
|
|
|
|
try:
|
2021-03-27 16:55:47 +01:00
|
|
|
return hjson.load(json_file.open(encoding='utf-8'))
|
2021-03-24 17:26:38 +01:00
|
|
|
|
2021-08-09 17:27:02 +02:00
|
|
|
except (json.decoder.JSONDecodeError, hjson.HjsonDecodeError) as e:
|
2021-03-24 17:26:38 +01:00
|
|
|
cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e)
|
|
|
|
exit(1)
|
2021-08-09 17:27:02 +02:00
|
|
|
except Exception as e:
|
|
|
|
cli.log.error('Unknown error attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e)
|
|
|
|
exit(1)
|
2021-03-24 17:26:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
def load_jsonschema(schema_name):
|
|
|
|
"""Read a jsonschema file from disk.
|
|
|
|
|
|
|
|
FIXME(skullydazed/anyone): Refactor to make this a public function.
|
|
|
|
"""
|
|
|
|
schema_path = Path(f'data/schemas/{schema_name}.jsonschema')
|
|
|
|
|
|
|
|
if not schema_path.exists():
|
|
|
|
schema_path = Path('data/schemas/false.jsonschema')
|
|
|
|
|
|
|
|
return json_load(schema_path)
|
|
|
|
|
|
|
|
|
|
|
|
def keyboard_validate(data):
|
|
|
|
"""Validates data against the keyboard jsonschema.
|
|
|
|
"""
|
|
|
|
schema = load_jsonschema('keyboard')
|
|
|
|
validator = jsonschema.Draft7Validator(schema).validate
|
|
|
|
|
|
|
|
return validator(data)
|
|
|
|
|
|
|
|
|
|
|
|
def keyboard_api_validate(data):
|
|
|
|
"""Validates data against the api_keyboard jsonschema.
|
|
|
|
"""
|
|
|
|
base = load_jsonschema('keyboard')
|
|
|
|
relative = load_jsonschema('api_keyboard')
|
|
|
|
resolver = jsonschema.RefResolver.from_schema(base)
|
|
|
|
validator = jsonschema.Draft7Validator(relative, resolver=resolver).validate
|
|
|
|
|
|
|
|
return validator(data)
|
|
|
|
|
|
|
|
|
|
|
|
def deep_update(origdict, newdict):
|
|
|
|
"""Update a dictionary in place, recursing to do a deep copy.
|
|
|
|
"""
|
|
|
|
for key, value in newdict.items():
|
|
|
|
if isinstance(value, Mapping):
|
|
|
|
origdict[key] = deep_update(origdict.get(key, {}), value)
|
|
|
|
|
|
|
|
else:
|
|
|
|
origdict[key] = value
|
|
|
|
|
|
|
|
return origdict
|