Skip to content

Commit

Permalink
add: setting fwmaker path
Browse files Browse the repository at this point in the history
update: firmware script
update: ui
  • Loading branch information
darakuneko committed May 5, 2023
1 parent 865b20a commit 7fb5c49
Show file tree
Hide file tree
Showing 14 changed files with 301 additions and 37 deletions.
58 changes: 43 additions & 15 deletions command.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@ const axios = require('axios')
const fs = require('fs')
const FormData = require('form-data')
const path = require('path')
const Store = require("electron-store")
const store = new Store()
const {app} = require("electron")

if (process.platform === 'darwin') process.env.PATH = `/usr/local/bin:${process.env.PATH}`
const instance = axios.create();
instance.defaults.timeout = 2500;
//store.clear('state')
const state = store.get('state')
const localFWMakerUrl = "http://127.0.0.1:3123"
const localFWdir = `${app.getPath('home')}/GPKFW/`

const fwMakerUrl = state?.setting?.fwMakerUrl ? state.setting.fwMakerUrl : localFWMakerUrl
const fwDir = state?.setting?.fwDir ? state.setting.fwDir : localFWdir

const appPath = __dirname.replace(/\/app\.asar/g, "").replace(/\\app\.asar/g, "")
const appExe = async (cmd) => await exec(`cd "${appPath}/gpk_fwmaker" && ${cmd}`)
const appSpawn = (cmd) => `cd "${appPath}/gpk_fwmaker" && ${cmd}`
const url = (path) => new URL(`http://127.0.0.1:3123${path}`).href
const fwMakerUrlMassage = "The docker command will not be issued unless the docker URL is 127.0.0.1."
const appExe = async (cmd) =>
fwMakerUrl.includes("127.0.0.1") ? await exec(`cd "${appPath}/gpk_fwmaker" && ${cmd}`) : fwMakerUrlMassage

const appSpawn = (cmd) =>
fwMakerUrl.includes("127.0.0.1") ? `cd "${appPath}/gpk_fwmaker" && ${cmd}` : fwMakerUrlMassage

const url = (path) => new URL(`${fwMakerUrl}${path}`).href
let isDockerUp = false
let skipCheckDocker = !fwMakerUrl.includes("127.0.0.1") ? !fwMakerUrl.includes("127.0.0.1") : false

const tagZeroFill2Int = (str) => {
const s = str
Expand Down Expand Up @@ -59,27 +77,37 @@ const responseStreamLog = async (res, mainWindow, channel) => {

const command = {
upImage: (mainWindow) => {
const res = spawn(appSpawn("docker compose build && docker compose up -d"), { shell: true });
streamLog(res, mainWindow, true)
if(!skipCheckDocker){
const res = spawn(appSpawn("docker compose build && docker compose up -d"), { shell: true })
streamLog(res, mainWindow, true)
}
},
stopImage: async () => {
if(!skipCheckDocker) await appExe("docker compose stop")
},
stopImage: async () => await appExe("docker compose stop"),
rebuildImage: async (mainWindow) => {
const res = spawn(appSpawn("docker compose build --no-cache && docker compose up -d"), { shell: true });
streamLog(res, mainWindow)
},
setSkipCheckDocker: async (skip) => skipCheckDocker = skip,
existSever: async () => {
if(skipCheckDocker) return 503
if(isDockerUp) {
const res = await axios(url("")).catch(e => e)
const res = await instance(url("")).catch(e => e)
return res.status ? res.status : 404
}
return 403
},
tags: async () => {
const res = await axios(url('/tags/qmk'))
const dat = res.data
const limit = parseZeroLastDigit(tagZeroFill2Int(dat[0]) - 3000)
const tags = dat.filter(v => tagZeroFill2Int(v) >= limit)
return tags
const res = await instance(url('/tags/qmk')).catch(e => e)
if(res.status === 200) {
const dat = res.data
const limit = parseZeroLastDigit(tagZeroFill2Int(dat[0]) - 3000)
const tags = dat.filter(v => tagZeroFill2Int(v) >= limit)
return tags
} else {
return []
}
},
build: async (dat, mainWindow) => {
const u = `/build/${dat.fw}`
Expand All @@ -104,8 +132,7 @@ const command = {
mainWindow.webContents.send("streamLog", `Cannot POST ${u}`)
},
buildCompleted: () => buildCompleted,
buildCache: (homePath, isWin) => {
const fwDir = `${homePath}/GPKFW/`
buildCache: (isWin) => {
const d = []
const searchFiles = (dirPath) => {
const allDirents = fs.readdirSync(dirPath, { withFileTypes: true })
Expand Down Expand Up @@ -175,7 +202,8 @@ const command = {
readJson: async (path) => {
const buffer = await fs.readFileSync(path)
return JSON.parse(buffer.toString())
}
},
getLocalFWdir: () => localFWdir
}

module.exports.command = command
127 changes: 121 additions & 6 deletions gpk_fwmaker/firmware-scripts/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from util import gen_uid, max_x_y, min_x_y, write_file, replace_chars, extract_matrix_pins
import json
from json import JSONDecodeError
import re


# GENERATE INFO.JSON
Expand Down Expand Up @@ -43,12 +42,19 @@ def get_layout_all(kbd: Keyboard) -> Keyboard:
qmk_keys = []
# Add non-multilayout keys to the list for now
for key in [k for k in kbd.keys if k not in ml_keys]:
# Ignore VIAL Encoder keys
if key.labels[4] == 'e':
continue
qmk_keys.append(key)

# Generate a dict of all multilayouts
# E.g. Used to test and figure out the multilayout value with the maximum amount of keys
ml_dict = {}
for key in [k for k in kbd.keys if k in ml_keys]:
# Ignore VIAL Encoder keys
if key.labels[4] == 'e':
continue

ml_ndx = int(key.labels[3])
ml_val = int(key.labels[5])

Expand Down Expand Up @@ -133,6 +139,22 @@ def get_layout_all(kbd: Keyboard) -> Keyboard:
# Add the key to the final list
qmk_keys.append(key)


# Special case to handle when a key isn't in the max multilayout but is required for a separate multilayout
# E.g. Multilayout where a split spacebar layout doesn't include the original matrix value for full spacebar,
# since that split multilayout will have more keys and will be picked by default.
for key in [k for k in kbd.keys if k in ml_keys]:
ml_ndx = int(key.labels[3])
ml_val = int(key.labels[5])
max_val = ml_dict[ml_ndx]['max']
matrix_list = [(key.labels[9], key.labels[11]) for key in ml_dict[ml_ndx][max_val]]
if (key.labels[9], key.labels[11]) not in matrix_list:
#print(key)
ml_dict[ml_ndx][max_val].append(key)
# Temporary, currently just adds the first key it sees into the layout_all, may cause issues but is a niche scenario
qmk_keys.append(key)


# Offset all the remaining keys (align against the top left)
x_offset, y_offset = min_x_y(qmk_keys)
for key in qmk_keys:
Expand All @@ -151,8 +173,20 @@ def get_layout_all(kbd: Keyboard) -> Keyboard:

return kbd

def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=None, pid=None, ver=None, mcu=None, bootloader=None, board=None, pin_dict=None, diode_dir="COL2ROW") -> dict:
def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=None, pid=None, ver=None, mcu=None, bootloader=None, board=None, pin_dict=None, diode_dir="COL2ROW", manufacturer=None) -> dict:
"""Converts a Keyboard into a QMK info.json (dict)"""
# Check for encoder keys (Both VIA and VIAL)
encoders_num = 0
for key in kbd.keys:
# Toggle encoders if a key with encoders detected
if key.labels[4].startswith('e'):
if key.labels[4] == 'e': # VIAL
enc_val = int(key.labels[9])

if len(key.labels[4]) > 1 and key.labels[4][1].isnumeric(): # VIA
enc_val = int(key.labels[4][1])
encoders_num = max(encoders_num, enc_val+1)

# Removes all multilayout options except max layouts.
kbd = get_layout_all(kbd)

Expand Down Expand Up @@ -180,8 +214,8 @@ def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=Non
# Initialize a key (dict)
qmk_key = OrderedDict(
label = "",
x = key.x,
y = key.y,
x = int(key.x) if int(key.x) == key.x else key.x,
y = int(key.y) if int(key.y) == key.y else key.y,
)

if key.width != 1:
Expand Down Expand Up @@ -210,6 +244,9 @@ def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=Non
if not maintainer:
maintainer = 'qmk'

if not manufacturer:
manufacturer = 'MANUFACTURER'

if not url:
url = ''

Expand All @@ -224,6 +261,7 @@ def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=Non
#'url': url,
'maintainer': maintainer,
#'usb': usb,
'manufacturer': manufacturer,
'layouts': {
'LAYOUT': {
'layout': qmk_layout_all
Expand Down Expand Up @@ -259,6 +297,14 @@ def kbd_to_qmk_info(kbd: Keyboard, name=None, maintainer=None, url=None, vid=Non
else:
keyboard["matrix_pins"] = {'cols': ['X', ] * cols, 'rows': ['X', ] * rows}

if encoders_num:
if not keyboard.get('features'):
keyboard["features"] = {}
keyboard["features"]["encoder"] = True
keyboard["encoder"] = {'rotary': []}
for i in range(encoders_num):
keyboard["encoder"]['rotary'].append({"pin_a": "X", "pin_b": "X"})

return keyboard


Expand Down Expand Up @@ -291,14 +337,17 @@ def kbd_to_vial(kbd: Keyboard, vial_uid:str=None, vendor_id:str=None, product_id

for key in vial_kbd.keys:
og_key = deepcopy(key)
key.color = "#cccccc" # Set to default colour to remove clutter from the KLE
# key.color = og_key.color
# key.color = "#cccccc" # Set to default colour to remove clutter from the KLE (DISABLED)
key.color = og_key.color
key.labels = [None] * 12 # Empty labels
key.textSize = [None] * 12 # Reset text size

if og_key.labels[4] == "e": # encoder; VIAL ONLY
key.labels[4] = og_key.labels[4]

elif og_key.labels[4].startswith("e"): # encoder; VIA (I know this is included in the VIAL converter, will have to change later)
key.labels[4] = og_key.labels[4]

# Matrix coords
row_lbl = og_key.labels[9]
col_lbl = og_key.labels[11]
Expand Down Expand Up @@ -564,6 +613,18 @@ def kbd_to_keymap(kbd: Keyboard, layers:int=4, lbl_ndx:int=1, layout_dict:dict=N
"""Generates a keymap.c file"""
keycodes_json = open('keycodes.json', 'r')
keycodes = json.load(keycodes_json)
# Check for encoder keys (Both VIA and VIAL)
encoders_num = 0
for key in kbd.keys:
# Toggle encoders if a key with encoders detected
if key.labels[4].startswith('e'):
if key.labels[4] == 'e': # VIAL
enc_val = int(key.labels[9])

if len(key.labels[4]) > 1 and key.labels[4][1].isnumeric(): # VIA
enc_val = int(key.labels[4][1])
encoders_num = max(encoders_num, enc_val+1)

# Removes all multilayout options except max layouts.
# For parity with info.json and keymap.c
kbd = get_layout_all(kbd)
Expand Down Expand Up @@ -665,6 +726,60 @@ def kbd_to_keymap(kbd: Keyboard, layers:int=4, lbl_ndx:int=1, layout_dict:dict=N
for line in keymap_lines:
keymap_all += line

if encoders_num:
encoder_kc = {}

if layout_dict:
if "encoder_layout" in layout_dict.keys(): # VIAL layout file
for i in range(encoders_num):
enc = []
for n in range(layers):
_enc = layout_dict["encoder_layout"][n][i]
for n, kc in enumerate(_enc):
# Convert (VIALs) deprecated keycodes into updated ones if required
if conversion_dict:
if kc in conversion_dict.keys():
_enc[n] = conversion_dict[kc]

# Convert lengthened keycodes into shortened aliases if required
if keycode_dict:
if kc in keycode_dict.keys():
_enc[n] = keycode_dict[kc]
enc.append(_enc)
encoder_kc[i] = enc

elif "encoders" in layout_dict.keys(): # VIA layout file
for i in range(encoders_num):
#encoder_kc[i] = layout_dict["encoders"][i]

kcs = layout_dict["encoders"][i]
for _ in range(len(kcs)):
for n, kc in enumerate(kcs[_]):
# Convert lengthened keycodes into shortened aliases if required
if keycode_dict:
if kc in keycode_dict.keys():
kcs[_][n] = keycode_dict[kc]

encoder_kc[i] = kcs


else:
for i in range(encoders_num):
encoder_kc[i] = []
for x in range(layers):
encoder_kc[i].append(["KC_TRNS", "KC_TRNS"])

keymap_all += "\n\n/* `ENCODER_MAP_ENABLE = yes` must be added to the rules.mk at the KEYMAP level. See QMK docs. */\n"
keymap_all += "/* Remove the following code if you do not enable it in your keymap (e.g. default keymap). */\n"
keymap_all += "#if defined(ENCODER_MAP_ENABLE)\nconst uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {\n"
for i in range(layers):
enc_line = []
for n in range(encoders_num):
enc_line.append(f"ENCODER_CCW_CW({encoder_kc[n][i][0]}, {encoder_kc[n][i][1]})")
cont = ', '.join(enc_line)
keymap_all += f"\t[{i}] = {{ {cont} }}\n"
keymap_all += "};\n#endif\n"

return "\n".join([x.rstrip() for x in keymap_all.split("\n")])


Expand Down
6 changes: 5 additions & 1 deletion gpk_fwmaker/firmware-scripts/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ def extract_matrix_pins(netlist:str, mcu:str="RP2040", output_pin_prefix:str="GP

for comp in tree[3]:
for prop in comp:
if prop[0] == "value" and mcu.lower() in prop[1].lower():
if mcu.lower().startswith("stm32"):
testcase = "stm32f"
else:
testcase = mcu.lower()
if prop[0] == "value" and prop[1].lower().startswith(testcase):
mcu_comp = comp

if not mcu_comp:
Expand Down
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ const closing = async(e, mainWindow) => {
app.quit()
}

ipcMain.handle('setSkipCheckDocker', async (e, skip) => await command.setSkipCheckDocker(skip))
ipcMain.handle('existSever', async () => await command.existSever())
ipcMain.handle('tags', async () => await command.tags())
ipcMain.handle('build', async (e, dat) => await command.build(dat, mainWindow))
ipcMain.handle('buildCompleted', () => command.buildCompleted())
ipcMain.handle('buildCache', () => command.buildCache(app.getPath('home'), process.platform==='win32'))
ipcMain.handle('buildCache', () => command.buildCache(process.platform==='win32'))
ipcMain.handle('generateQMKFile', async (e, dat) => await command.generateQMKFile(dat))
ipcMain.handle('generateVialId', async () => await command.generateVialId())
ipcMain.handle('updateRepository', async (e, fw) => await command.updateRepository(fw, mainWindow))
Expand All @@ -63,3 +64,5 @@ ipcMain.handle('convertViaJson', async (e, file) => await command.convertViaJso
ipcMain.handle('convertKleJson', async (e, obj) => await command.convertKleJson(obj))
ipcMain.handle('readJson', async (e, path) => await command.readJson(path))
ipcMain.handle('appVersion', () => app.getVersion())

ipcMain.handle('getLocalFWdir', () => command.getLocalFWdir())
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dist:linux": "npm run build && electron-builder -l"
},
"name": "gpk_fwbuilder",
"version": "0.6.2",
"version": "0.7.0",
"description": "GPK FWBuilder",
"homepage": "https://github.com/darakuneko",
"author": {
Expand Down
2 changes: 2 additions & 0 deletions preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ process.once('loaded', async () => {

contextBridge.exposeInMainWorld(
"api", {
setSkipCheckDocker: async (skip) => await ipcRenderer.invoke('setSkipCheckDocker', skip),
existSever: async () => await ipcRenderer.invoke('existSever'),
tags: async () => await ipcRenderer.invoke('tags'),
build: async (dat) => await ipcRenderer.invoke('build', dat),
Expand All @@ -20,6 +21,7 @@ process.once('loaded', async () => {
convertKleJson: async (obj) => await ipcRenderer.invoke('convertKleJson', obj),
readJson: async (path) => await ipcRenderer.invoke('readJson', path),
appVersion: async () => await ipcRenderer.invoke('appVersion'),
getLocalFWdir: async () => await ipcRenderer.invoke('getLocalFWdir'),
on: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args))
})
})
Loading

0 comments on commit 7fb5c49

Please sign in to comment.