mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
scripts: replace dark-variant.sh with go scripts/variants
uses regex mostly, resulting in a significantly faster execution (old: ~2s, new: ~31ms). Only matches classList.add/remove and class="..." (won't touch string literal variables or colours), but these weren't really used anyway. Supports multi-line classList.add/remove, which was the reason I wrote this anyway (formatting the codebase introduced some of these).
This commit is contained in:
1
.git-blame-ignore-revs
Normal file
1
.git-blame-ignore-revs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
817107622a8fe6f2fdaf198da4b2632854aa9bac
|
||||||
9
Makefile
9
Makefile
@@ -142,11 +142,14 @@ TYPESCRIPT_TEMPSRC = $(TYPESCRIPT_SRC:ts/%=tempts/%)
|
|||||||
TYPESCRIPT_TARGET = $(DATA)/web/js/admin.js
|
TYPESCRIPT_TARGET = $(DATA)/web/js/admin.js
|
||||||
$(TYPESCRIPT_TARGET): $(TYPESCRIPT_FULLSRC) ts/tsconfig.json
|
$(TYPESCRIPT_TARGET): $(TYPESCRIPT_FULLSRC) ts/tsconfig.json
|
||||||
$(TYPECHECK)
|
$(TYPECHECK)
|
||||||
|
# rm -rf tempts
|
||||||
|
# cp -r ts tempts
|
||||||
rm -rf tempts
|
rm -rf tempts
|
||||||
cp -r ts tempts
|
mkdir -p tempts
|
||||||
$(adding dark variants to typescript)
|
$(adding dark variants to typescript)
|
||||||
scripts/dark-variant.sh tempts
|
# scripts/dark-variant.sh tempts
|
||||||
scripts/dark-variant.sh tempts/modules
|
# scripts/dark-variant.sh tempts/modules
|
||||||
|
go run scripts/variants/main.go -dir ts -out tempts
|
||||||
$(info compiling typescript)
|
$(info compiling typescript)
|
||||||
$(foreach tempsrc,$(TYPESCRIPT_TEMPSRC),$(ESBUILD) --target=es6 --bundle $(tempsrc) $(SOURCEMAP) --outfile=$(patsubst %.ts,%.js,$(subst tempts/,./$(DATA)/web/js/,$(tempsrc))) $(MINIFY);)
|
$(foreach tempsrc,$(TYPESCRIPT_TEMPSRC),$(ESBUILD) --target=es6 --bundle $(tempsrc) $(SOURCEMAP) --outfile=$(patsubst %.ts,%.js,$(subst tempts/,./$(DATA)/web/js/,$(tempsrc))) $(MINIFY);)
|
||||||
$(COPYTS)
|
$(COPYTS)
|
||||||
|
|||||||
9
main.go
9
main.go
@@ -23,15 +23,16 @@ import (
|
|||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
|
"github.com/hrfee/mediabrowser"
|
||||||
|
"github.com/lithammer/shortuuid/v3"
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
"github.com/hrfee/jfa-go/common"
|
"github.com/hrfee/jfa-go/common"
|
||||||
_ "github.com/hrfee/jfa-go/docs"
|
_ "github.com/hrfee/jfa-go/docs"
|
||||||
"github.com/hrfee/jfa-go/jellyseerr"
|
"github.com/hrfee/jfa-go/jellyseerr"
|
||||||
"github.com/hrfee/jfa-go/logger"
|
"github.com/hrfee/jfa-go/logger"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/hrfee/jfa-go/ombi"
|
"github.com/hrfee/jfa-go/ombi"
|
||||||
"github.com/hrfee/mediabrowser"
|
|
||||||
"github.com/lithammer/shortuuid/v3"
|
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -77,7 +78,9 @@ var serverTypes = map[string]string{
|
|||||||
"jellyfin": "Jellyfin",
|
"jellyfin": "Jellyfin",
|
||||||
"emby": "Emby (experimental)",
|
"emby": "Emby (experimental)",
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverType = mediabrowser.JellyfinServer
|
var serverType = mediabrowser.JellyfinServer
|
||||||
|
|
||||||
var substituteStrings = ""
|
var substituteStrings = ""
|
||||||
|
|
||||||
var externalURI, externalDomain string // The latter lower-case as should be accessed through app.ExternalDomain()
|
var externalURI, externalDomain string // The latter lower-case as should be accessed through app.ExternalDomain()
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# scan all typescript and automatically add dark variants to color tags if they're not already present.
|
|
||||||
|
|
||||||
for f in $1/*.ts; do
|
|
||||||
# FIXME: inline html
|
|
||||||
for l in $(grep -n "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" $f | sed -e 's/:.*//g'); do
|
|
||||||
# for l in $(sed -n '/classList/=' $f); do
|
|
||||||
line=$(sed -n "${l}p" $f)
|
|
||||||
echo $line | grep "classList" &> /dev/null
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo $line | sed 's/.*classList//; s/).*//' | grep "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" &> /dev/null
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
# echo "found classList @ " $l
|
|
||||||
echo $line | grep "dark:" &>/dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
for color in neutral positive urge warning info critical; do
|
|
||||||
sed -i "${l},${l}s/\"~${color}\"/\"~${color}\", \"dark:~d_${color}\"/g" $f
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "FIX: classList found, but color tag wasn't in it"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo $line | grep "querySelector" &> /dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# echo "found inline in " $f " @ " $l ", " $(sed -n "${l}p" $f)
|
|
||||||
echo $line | grep "dark:" &>/dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
for color in neutral positive urge warning info critical; do
|
|
||||||
sed -i "${l},${l}s/~${color}/~${color} dark:~d_${color}/g" $f
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo $line | sed 's/.*querySelector//; s/).*//' | grep "~neutral\|~positive\|~urge\|~warning\|~info\|~critical" &> /dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo $line | grep "dark:" &>/dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# echo "found inline in " $f " @ " $l ", " $(sed -n "${l}p" $f)
|
|
||||||
for color in neutral positive urge warning info critical; do
|
|
||||||
sed -i "${l},${l}s/~${color}/~${color} dark:~d_${color}/g" $f
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
#else
|
|
||||||
#echo "FIX: querySelector found, but color tag wasn't in it: " $line
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
3
scripts/variants/go.mod
Normal file
3
scripts/variants/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module github.com/hrfee/jfa-go/scripts/variants
|
||||||
|
|
||||||
|
go 1.25.4
|
||||||
146
scripts/variants/main.go
Normal file
146
scripts/variants/main.go
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
// Package variants provides a script to comb through typescript/javascript files and
|
||||||
|
// find (most) instances of a a17t color (~neutral...) being used without
|
||||||
|
// an accompanying dark version (dark:~d_neutral...) and insert one.
|
||||||
|
// Not fully feature-matched with the old bash version, only matching classList.add/remove and class="...",
|
||||||
|
// but doesn't break on multi line function params, and is probably much faster.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
var classList = func() *regexp.Regexp {
|
||||||
|
classList, err := regexp.Compile(`classList\.(add|remove)(\((?:[^()]*|\((?:[^()]*|\([^()]*\))\))*\))`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return classList
|
||||||
|
}()
|
||||||
|
var color = func() *regexp.Regexp {
|
||||||
|
color, err := regexp.Compile(`\~(neutral|positive|warning|critical|info|urge|gray)`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}()
|
||||||
|
var quotedColor = func() *regexp.Regexp {
|
||||||
|
quotedColor, err := regexp.Compile(`("|'|\x60)\~(neutral|positive|warning|critical|info|urge|gray)("|'|\x60)`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return quotedColor
|
||||||
|
}()
|
||||||
|
var htmlClassList = func() *regexp.Regexp {
|
||||||
|
htmlClassList, err := regexp.Compile(`class="[^"]*\~(neutral|positive|warning|critical|info|urge|gray)[^"]*"`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return htmlClassList
|
||||||
|
}()
|
||||||
|
|
||||||
|
func ParseDir(in, out string) error {
|
||||||
|
err := filepath.WalkDir(in, func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
perm := info.Mode()
|
||||||
|
rel, err := filepath.Rel(in, path)
|
||||||
|
outFile := filepath.Join(out, rel)
|
||||||
|
if d.IsDir() {
|
||||||
|
return os.MkdirAll(outFile, perm)
|
||||||
|
}
|
||||||
|
log.Printf("\"%s\" => \"%s\"\n", path, outFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ParseFile(path, outFile, &perm)
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseFile(in, out string, perm *fs.FileMode) error {
|
||||||
|
file, err := os.ReadFile(in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if perm == nil {
|
||||||
|
f, err := os.Stat(in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p := f.Mode()
|
||||||
|
perm = &p
|
||||||
|
}
|
||||||
|
|
||||||
|
outText := classList.ReplaceAllFunc(file, func(match []byte) []byte {
|
||||||
|
if bytes.Contains(match, []byte("dark:~d_")) {
|
||||||
|
log.Printf("Skipping pre-set dark colour: `%s`\n", string(match))
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
submatches := quotedColor.FindSubmatch(match)
|
||||||
|
if len(submatches) == 0 {
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
quote := string(submatches[1])
|
||||||
|
color := string(submatches[2])
|
||||||
|
fmt.Printf("Matched quote %s, color %s\n", quote, color)
|
||||||
|
newVal := bytes.Replace(match, []byte(quote+"~"+color+quote), []byte(quote+"~"+color+quote+", "+quote+"dark:~d_"+color+quote), 1)
|
||||||
|
fmt.Printf("`%s` => `%s`\n", string(match), string(newVal))
|
||||||
|
return newVal
|
||||||
|
})
|
||||||
|
|
||||||
|
outText = htmlClassList.ReplaceAllFunc(outText, func(match []byte) []byte {
|
||||||
|
if bytes.Contains(match, []byte("dark:~d_")) {
|
||||||
|
log.Printf("Skipping pre-set dark colour: `%s`\n", string(match))
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
// Sucks we can't get a submatch from ReplaceAllFunc
|
||||||
|
submatches := color.FindSubmatch(match)
|
||||||
|
if len(submatches) == 0 {
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
c := submatches[1]
|
||||||
|
newVal := bytes.Replace(match, []byte("~"+string(c)), []byte("~"+string(c)+" dark:~d_"+string(c)), 1)
|
||||||
|
fmt.Printf("`%s` => `%s`\n", string(match), string(newVal))
|
||||||
|
return newVal
|
||||||
|
})
|
||||||
|
err = os.WriteFile(out, outText, *perm)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var inFile, inDir, out string
|
||||||
|
flag.StringVar(&inFile, "file", "", "Input of an individual file.")
|
||||||
|
flag.StringVar(&inDir, "dir", "", "Input of a whole directory.")
|
||||||
|
flag.StringVar(&out, "out", "", "Output filepath/directory, depending on if -file or -dir passed.")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if out == "" {
|
||||||
|
flag.PrintDefaults()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if inFile != "" {
|
||||||
|
err = ParseFile(inFile, out, nil)
|
||||||
|
} else if inDir != "" {
|
||||||
|
err = ParseDir(inDir, out)
|
||||||
|
} else {
|
||||||
|
flag.PrintDefaults()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -472,13 +472,12 @@ export function throttle(callback: () => void, limitMilliseconds: number): () =>
|
|||||||
export function SetupCopyButton(
|
export function SetupCopyButton(
|
||||||
button: HTMLButtonElement,
|
button: HTMLButtonElement,
|
||||||
text: string | (() => string),
|
text: string | (() => string),
|
||||||
baseClass?: string,
|
baseClasses?: string[],
|
||||||
notif?: string,
|
notif?: string,
|
||||||
) {
|
) {
|
||||||
if (!notif) notif = window.lang.strings("copied");
|
if (!notif) notif = window.lang.strings("copied");
|
||||||
if (!baseClass) baseClass = "~info";
|
if (!baseClasses || baseClasses.length == 0) baseClasses = ["~info", "dark:~d_info"];
|
||||||
// script will probably turn this into multiple
|
// script will probably turn this into multiple
|
||||||
const baseClasses = baseClass.split(" ");
|
|
||||||
button.type = "button";
|
button.type = "button";
|
||||||
button.classList.add("button", ...baseClasses, "@low", "p-1");
|
button.classList.add("button", ...baseClasses, "@low", "p-1");
|
||||||
button.title = window.lang.strings("copy");
|
button.title = window.lang.strings("copy");
|
||||||
@@ -505,8 +504,8 @@ export function SetupCopyButton(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CopyButton(text: string | (() => string), baseClass?: string, notif?: string): HTMLButtonElement {
|
export function CopyButton(text: string | (() => string), baseClasses?: string[], notif?: string): HTMLButtonElement {
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
SetupCopyButton(button, text, baseClass, notif);
|
SetupCopyButton(button, text, baseClasses, notif);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user