logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

community_modules.py (3149B)


  1. import os
  2. from pathlib import Path
  3. from functools import lru_cache
  4. from milc.attrdict import AttrDict
  5. from qmk.json_schema import json_load, validate, merge_ordered_dicts
  6. from qmk.util import truthy
  7. from qmk.constants import QMK_FIRMWARE, QMK_USERSPACE, HAS_QMK_USERSPACE
  8. from qmk.path import under_qmk_firmware, under_qmk_userspace
  9. COMMUNITY_MODULE_JSON_FILENAME = 'qmk_module.json'
  10. class ModuleAPI(AttrDict):
  11. def __init__(self, **kwargs):
  12. super().__init__()
  13. for key, value in kwargs.items():
  14. self[key] = value
  15. @lru_cache(maxsize=1)
  16. def module_api_list():
  17. module_definition_files = sorted(set(QMK_FIRMWARE.glob('data/constants/module_hooks/*.hjson')))
  18. module_definition_jsons = [json_load(f) for f in module_definition_files]
  19. module_definitions = merge_ordered_dicts(module_definition_jsons)
  20. latest_module_version = module_definition_files[-1].stem
  21. latest_module_version_parts = latest_module_version.split('.')
  22. api_list = []
  23. for name, mod in module_definitions.items():
  24. api_list.append(ModuleAPI(
  25. ret_type=mod['ret_type'],
  26. name=name,
  27. args=mod['args'],
  28. call_params=mod.get('call_params', ''),
  29. guard=mod.get('guard', None),
  30. header=mod.get('header', None),
  31. ))
  32. return api_list, latest_module_version, latest_module_version_parts[0], latest_module_version_parts[1], latest_module_version_parts[2]
  33. def find_available_module_paths():
  34. """Find all available modules.
  35. """
  36. search_dirs = []
  37. if HAS_QMK_USERSPACE:
  38. search_dirs.append(QMK_USERSPACE / 'modules')
  39. search_dirs.append(QMK_FIRMWARE / 'modules')
  40. modules = []
  41. for search_dir in search_dirs:
  42. for module_json_path in search_dir.rglob(COMMUNITY_MODULE_JSON_FILENAME):
  43. modules.append(module_json_path.parent)
  44. return modules
  45. def find_module_path(module):
  46. """Find a module by name.
  47. """
  48. for module_path in find_available_module_paths():
  49. # Ensure the module directory is under QMK Firmware or QMK Userspace
  50. relative_path = under_qmk_firmware(module_path)
  51. if not relative_path:
  52. relative_path = under_qmk_userspace(module_path)
  53. if not relative_path:
  54. continue
  55. lhs = str(relative_path.as_posix())[len('modules/'):]
  56. rhs = str(Path(module).as_posix())
  57. if relative_path and lhs == rhs:
  58. return module_path
  59. return None
  60. def load_module_json(module):
  61. """Load a module JSON file.
  62. """
  63. module_path = find_module_path(module)
  64. if not module_path:
  65. raise FileNotFoundError(f'Module not found: {module}')
  66. module_json = json_load(module_path / COMMUNITY_MODULE_JSON_FILENAME)
  67. if not truthy(os.environ.get('SKIP_SCHEMA_VALIDATION'), False):
  68. validate(module_json, 'qmk.community_module.v1')
  69. module_json['module'] = module
  70. module_json['module_path'] = module_path
  71. return module_json
  72. def load_module_jsons(modules):
  73. """Load the module JSON files, matching the specified order.
  74. """
  75. return list(map(load_module_json, modules))