blob_generator.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. """This script generates the XAP info.json payload header to be compiled into QMK.
  2. """
  3. import json
  4. import gzip
  5. from pathlib import Path
  6. from qmk.info import keymap_json
  7. from qmk.commands import get_chunks, dump_lines
  8. from qmk.json_schema import deep_update, json_load
  9. from qmk.json_encoders import InfoJSONEncoder
  10. from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
  11. def _build_info(keyboard, keymap):
  12. """Build the xap version of info.json
  13. """
  14. defaults_json = json_load(Path('data/mappings/xap_defaults.json'))
  15. km_info_json = keymap_json(keyboard, keymap)
  16. info_json = {}
  17. deep_update(info_json, defaults_json)
  18. deep_update(info_json, km_info_json)
  19. # TODO: Munge to XAP requirements
  20. info_json.pop('config_h_features', None)
  21. info_json.pop('keymaps', None)
  22. info_json.pop('parse_errors', None)
  23. info_json.pop('parse_warnings', None)
  24. info_json.get('usb', {}).pop('device_ver', None)
  25. for layout in info_json.get('layouts', {}).values():
  26. layout.pop('filename', None)
  27. layout.pop('c_macro', None)
  28. for item in layout.get('layout', []):
  29. item.pop('label', None)
  30. return info_json
  31. def generate_blob(output_file, keyboard, keymap):
  32. """Generate XAP payload
  33. """
  34. info_json = _build_info(keyboard, keymap)
  35. # Minify
  36. str_data = json.dumps(info_json, separators=(',', ':'))
  37. # Compress
  38. compressed = gzip.compress(str_data.encode("utf-8"), compresslevel=9)
  39. # split into lines to match xxd output
  40. hex_array = ["0x{:02X}".format(b) for b in compressed]
  41. data_len = len(hex_array)
  42. data = ""
  43. for chunk in get_chunks(hex_array, 12):
  44. data += f' {", ".join(chunk)},\n'
  45. lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '']
  46. lines.append('#if 0')
  47. lines.append('// Blob contains a minified+gzipped version of the following:')
  48. lines.append(json.dumps(info_json, cls=InfoJSONEncoder))
  49. lines.append('#endif')
  50. lines.append('')
  51. # Gen output file
  52. lines.append('static const unsigned char config_blob_gz[] PROGMEM = {')
  53. lines.append(data)
  54. lines.append('};')
  55. lines.append(f'#define CONFIG_BLOB_GZ_LEN {data_len}')
  56. dump_lines(output_file, lines)