Some more things

This commit is contained in:
Simon Martens
2025-03-21 14:48:40 +01:00
parent 2550fd151e
commit 52382a00e2
5 changed files with 149 additions and 39 deletions

63
.air.toml Normal file
View File

@@ -0,0 +1,63 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
full_bin = "./tmp/lenz"
cmd = "go build -tags=dev,fts5,sqlite_icu -o ./tmp/lenz ."
delay = 400
exclude_dir = [
"import",
"views",
"tmp",
"vendor",
"testdata",
"_cache",
"data_git",
"cache_gnd",
"cache_geonames",
"pb_data",
"Almanach-Bilder",
"Static-Bilder",
]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html", "gohtml", "js", "css", "xsl"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = [""]
rerun = false
rerun_delay = 250
send_interrupt = true
stop_on_error = true
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = false
[misc]
clean_on_exit = true
[proxy]
app_port = 8090
enabled = true
proxy_port = 8081
[screen]
clear_on_rebuild = true
keep_scroll = true

2
.gitignore vendored
View File

@@ -1 +1,3 @@
cache/
_cache/
tmp/

75
lenz.go
View File

@@ -1,16 +1,30 @@
package main
import (
"fmt"
"log/slog"
"path/filepath"
"time"
"github.com/Theodor-Springmann-Stiftung/lenz-web/config"
"github.com/Theodor-Springmann-Stiftung/lenz-web/git"
"github.com/Theodor-Springmann-Stiftung/lenz-web/xml"
gitprovider "github.com/Theodor-Springmann-Stiftung/lenz-web/git"
"github.com/Theodor-Springmann-Stiftung/lenz-web/server"
"github.com/Theodor-Springmann-Stiftung/lenz-web/templating"
"github.com/Theodor-Springmann-Stiftung/lenz-web/views"
xmlparsing "github.com/Theodor-Springmann-Stiftung/lenz-web/xml"
"github.com/Theodor-Springmann-Stiftung/lenz-web/xmlmodels"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/storage/memory/v2"
)
var REFRESH_CHANGES = []string{
"./views/assets",
}
var RESET_CHANGES = []string{
"./views/layouts",
"./views/routes",
}
func main() {
cfg, err := config.Get()
if err != nil {
@@ -29,8 +43,61 @@ func main() {
panic(err)
}
// INFO: the lib, engine and storage objects passed to the server are not made to
// be recreated.
lib := xmlmodels.NewLibrary()
lib.Parse(xmlparsing.Commit, dir, gp.Hash)
fmt.Println("Library: ", lib)
engine := templating.New(&views.LayoutFS, &views.RoutesFS)
storage := memory.New(memory.Config{
GCInterval: 24 * time.Hour,
})
if cfg.Debug {
SetupDebug(storage, engine)
}
server := server.New(engine, storage, cfg.Debug)
server.Start(cfg.Address + ":" + cfg.Port)
}
func SetupDebug(storage fiber.Storage, engine *templating.Engine) {
SetupRefreshWatcher(storage, engine)
SetupReloadWatcher(storage, engine)
engine.Debug()
}
func SetupRefreshWatcher(storage fiber.Storage, engine *templating.Engine) {
refreshwatcher, err := New(func() { RefreshFunction(storage, engine) })
if err != nil {
slog.Error("Error setting up refresh watcher, continuing without: ", "error:", err)
return
}
for _, path := range REFRESH_CHANGES {
refreshwatcher.AddRecursive(path)
}
}
func SetupReloadWatcher(storage fiber.Storage, engine *templating.Engine) {
resetwatcher, err := New(func() { ResetFunction(storage, engine) })
if err != nil {
slog.Error("Error setting up refresh watcher, continuing without: ", "error:", err)
return
}
for _, path := range RESET_CHANGES {
resetwatcher.AddRecursive(path)
}
}
func ResetFunction(storage fiber.Storage, engine *templating.Engine) {
storage.Reset()
engine.Reload()
}
func RefreshFunction(storage fiber.Storage, engine *templating.Engine) {
storage.Reset()
engine.Refresh()
}

View File

@@ -4,8 +4,9 @@ import (
"html/template"
"io"
"io/fs"
"log"
"log/slog"
"net/http"
"strconv"
"sync"
"github.com/Theodor-Springmann-Stiftung/lenz-web/helpers/functions"
@@ -15,6 +16,7 @@ import (
const (
ASSETS_URL_PREFIX = "/assets"
WS_SERVER = 9000
RELOAD_TEMPLATE = `
<script type="module">
(function () {
@@ -73,7 +75,7 @@ type Engine struct {
// INFO: We pass the app here to be able to access the config and other data for functions
// which also means we must reload the engine if the app changes
func NewEngine(layouts, templates *fs.FS) *Engine {
func New(layouts, templates *fs.FS) *Engine {
e := Engine{
regmu: &sync.Mutex{},
mu: &sync.Mutex{},
@@ -100,9 +102,9 @@ func (e *Engine) startWsServerOnPort9000() {
mux := http.NewServeMux()
mux.Handle("/pb/reload", websocket.Handler(e.ws.Handler))
log.Println("[Engine Debug] Starting separate WebSocket server on :9000 for live reload...")
if err := http.ListenAndServe(":9000", mux); err != nil {
log.Println("[Engine Debug] WebSocket server error:", err)
slog.Info("Starting separate WebSocket server for live reload...", "port", WS_SERVER)
if err := http.ListenAndServe(":"+strconv.Itoa(WS_SERVER), mux); err != nil {
slog.Debug("WebSocket server error", "error", err)
}
}
@@ -112,30 +114,6 @@ func (e *Engine) funcs() error {
// Passing HTML
e.AddFunc("Safe", functions.Safe)
// Creating an array or dict (to pass to a template)
// e.AddFunc("Arr", functions.Arr)
// e.AddFunc("Dict", functions.Dict)
// Datatype Functions
// e.AddFunc("HasPrefix", strings.HasPrefix)
// e.AddFunc("Contains", functions.Contains)
// e.AddFunc("Add", functions.Add)
// e.AddFunc("Len", functions.Length)
// String Functions
// e.AddFunc("Lower", functions.Lower)
// e.AddFunc("Upper", functions.Upper)
// e.AddFunc("First", functions.First)
// e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
// e.AddFunc("ReplaceSlashParenSlash", functions.ReplaceSlashParenSlash)
// e.AddFunc("LinksAnnotation", functions.LinksAnnotation)
//
// Time & Date Functions
// e.AddFunc("Today", functions.Today)
// e.AddFunc("GetMonth", functions.GetMonth)
//
// // TOC
// e.AddFunc("TOCFromHTML", functions.TOCFromHTML)
return nil
}

View File

@@ -2,7 +2,7 @@ package main
import (
"io/fs"
"log"
"log/slog"
"os"
"path/filepath"
"time"
@@ -19,7 +19,7 @@ type Watcher struct {
*fsnotify.Watcher
}
func RefreshWatcher(fn func()) (*Watcher, error) {
func New(fn func()) (*Watcher, error) {
watcher := Watcher{}
w, err := fsnotify.NewWatcher()
if err != nil {
@@ -40,7 +40,7 @@ func RefreshWatcher(fn func()) (*Watcher, error) {
reloadTimer.Stop()
}
reloadTimer = time.AfterFunc(WATCHER_DEBOUNCE, func() {
log.Println("Changes detected, reloading templates...")
slog.Debug("Changes detected, reloading templates...")
fn()
})
}
@@ -49,13 +49,13 @@ func RefreshWatcher(fn func()) (*Watcher, error) {
fi, statErr := os.Stat(event.Name)
if statErr == nil && fi.IsDir() {
_ = watcher.Add(event.Name)
log.Printf("Now watching new directory: %s", event.Name)
slog.Debug("Now watching new directory", "path", event.Name)
}
}
case err := <-watcher.Errors:
if err != nil {
log.Printf("fsnotify error: %v\n", err)
slog.Error("fsnotify error", "error", err)
}
case <-done:
@@ -78,7 +78,7 @@ func (w *Watcher) AddRecursive(root string) error {
if werr != nil {
return werr
}
log.Printf("Now watching directory: %s", path)
slog.Debug("Now watching directory", "path", path)
}
return nil
})