aboutsummaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python/qmk/cli')
-rw-r--r--lib/python/qmk/cli/__init__.py1
-rw-r--r--lib/python/qmk/cli/c2json.py2
-rw-r--r--lib/python/qmk/cli/generate/__init__.py1
-rwxr-xr-xlib/python/qmk/cli/generate/api.py58
-rwxr-xr-xlib/python/qmk/cli/info.py56
-rwxr-xr-xlib/python/qmk/cli/json2c.py2
-rw-r--r--lib/python/qmk/cli/list/keyboards.py19
7 files changed, 92 insertions, 47 deletions
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py
index ba964ebbb..47e1b4435 100644
--- a/lib/python/qmk/cli/__init__.py
+++ b/lib/python/qmk/cli/__init__.py
@@ -13,6 +13,7 @@ from . import config
13from . import docs 13from . import docs
14from . import doctor 14from . import doctor
15from . import flash 15from . import flash
16from . import generate
16from . import hello 17from . import hello
17from . import info 18from . import info
18from . import json 19from . import json
diff --git a/lib/python/qmk/cli/c2json.py b/lib/python/qmk/cli/c2json.py
index 0267303fd..8c8bd1f57 100644
--- a/lib/python/qmk/cli/c2json.py
+++ b/lib/python/qmk/cli/c2json.py
@@ -44,7 +44,7 @@ def c2json(cli):
44 44
45 # Generate the keymap.json 45 # Generate the keymap.json
46 try: 46 try:
47 keymap_json = qmk.keymap.generate(keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers'], type='json', keymap=keymap_json['keymap']) 47 keymap_json = qmk.keymap.generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers'])
48 except KeyError: 48 except KeyError:
49 cli.log.error('Something went wrong. Try to use --no-cpp.') 49 cli.log.error('Something went wrong. Try to use --no-cpp.')
50 sys.exit(1) 50 sys.exit(1)
diff --git a/lib/python/qmk/cli/generate/__init__.py b/lib/python/qmk/cli/generate/__init__.py
new file mode 100644
index 000000000..4dc7607ef
--- /dev/null
+++ b/lib/python/qmk/cli/generate/__init__.py
@@ -0,0 +1 @@
from . import api
diff --git a/lib/python/qmk/cli/generate/api.py b/lib/python/qmk/cli/generate/api.py
new file mode 100755
index 000000000..9807a9cd6
--- /dev/null
+++ b/lib/python/qmk/cli/generate/api.py
@@ -0,0 +1,58 @@
1"""This script automates the generation of the QMK API data.
2"""
3from pathlib import Path
4from shutil import copyfile
5import json
6
7from milc import cli
8
9from qmk.datetime import current_datetime
10from qmk.info import info_json
11from qmk.keyboard import list_keyboards
12
13
14@cli.subcommand('Creates a new keymap for the keyboard of your choosing', hidden=False if cli.config.user.developer else True)
15def generate_api(cli):
16 """Generates the QMK API data.
17 """
18 api_data_dir = Path('api_data')
19 v1_dir = api_data_dir / 'v1'
20 keyboard_list = v1_dir / 'keyboard_list.json'
21 keyboard_all = v1_dir / 'keyboards.json'
22 usb_file = v1_dir / 'usb.json'
23
24 if not api_data_dir.exists():
25 api_data_dir.mkdir()
26
27 kb_all = {'last_updated': current_datetime(), 'keyboards': {}}
28 usb_list = {'last_updated': current_datetime(), 'devices': {}}
29
30 # Generate and write keyboard specific JSON files
31 for keyboard_name in list_keyboards():
32 kb_all['keyboards'][keyboard_name] = info_json(keyboard_name)
33 keyboard_dir = v1_dir / 'keyboards' / keyboard_name
34 keyboard_info = keyboard_dir / 'info.json'
35 keyboard_readme = keyboard_dir / 'readme.md'
36 keyboard_readme_src = Path('keyboards') / keyboard_name / 'readme.md'
37
38 keyboard_dir.mkdir(parents=True, exist_ok=True)
39 keyboard_info.write_text(json.dumps(kb_all['keyboards'][keyboard_name]))
40
41 if keyboard_readme_src.exists():
42 copyfile(keyboard_readme_src, keyboard_readme)
43
44 if 'usb' in kb_all['keyboards'][keyboard_name]:
45 usb = kb_all['keyboards'][keyboard_name]['usb']
46
47 if usb['vid'] not in usb_list['devices']:
48 usb_list['devices'][usb['vid']] = {}
49
50 if usb['pid'] not in usb_list['devices'][usb['vid']]:
51 usb_list['devices'][usb['vid']][usb['pid']] = {}
52
53 usb_list['devices'][usb['vid']][usb['pid']][keyboard_name] = usb
54
55 # Write the global JSON files
56 keyboard_list.write_text(json.dumps({'last_updated': current_datetime(), 'keyboards': sorted(kb_all['keyboards'])}))
57 keyboard_all.write_text(json.dumps(kb_all))
58 usb_file.write_text(json.dumps(usb_list))
diff --git a/lib/python/qmk/cli/info.py b/lib/python/qmk/cli/info.py
index 0e64d4074..44ce1186a 100755
--- a/lib/python/qmk/cli/info.py
+++ b/lib/python/qmk/cli/info.py
@@ -16,7 +16,7 @@ ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop'
16COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' 16COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz'
17 17
18 18
19def show_keymap(info_json, title_caps=True): 19def show_keymap(kb_info_json, title_caps=True):
20 """Render the keymap in ascii art. 20 """Render the keymap in ascii art.
21 """ 21 """
22 keymap_path = locate_keymap(cli.config.info.keyboard, cli.config.info.keymap) 22 keymap_path = locate_keymap(cli.config.info.keyboard, cli.config.info.keymap)
@@ -36,7 +36,7 @@ def show_keymap(info_json, title_caps=True):
36 else: 36 else:
37 cli.echo('{fg_cyan}layer_%s{fg_reset}:', layer_num) 37 cli.echo('{fg_cyan}layer_%s{fg_reset}:', layer_num)
38 38
39 print(render_layout(info_json['layouts'][layout_name]['layout'], layer)) 39 print(render_layout(kb_info_json['layouts'][layout_name]['layout'], layer))
40 40
41 41
42def show_layouts(kb_info_json, title_caps=True): 42def show_layouts(kb_info_json, title_caps=True):
@@ -48,10 +48,10 @@ def show_layouts(kb_info_json, title_caps=True):
48 print(layout_art) # Avoid passing dirty data to cli.echo() 48 print(layout_art) # Avoid passing dirty data to cli.echo()
49 49
50 50
51def show_matrix(info_json, title_caps=True): 51def show_matrix(kb_info_json, title_caps=True):
52 """Render the layout with matrix labels in ascii art. 52 """Render the layout with matrix labels in ascii art.
53 """ 53 """
54 for layout_name, layout in info_json['layouts'].items(): 54 for layout_name, layout in kb_info_json['layouts'].items():
55 # Build our label list 55 # Build our label list
56 labels = [] 56 labels = []
57 for key in layout['layout']: 57 for key in layout['layout']:
@@ -69,54 +69,54 @@ def show_matrix(info_json, title_caps=True):
69 else: 69 else:
70 cli.echo('{fg_blue}matrix_%s{fg_reset}:', layout_name) 70 cli.echo('{fg_blue}matrix_%s{fg_reset}:', layout_name)
71 71
72 print(render_layout(info_json['layouts'][layout_name]['layout'], labels)) 72 print(render_layout(kb_info_json['layouts'][layout_name]['layout'], labels))
73 73
74 74
75def print_friendly_output(info_json): 75def print_friendly_output(kb_info_json):
76 """Print the info.json in a friendly text format. 76 """Print the info.json in a friendly text format.
77 """ 77 """
78 cli.echo('{fg_blue}Keyboard Name{fg_reset}: %s', info_json.get('keyboard_name', 'Unknown')) 78 cli.echo('{fg_blue}Keyboard Name{fg_reset}: %s', kb_info_json.get('keyboard_name', 'Unknown'))
79 cli.echo('{fg_blue}Manufacturer{fg_reset}: %s', info_json.get('manufacturer', 'Unknown')) 79 cli.echo('{fg_blue}Manufacturer{fg_reset}: %s', kb_info_json.get('manufacturer', 'Unknown'))
80 if 'url' in info_json: 80 if 'url' in kb_info_json:
81 cli.echo('{fg_blue}Website{fg_reset}: %s', info_json.get('url', '')) 81 cli.echo('{fg_blue}Website{fg_reset}: %s', kb_info_json.get('url', ''))
82 if info_json.get('maintainer', 'qmk') == 'qmk': 82 if kb_info_json.get('maintainer', 'qmk') == 'qmk':
83 cli.echo('{fg_blue}Maintainer{fg_reset}: QMK Community') 83 cli.echo('{fg_blue}Maintainer{fg_reset}: QMK Community')
84 else: 84 else:
85 cli.echo('{fg_blue}Maintainer{fg_reset}: %s', info_json['maintainer']) 85 cli.echo('{fg_blue}Maintainer{fg_reset}: %s', kb_info_json['maintainer'])
86 cli.echo('{fg_blue}Keyboard Folder{fg_reset}: %s', info_json.get('keyboard_folder', 'Unknown')) 86 cli.echo('{fg_blue}Keyboard Folder{fg_reset}: %s', kb_info_json.get('keyboard_folder', 'Unknown'))
87 cli.echo('{fg_blue}Layouts{fg_reset}: %s', ', '.join(sorted(info_json['layouts'].keys()))) 87 cli.echo('{fg_blue}Layouts{fg_reset}: %s', ', '.join(sorted(kb_info_json['layouts'].keys())))
88 if 'width' in info_json and 'height' in info_json: 88 if 'width' in kb_info_json and 'height' in kb_info_json:
89 cli.echo('{fg_blue}Size{fg_reset}: %s x %s' % (info_json['width'], info_json['height'])) 89 cli.echo('{fg_blue}Size{fg_reset}: %s x %s' % (kb_info_json['width'], kb_info_json['height']))
90 cli.echo('{fg_blue}Processor{fg_reset}: %s', info_json.get('processor', 'Unknown')) 90 cli.echo('{fg_blue}Processor{fg_reset}: %s', kb_info_json.get('processor', 'Unknown'))
91 cli.echo('{fg_blue}Bootloader{fg_reset}: %s', info_json.get('bootloader', 'Unknown')) 91 cli.echo('{fg_blue}Bootloader{fg_reset}: %s', kb_info_json.get('bootloader', 'Unknown'))
92 92
93 if cli.config.info.layouts: 93 if cli.config.info.layouts:
94 show_layouts(info_json, True) 94 show_layouts(kb_info_json, True)
95 95
96 if cli.config.info.matrix: 96 if cli.config.info.matrix:
97 show_matrix(info_json, True) 97 show_matrix(kb_info_json, True)
98 98
99 if cli.config_source.info.keymap and cli.config_source.info.keymap != 'config_file': 99 if cli.config_source.info.keymap and cli.config_source.info.keymap != 'config_file':
100 show_keymap(info_json, True) 100 show_keymap(kb_info_json, True)
101 101
102 102
103def print_text_output(info_json): 103def print_text_output(kb_info_json):
104 """Print the info.json in a plain text format. 104 """Print the info.json in a plain text format.
105 """ 105 """
106 for key in sorted(info_json): 106 for key in sorted(kb_info_json):
107 if key == 'layouts': 107 if key == 'layouts':
108 cli.echo('{fg_blue}layouts{fg_reset}: %s', ', '.join(sorted(info_json['layouts'].keys()))) 108 cli.echo('{fg_blue}layouts{fg_reset}: %s', ', '.join(sorted(kb_info_json['layouts'].keys())))
109 else: 109 else:
110 cli.echo('{fg_blue}%s{fg_reset}: %s', key, info_json[key]) 110 cli.echo('{fg_blue}%s{fg_reset}: %s', key, kb_info_json[key])
111 111
112 if cli.config.info.layouts: 112 if cli.config.info.layouts:
113 show_layouts(info_json, False) 113 show_layouts(kb_info_json, False)
114 114
115 if cli.config.info.matrix: 115 if cli.config.info.matrix:
116 show_matrix(info_json, False) 116 show_matrix(kb_info_json, False)
117 117
118 if cli.config_source.info.keymap and cli.config_source.info.keymap != 'config_file': 118 if cli.config_source.info.keymap and cli.config_source.info.keymap != 'config_file':
119 show_keymap(info_json, False) 119 show_keymap(kb_info_json, False)
120 120
121 121
122@cli.argument('-kb', '--keyboard', help='Keyboard to show info for.') 122@cli.argument('-kb', '--keyboard', help='Keyboard to show info for.')
diff --git a/lib/python/qmk/cli/json2c.py b/lib/python/qmk/cli/json2c.py
index 2a9009436..426078063 100755
--- a/lib/python/qmk/cli/json2c.py
+++ b/lib/python/qmk/cli/json2c.py
@@ -38,7 +38,7 @@ def json2c(cli):
38 user_keymap = json.load(fd) 38 user_keymap = json.load(fd)
39 39
40 # Generate the keymap 40 # Generate the keymap
41 keymap_c = qmk.keymap.generate(user_keymap['keyboard'], user_keymap['layout'], user_keymap['layers']) 41 keymap_c = qmk.keymap.generate_c(user_keymap['keyboard'], user_keymap['layout'], user_keymap['layers'])
42 42
43 if cli.args.output: 43 if cli.args.output:
44 cli.args.output.parent.mkdir(parents=True, exist_ok=True) 44 cli.args.output.parent.mkdir(parents=True, exist_ok=True)
diff --git a/lib/python/qmk/cli/list/keyboards.py b/lib/python/qmk/cli/list/keyboards.py
index ca0c5661a..8b6c45167 100644
--- a/lib/python/qmk/cli/list/keyboards.py
+++ b/lib/python/qmk/cli/list/keyboards.py
@@ -1,28 +1,13 @@
1"""List the keyboards currently defined within QMK 1"""List the keyboards currently defined within QMK
2""" 2"""
3# We avoid pathlib here because this is performance critical code.
4import os
5import glob
6
7from milc import cli 3from milc import cli
8 4
9BASE_PATH = os.path.join(os.getcwd(), "keyboards") + os.path.sep 5import qmk.keyboard
10KB_WILDCARD = os.path.join(BASE_PATH, "**", "rules.mk")
11
12
13def find_name(path):
14 """Determine the keyboard name by stripping off the base_path and rules.mk.
15 """
16 return path.replace(BASE_PATH, "").replace(os.path.sep + "rules.mk", "")
17 6
18 7
19@cli.subcommand("List the keyboards currently defined within QMK") 8@cli.subcommand("List the keyboards currently defined within QMK")
20def list_keyboards(cli): 9def list_keyboards(cli):
21 """List the keyboards currently defined within QMK 10 """List the keyboards currently defined within QMK
22 """ 11 """
23 # find everywhere we have rules.mk where keymaps isn't in the path 12 for keyboard_name in qmk.keyboard.list_keyboards():
24 paths = [path for path in glob.iglob(KB_WILDCARD, recursive=True) if 'keymaps' not in path]
25
26 # Extract the keyboard name from the path and print it
27 for keyboard_name in sorted(map(find_name, paths)):
28 print(keyboard_name) 13 print(keyboard_name)