diff options
Diffstat (limited to 'lib/python/qmk/info.py')
| -rw-r--r-- | lib/python/qmk/info.py | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 2accaba9e..cf5dc6640 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py | |||
| @@ -45,7 +45,12 @@ def info_json(keyboard): | |||
| 45 | info_data['keymaps'][keymap.name] = {'url': f'https://raw.githubusercontent.com/qmk/qmk_firmware/master/{keymap}/keymap.json'} | 45 | info_data['keymaps'][keymap.name] = {'url': f'https://raw.githubusercontent.com/qmk/qmk_firmware/master/{keymap}/keymap.json'} |
| 46 | 46 | ||
| 47 | # Populate layout data | 47 | # Populate layout data |
| 48 | for layout_name, layout_json in _find_all_layouts(info_data, keyboard).items(): | 48 | layouts, aliases = _find_all_layouts(info_data, keyboard) |
| 49 | |||
| 50 | if aliases: | ||
| 51 | info_data['layout_aliases'] = aliases | ||
| 52 | |||
| 53 | for layout_name, layout_json in layouts.items(): | ||
| 49 | if not layout_name.startswith('LAYOUT_kc'): | 54 | if not layout_name.startswith('LAYOUT_kc'): |
| 50 | layout_json['c_macro'] = True | 55 | layout_json['c_macro'] = True |
| 51 | info_data['layouts'][layout_name] = layout_json | 56 | info_data['layouts'][layout_name] = layout_json |
| @@ -92,7 +97,7 @@ def _json_load(json_file): | |||
| 92 | Note: file must be a Path object. | 97 | Note: file must be a Path object. |
| 93 | """ | 98 | """ |
| 94 | try: | 99 | try: |
| 95 | return hjson.load(json_file.open()) | 100 | return hjson.load(json_file.open(encoding='utf-8')) |
| 96 | 101 | ||
| 97 | except json.decoder.JSONDecodeError as e: | 102 | except json.decoder.JSONDecodeError as e: |
| 98 | cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e) | 103 | cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e) |
| @@ -415,21 +420,28 @@ def _merge_layouts(info_data, new_info_data): | |||
| 415 | 420 | ||
| 416 | def _search_keyboard_h(path): | 421 | def _search_keyboard_h(path): |
| 417 | current_path = Path('keyboards/') | 422 | current_path = Path('keyboards/') |
| 423 | aliases = {} | ||
| 418 | layouts = {} | 424 | layouts = {} |
| 425 | |||
| 419 | for directory in path.parts: | 426 | for directory in path.parts: |
| 420 | current_path = current_path / directory | 427 | current_path = current_path / directory |
| 421 | keyboard_h = '%s.h' % (directory,) | 428 | keyboard_h = '%s.h' % (directory,) |
| 422 | keyboard_h_path = current_path / keyboard_h | 429 | keyboard_h_path = current_path / keyboard_h |
| 423 | if keyboard_h_path.exists(): | 430 | if keyboard_h_path.exists(): |
| 424 | layouts.update(find_layouts(keyboard_h_path)) | 431 | new_layouts, new_aliases = find_layouts(keyboard_h_path) |
| 432 | layouts.update(new_layouts) | ||
| 433 | |||
| 434 | for alias, alias_text in new_aliases.items(): | ||
| 435 | if alias_text in layouts: | ||
| 436 | aliases[alias] = alias_text | ||
| 425 | 437 | ||
| 426 | return layouts | 438 | return layouts, aliases |
| 427 | 439 | ||
| 428 | 440 | ||
| 429 | def _find_all_layouts(info_data, keyboard): | 441 | def _find_all_layouts(info_data, keyboard): |
| 430 | """Looks for layout macros associated with this keyboard. | 442 | """Looks for layout macros associated with this keyboard. |
| 431 | """ | 443 | """ |
| 432 | layouts = _search_keyboard_h(Path(keyboard)) | 444 | layouts, aliases = _search_keyboard_h(Path(keyboard)) |
| 433 | 445 | ||
| 434 | if not layouts: | 446 | if not layouts: |
| 435 | # If we don't find any layouts from info.json or keyboard.h we widen our search. This is error prone which is why we want to encourage people to follow the standard above. | 447 | # If we don't find any layouts from info.json or keyboard.h we widen our search. This is error prone which is why we want to encourage people to follow the standard above. |
| @@ -437,11 +449,15 @@ def _find_all_layouts(info_data, keyboard): | |||
| 437 | 449 | ||
| 438 | for file in glob('keyboards/%s/*.h' % keyboard): | 450 | for file in glob('keyboards/%s/*.h' % keyboard): |
| 439 | if file.endswith('.h'): | 451 | if file.endswith('.h'): |
| 440 | these_layouts = find_layouts(file) | 452 | these_layouts, these_aliases = find_layouts(file) |
| 453 | |||
| 441 | if these_layouts: | 454 | if these_layouts: |
| 442 | layouts.update(these_layouts) | 455 | layouts.update(these_layouts) |
| 443 | 456 | ||
| 444 | return layouts | 457 | if these_aliases: |
| 458 | aliases.update(these_aliases) | ||
| 459 | |||
| 460 | return layouts, aliases | ||
| 445 | 461 | ||
| 446 | 462 | ||
| 447 | def _log_error(info_data, message): | 463 | def _log_error(info_data, message): |
| @@ -540,11 +556,19 @@ def merge_info_jsons(keyboard, info_data): | |||
| 540 | cli.log.error('\t%s: %s', json_path, e.message) | 556 | cli.log.error('\t%s: %s', json_path, e.message) |
| 541 | continue | 557 | continue |
| 542 | 558 | ||
| 543 | # Mark the layouts as coming from json | 559 | # Merge layout data in |
| 544 | for layout in new_info_data.get('layouts', {}).values(): | 560 | for layout_name, layout in new_info_data.get('layouts', {}).items(): |
| 545 | layout['c_macro'] = False | 561 | if layout_name in info_data['layouts']: |
| 562 | for new_key, existing_key in zip(layout['layout'], info_data['layouts'][layout_name]['layout']): | ||
| 563 | existing_key.update(new_key) | ||
| 564 | else: | ||
| 565 | layout['c_macro'] = False | ||
| 566 | info_data['layouts'][layout_name] = layout | ||
| 546 | 567 | ||
| 547 | # Update info_data with the new data | 568 | # Update info_data with the new data |
| 569 | if 'layouts' in new_info_data: | ||
| 570 | del (new_info_data['layouts']) | ||
| 571 | |||
| 548 | deep_update(info_data, new_info_data) | 572 | deep_update(info_data, new_info_data) |
| 549 | 573 | ||
| 550 | return info_data | 574 | return info_data |
