mirror of
https://github.com/Macrame-App/Macrame
synced 2025-12-29 07:19:26 +00:00
Refactor: Moved Go app to the root and fixed links.
This commit is contained in:
parent
d1de67910d
commit
7157d43168
28 changed files with 100 additions and 164 deletions
123
app/helper/api-helper.go
Normal file
123
app/helper/api-helper.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"macrame/app/structs"
|
||||
. "macrame/app/structs"
|
||||
)
|
||||
|
||||
func EndpointAccess(w http.ResponseWriter, r *http.Request) (bool, string, error) {
|
||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
|
||||
if err != nil {
|
||||
return false, "", errors.New(r.URL.Path + ": SplitHostPort error: " + err.Error())
|
||||
}
|
||||
|
||||
if (isLocal(ip) && isEndpointAllowed("Local", r.URL.Path)) ||
|
||||
(isLanRemote(ip) && isEndpointAllowed("Remote", r.URL.Path)) {
|
||||
return true, "", nil
|
||||
} else if isLanRemote(ip) && isEndpointAllowed("Auth", r.URL.Path) {
|
||||
data, err := decryptAuth(r)
|
||||
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
return data != "", data, nil
|
||||
}
|
||||
|
||||
return false, "", errors.New(r.URL.Path + ": not authorized or accessible")
|
||||
}
|
||||
|
||||
func isLocal(ip string) bool {
|
||||
return ip == "127.0.0.1" || ip == "::1"
|
||||
}
|
||||
|
||||
func isLanRemote(ip string) bool {
|
||||
return strings.HasPrefix(ip, "192.168.")
|
||||
}
|
||||
|
||||
func isEndpointAllowed(source string, endpoint string) bool {
|
||||
var endpoints, err = getAllowedEndpoints(source)
|
||||
if err != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if (endpoints != nil) && (len(endpoints) > 0) {
|
||||
for _, e := range endpoints {
|
||||
if e == endpoint {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getAllowedEndpoints(source string) (endpoints []string, err string) {
|
||||
if source == "Local" {
|
||||
return Endpoints.Local, ""
|
||||
}
|
||||
if source == "Remote" {
|
||||
return Endpoints.Remote, ""
|
||||
}
|
||||
if source == "Auth" {
|
||||
return Endpoints.Auth, ""
|
||||
}
|
||||
|
||||
return []string{}, "No allowed endpoints"
|
||||
}
|
||||
|
||||
func decryptAuth(r *http.Request) (string, error) {
|
||||
var req structs.Authcall
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
|
||||
if err != nil || req.Uuid == "" || req.Data == "" {
|
||||
return "", errors.New("DecryptAuth Error: " + err.Error() + "; UUID: " + req.Uuid + "; Data: " + req.Data)
|
||||
}
|
||||
|
||||
deviceKey, errKey := GetKeyByUuid(req.Uuid)
|
||||
decryptData, errDec := DecryptAES(deviceKey, req.Data)
|
||||
|
||||
if errKey != nil && errDec != nil || decryptData == "" {
|
||||
return "", errors.New("DecryptAuth Error: " + errKey.Error() + "; " + errDec.Error() + "; UUID: " + req.Uuid + "; Data: " + req.Data)
|
||||
}
|
||||
|
||||
return decryptData, nil
|
||||
}
|
||||
|
||||
func ParseRequest(req interface{}, data string, r *http.Request) (d interface{}, err error) {
|
||||
if data != "" {
|
||||
dataBytes := []byte(data)
|
||||
return req, json.Unmarshal(dataBytes, &req)
|
||||
} else {
|
||||
return req, json.NewDecoder(r.Body).Decode(&req)
|
||||
}
|
||||
}
|
||||
44
app/helper/browser-helper.go
Normal file
44
app/helper/browser-helper.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func OpenBrowser(url string) bool {
|
||||
var args []string
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
args = []string{"open"}
|
||||
case "windows":
|
||||
args = []string{"cmd", "/c", "start"}
|
||||
default:
|
||||
args = []string{"xdg-open"}
|
||||
}
|
||||
|
||||
cmd := exec.Command(args[0], append(args[1:], url)...)
|
||||
|
||||
return cmd.Start() == nil
|
||||
}
|
||||
66
app/helper/device-helper.go
Normal file
66
app/helper/device-helper.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TempPinFile(Uuid string, pin string) (bool, error) {
|
||||
err := os.WriteFile("devices/"+Uuid+".tmp", []byte(pin), 0644)
|
||||
if err != nil {
|
||||
return false, errors.New("TempPinFile Error: " + err.Error())
|
||||
}
|
||||
|
||||
time.AfterFunc(1*time.Minute, func() {
|
||||
os.Remove("devices/" + Uuid + ".tmp")
|
||||
})
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func RemovePinFile(Uuid string) error { return os.Remove("devices/" + Uuid + ".tmp") }
|
||||
|
||||
func CheckPinFile(Uuid string) bool {
|
||||
_, err := os.Stat("devices/" + Uuid + ".tmp")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func SaveDeviceKey(Uuid string, key string) error {
|
||||
err := os.WriteFile("devices/"+Uuid+".key", []byte(key), 0644)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetKeyByUuid(Uuid string) (string, error) {
|
||||
data, err := os.ReadFile("devices/" + Uuid + ".key")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
135
app/helper/encrypt-helper.go
Normal file
135
app/helper/encrypt-helper.go
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
mathRand "math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func EncryptAES(key string, plaintext string) (string, error) {
|
||||
origData := []byte(plaintext)
|
||||
|
||||
// Create AES cipher
|
||||
block, err := aes.NewCipher(keyToBytes(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
blockSize := block.BlockSize()
|
||||
|
||||
origData = PKCS5Padding(origData, blockSize)
|
||||
|
||||
iv := []byte(EnvGet("MCRM__IV"))
|
||||
blockMode := cipher.NewCBCEncrypter(block, iv)
|
||||
|
||||
crypted := make([]byte, len(origData))
|
||||
blockMode.CryptBlocks(crypted, origData)
|
||||
|
||||
cryptedString := base64.StdEncoding.EncodeToString(crypted)
|
||||
|
||||
return cryptedString, nil
|
||||
}
|
||||
|
||||
func DecryptAES(key string, cryptedText string) (string, error) {
|
||||
crypted, err := base64.StdEncoding.DecodeString(cryptedText)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(keyToBytes(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
iv := []byte(EnvGet("MCRM__IV"))
|
||||
blockMode := cipher.NewCBCDecrypter(block, iv)
|
||||
|
||||
origData := make([]byte, len(crypted))
|
||||
|
||||
blockMode.CryptBlocks(origData, crypted)
|
||||
origData, err = PKCS5UnPadding(origData)
|
||||
|
||||
if err != nil || len(origData) <= 3 {
|
||||
return "", errors.New("invalid key")
|
||||
}
|
||||
|
||||
origDataString := string(origData)
|
||||
|
||||
return origDataString, nil
|
||||
}
|
||||
|
||||
func GenerateRandomString(length int) string {
|
||||
b := make([]byte, length)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
|
||||
func GenerateRandomIntegerString(length int) string {
|
||||
var sb strings.Builder
|
||||
for i := 0; i < length; i++ {
|
||||
sb.WriteByte('0' + byte(mathRand.Intn(10)))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func GenerateKey() string {
|
||||
return strings.Replace(GenerateRandomString(24), "=", "", -1)
|
||||
}
|
||||
|
||||
func keyToBytes(key string) []byte {
|
||||
// Convert key to bytes
|
||||
keyBytes := []byte(key)
|
||||
|
||||
// If key is 4 characters, append salt
|
||||
if len(key) == 4 {
|
||||
keyBytes = []byte(key + EnvGet("MCRM__SALT"))
|
||||
}
|
||||
|
||||
return keyBytes
|
||||
}
|
||||
|
||||
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(ciphertext)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(ciphertext, padtext...)
|
||||
}
|
||||
|
||||
func PKCS5UnPadding(origData []byte) ([]byte, error) {
|
||||
length := len(origData)
|
||||
unpadding := int(origData[length-1])
|
||||
|
||||
if (unpadding >= length) || (unpadding == 0) {
|
||||
return nil, errors.New("unpadding error")
|
||||
}
|
||||
|
||||
return origData[:(length - unpadding)], nil
|
||||
}
|
||||
128
app/helper/env-helper.go
Normal file
128
app/helper/env-helper.go
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var configPath = "public/config.js"
|
||||
|
||||
func EnvGet(key string) string {
|
||||
|
||||
if !configFileExists() {
|
||||
CreateConfigFile(configPath)
|
||||
CheckFeDevDir()
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
log.Println("Error reading config.js:", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
raw := strings.TrimSpace(string(data))
|
||||
raw = strings.TrimPrefix(raw, "window.__CONFIG__ = ")
|
||||
raw = strings.TrimSuffix(raw, ";")
|
||||
|
||||
var config map[string]string
|
||||
if err := json.Unmarshal([]byte(raw), &config); err != nil {
|
||||
log.Println("Error parsing config.js:", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return config[key]
|
||||
}
|
||||
|
||||
func configFileExists() bool {
|
||||
_, err := os.Stat(configPath)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func CheckFeDevDir() {
|
||||
log.Println("Checking FE dev directory...")
|
||||
_, err := os.Stat("fe")
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error checking FE dev directory:", err)
|
||||
return
|
||||
}
|
||||
|
||||
copyConfigToFe()
|
||||
}
|
||||
|
||||
func copyConfigToFe() {
|
||||
data, err := os.ReadFile(configPath)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error reading config.js:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.WriteFile("fe/config.js", data, 0644); err != nil {
|
||||
log.Println("Error writing config.js:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateConfigFile(filename string) {
|
||||
port, _ := findOpenPort()
|
||||
saltKey := GenerateKey()
|
||||
salt := saltKey[:28]
|
||||
iv := GenerateRandomIntegerString(16)
|
||||
|
||||
config := map[string]string{
|
||||
"MCRM__PORT": port,
|
||||
"MCRM__SALT": salt,
|
||||
"MCRM__IV": iv,
|
||||
}
|
||||
|
||||
jsonData, err := json.MarshalIndent(config, "", " ")
|
||||
if err != nil {
|
||||
log.Println("Error creating config JSON:", err)
|
||||
return
|
||||
}
|
||||
jsData := "window.__CONFIG__ = " + string(jsonData) + ";"
|
||||
|
||||
log.Println("Created JS config:", jsData)
|
||||
|
||||
if err := os.WriteFile(filename, []byte(jsData), 0644); err != nil {
|
||||
log.Println("Error writing config.js:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func findOpenPort() (string, error) {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer l.Close()
|
||||
return strconv.Itoa(l.Addr().(*net.TCPAddr).Port), nil
|
||||
}
|
||||
114
app/helper/macro-helper.go
Normal file
114
app/helper/macro-helper.go
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
)
|
||||
|
||||
func FormatMacroFileName(s string) string {
|
||||
// Remove invalid characters
|
||||
re := regexp.MustCompile(`[\/\?\*\>\<\:\"\|
|
||||
]`)
|
||||
s = re.ReplaceAllString(s, "")
|
||||
|
||||
// Replace spaces with underscores
|
||||
s = strings.ReplaceAll(s, " ", "_")
|
||||
|
||||
// Remove special characters
|
||||
re = regexp.MustCompile(`[!@#$%^&\(\)\[\]\{\}\~]`)
|
||||
s = re.ReplaceAllString(s, "")
|
||||
|
||||
// Truncate the string
|
||||
if len(s) > 255 {
|
||||
s = s[:255]
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func ReadMacroFile(filename string) (steps []map[string]interface{}, err error) {
|
||||
content, err := os.ReadFile(filename)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(content, &steps)
|
||||
|
||||
return steps, err
|
||||
}
|
||||
|
||||
func RunMacroSteps(steps []map[string]interface{}) error {
|
||||
for _, step := range steps {
|
||||
switch step["type"] {
|
||||
case "key":
|
||||
keyCode := step["code"].(string)
|
||||
|
||||
if strings.Contains(keyCode, "|") {
|
||||
keyCode = handleToggleCode(keyCode, step["direction"].(string))
|
||||
}
|
||||
|
||||
robotgo.KeyToggle(keyCode, step["direction"].(string))
|
||||
case "delay":
|
||||
|
||||
time.Sleep(time.Duration(step["value"].(float64)) * time.Millisecond)
|
||||
|
||||
default:
|
||||
return errors.New("RunMacroSteps Unknown step type: %v" + fmt.Sprint(step["type"]))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var toggleCodes = map[string]bool{}
|
||||
|
||||
func handleToggleCode(keyCode string, direction string) string {
|
||||
splitCodes := strings.Split(keyCode, "|")
|
||||
|
||||
if direction == "down" {
|
||||
if _, ok := toggleCodes[splitCodes[0]]; !ok {
|
||||
toggleCodes[splitCodes[0]] = true
|
||||
return splitCodes[0]
|
||||
}
|
||||
return splitCodes[1]
|
||||
}
|
||||
|
||||
if direction == "up" {
|
||||
if toggleCodes[splitCodes[0]] {
|
||||
toggleCodes[splitCodes[0]] = false
|
||||
return splitCodes[0]
|
||||
}
|
||||
delete(toggleCodes, splitCodes[0])
|
||||
return splitCodes[1]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
101
app/helper/translation-helper.go
Normal file
101
app/helper/translation-helper.go
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Macrame is a program that enables the user to create keyboard macros and button panels.
|
||||
The macros are saved as simple JSON files and can be linked to the button panels. The panels can
|
||||
be created with HTML and CSS.
|
||||
|
||||
Copyright (C) 2025 Jesse Malotaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package helper
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var translations = map[string]string{
|
||||
"ArrowUp": "up",
|
||||
"ArrowDown": "down",
|
||||
"ArrowRight": "right",
|
||||
"ArrowLeft": "left",
|
||||
"Meta": "cmd",
|
||||
"MetaLeft": "lcmd",
|
||||
"MetaRight": "rcmd",
|
||||
"Alt": "alt",
|
||||
"AltLeft": "lalt",
|
||||
"AltRight": "ralt",
|
||||
"Control": "ctrl",
|
||||
"ControlLeft": "lctrl",
|
||||
"ControlRight": "rctrl",
|
||||
"Shift": "shift",
|
||||
"ShiftLeft": "lshift",
|
||||
"ShiftRight": "rshift",
|
||||
"AudioVolumeMute": "audio_mute",
|
||||
"AudioVolumeDown": "audio_vol_down",
|
||||
"AudioVolumeUp": "audio_vol_up",
|
||||
"MediaTrackPrevious": "audio_prev",
|
||||
"MediaTrackNext": "audio_next",
|
||||
"MediaPlayPause": "audio_play|audio_pause",
|
||||
"Numpad0": "num0",
|
||||
"Numpad1": "num1",
|
||||
"Numpad2": "num2",
|
||||
"Numpad3": "num3",
|
||||
"Numpad4": "num4",
|
||||
"Numpad5": "num5",
|
||||
"Numpad6": "num6",
|
||||
"Numpad7": "num7",
|
||||
"Numpad8": "num8",
|
||||
"Numpad9": "num9",
|
||||
"NumLock": "num_lock",
|
||||
"NumpadDecimal": "num.",
|
||||
"NumpadAdd": "num+",
|
||||
"NumpadSubtract": "num-",
|
||||
"NumpadMultiply": "num*",
|
||||
"NumpadDivide": "num/",
|
||||
"NumpadEnter": "num_enter",
|
||||
"Clear": "num_clear",
|
||||
"BracketLeft": "[",
|
||||
"BracketRight": "]",
|
||||
"Quote": "'",
|
||||
"Semicolon": ";",
|
||||
"Backquote": "`",
|
||||
"Backslash": "\\",
|
||||
"IntlBackslash": "\\",
|
||||
"Slash": "/",
|
||||
"Comma": ",",
|
||||
"Period": ".",
|
||||
"Equal": "=",
|
||||
"Minus": "-",
|
||||
}
|
||||
|
||||
func Translate(code string) string {
|
||||
if val, ok := translations[code]; ok {
|
||||
return val
|
||||
}
|
||||
return strings.ToLower(code)
|
||||
}
|
||||
|
||||
func ReverseTranslate(name string) string {
|
||||
if name == "\\" {
|
||||
return "Backslash"
|
||||
}
|
||||
|
||||
for key, value := range translations {
|
||||
if value == name {
|
||||
return key
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue