json_schema.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. """Functions that help us generate and use info.json files.
  2. """
  3. import json
  4. from collections.abc import Mapping
  5. from pathlib import Path
  6. import hjson
  7. import jsonschema
  8. from milc import cli
  9. def json_load(json_file):
  10. """Load a json file from disk.
  11. Note: file must be a Path object.
  12. """
  13. try:
  14. return hjson.load(json_file.open())
  15. except json.decoder.JSONDecodeError as e:
  16. cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e)
  17. exit(1)
  18. def load_jsonschema(schema_name):
  19. """Read a jsonschema file from disk.
  20. FIXME(skullydazed/anyone): Refactor to make this a public function.
  21. """
  22. schema_path = Path(f'data/schemas/{schema_name}.jsonschema')
  23. if not schema_path.exists():
  24. schema_path = Path('data/schemas/false.jsonschema')
  25. return json_load(schema_path)
  26. def keyboard_validate(data):
  27. """Validates data against the keyboard jsonschema.
  28. """
  29. schema = load_jsonschema('keyboard')
  30. validator = jsonschema.Draft7Validator(schema).validate
  31. return validator(data)
  32. def keyboard_api_validate(data):
  33. """Validates data against the api_keyboard jsonschema.
  34. """
  35. base = load_jsonschema('keyboard')
  36. relative = load_jsonschema('api_keyboard')
  37. resolver = jsonschema.RefResolver.from_schema(base)
  38. validator = jsonschema.Draft7Validator(relative, resolver=resolver).validate
  39. return validator(data)
  40. def deep_update(origdict, newdict):
  41. """Update a dictionary in place, recursing to do a deep copy.
  42. """
  43. for key, value in newdict.items():
  44. if isinstance(value, Mapping):
  45. origdict[key] = deep_update(origdict.get(key, {}), value)
  46. else:
  47. origdict[key] = value
  48. return origdict