summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--main.go52
-rw-r--r--pkg/atexit/atexit.go13
-rw-r--r--pkg/try/try.go (renamed from src/try/try.go)9
-rw-r--r--pkg/watch/watch.go41
-rw-r--r--src/dbx/db.go7
-rw-r--r--src/http.go8
-rw-r--r--src/i18n.go2
-rw-r--r--src/templates.go40
-rw-r--r--src/templates/coins-designs-ad.html.tmpl2
-rw-r--r--src/templates/coins-designs-be.html.tmpl5
-rw-r--r--src/templates/coins-designs-hr.html.tmpl8
-rw-r--r--static/fonts/ysabeau-office-regular-italic.otfbin0 -> 213512 bytes
-rw-r--r--static/fonts/ysabeau-office-regular.otfbin0 -> 272220 bytes
-rw-r--r--static/fonts/ysabeau-regular-italic.woff2bin50700 -> 0 bytes
-rw-r--r--static/fonts/ysabeau-regular.woff2bin47828 -> 0 bytes
-rw-r--r--static/style.css12
17 files changed, 128 insertions, 72 deletions
diff --git a/.gitattributes b/.gitattributes
index 89147c5..0e79892 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,4 @@
*.avif binary
*.jpg binary
+*.otf binary
vendor/ linguist-vendored \ No newline at end of file
diff --git a/main.go b/main.go
index f5c039a..a9b9ea7 100644
--- a/main.go
+++ b/main.go
@@ -5,16 +5,18 @@ package main
import (
"flag"
- "log"
"os"
+ "os/signal"
"path/filepath"
"syscall"
- "time"
+
+ "git.thomasvoss.com/euro-cash.eu/pkg/atexit"
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
+ "git.thomasvoss.com/euro-cash.eu/pkg/watch"
"git.thomasvoss.com/euro-cash.eu/src"
"git.thomasvoss.com/euro-cash.eu/src/dbx"
"git.thomasvoss.com/euro-cash.eu/src/email"
- . "git.thomasvoss.com/euro-cash.eu/src/try"
)
func main() {
@@ -38,39 +40,23 @@ func main() {
"database name or ‘:memory:’ for an in-memory database")
flag.Parse()
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
+ go func() {
+ <-sigs
+ atexit.Exec()
+ os.Exit(0)
+ }()
+
if *debugp {
- go watch()
+ path := Try2(os.Executable())
+ go watch.File(path, func() {
+ atexit.Exec()
+ Try(syscall.Exec(path, os.Args, os.Environ()))
+ })
}
dbx.Init(Try2(os.OpenRoot("src/dbx/sql")).FS())
- app.BuildTemplates(Try2(os.OpenRoot("src/templates")).FS())
+ app.BuildTemplates(Try2(os.OpenRoot("src/templates")).FS(), *debugp)
app.Run(*port)
}
-
-func watch() {
- path, err := os.Executable()
- if err != nil {
- log.Fatal(err)
- }
-
- ostat, err := os.Stat(path)
- if err != nil {
- log.Fatal(err)
- }
-
- for {
- nstat, err := os.Stat(path)
- if err != nil {
- log.Fatal(err)
- }
-
- if nstat.ModTime() != ostat.ModTime() {
- dbx.Close()
- if err := syscall.Exec(path, os.Args, os.Environ()); err != nil {
- log.Fatal(err)
- }
- }
-
- time.Sleep(1 * time.Second)
- }
-}
diff --git a/pkg/atexit/atexit.go b/pkg/atexit/atexit.go
new file mode 100644
index 0000000..a349649
--- /dev/null
+++ b/pkg/atexit/atexit.go
@@ -0,0 +1,13 @@
+package atexit
+
+var hooks = []func(){}
+
+func Register(f func()) {
+ hooks = append(hooks, f)
+}
+
+func Exec() {
+ for i := len(hooks) - 1; i >= 0; i-- {
+ hooks[i]()
+ }
+}
diff --git a/src/try/try.go b/pkg/try/try.go
index fc086d1..2576dcd 100644
--- a/src/try/try.go
+++ b/pkg/try/try.go
@@ -1,10 +1,15 @@
package try
-import "log"
+import (
+ "log"
+
+ "git.thomasvoss.com/euro-cash.eu/pkg/atexit"
+)
func Try(e error) {
if e != nil {
- log.Fatal(e)
+ atexit.Exec()
+ log.Fatalln(e)
}
}
diff --git a/pkg/watch/watch.go b/pkg/watch/watch.go
new file mode 100644
index 0000000..f409dac
--- /dev/null
+++ b/pkg/watch/watch.go
@@ -0,0 +1,41 @@
+package watch
+
+import (
+ "errors"
+ "io/fs"
+ "log"
+ "os"
+ "time"
+
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
+)
+
+func File(path string, f func()) {
+ impl(path, os.Stat, f)
+}
+
+func FileFS(dir fs.FS, path string, f func()) {
+ impl(path, func(path string) (os.FileInfo, error) {
+ return fs.Stat(dir, path)
+ }, f)
+}
+
+func impl(path string, statfn func(string) (os.FileInfo, error), f func()) {
+ ostat := Try2(statfn(path))
+
+ for {
+ nstat, err := statfn(path)
+ switch {
+ case errors.Is(err, os.ErrNotExist):
+ return
+ case err != nil:
+ log.Println(err)
+ }
+
+ if nstat.ModTime() != ostat.ModTime() {
+ f()
+ ostat = nstat
+ }
+ time.Sleep(1 * time.Second)
+ }
+}
diff --git a/src/dbx/db.go b/src/dbx/db.go
index 5bd65a5..fcb345e 100644
--- a/src/dbx/db.go
+++ b/src/dbx/db.go
@@ -9,9 +9,9 @@ import (
"sort"
"strings"
+ "git.thomasvoss.com/euro-cash.eu/pkg/atexit"
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
"github.com/mattn/go-sqlite3"
-
- . "git.thomasvoss.com/euro-cash.eu/src/try"
)
var (
@@ -22,6 +22,7 @@ var (
func Init(sqlDir fs.FS) {
db = Try2(sql.Open("sqlite3", DBName))
Try(db.Ping())
+ atexit.Register(Close)
Try(applyMigrations(sqlDir))
/* TODO: Remove debug code */
@@ -120,7 +121,7 @@ func applyMigrations(dir fs.FS) error {
if err := tx.Commit(); err != nil {
return err
}
- log.Printf("Applied database migration ‘%s’", f)
+ log.Printf("Applied database migration ‘%s’\n", f)
}
if last != "" {
diff --git a/src/http.go b/src/http.go
index a5897b4..6feb865 100644
--- a/src/http.go
+++ b/src/http.go
@@ -12,6 +12,8 @@ import (
"strconv"
"strings"
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
+
"git.thomasvoss.com/euro-cash.eu/src/dbx"
"git.thomasvoss.com/euro-cash.eu/src/email"
)
@@ -41,9 +43,7 @@ func Run(port int) {
portStr := ":" + strconv.Itoa(port)
log.Println("Listening on", portStr)
- err := http.ListenAndServe(portStr, mux)
- dbx.Close()
- log.Fatal(err)
+ Try(http.ListenAndServe(portStr, mux))
}
func chain(xs ...middleware) middleware {
@@ -179,7 +179,7 @@ func throwError(status int, err error, w http.ResponseWriter, r *http.Request) {
w.WriteHeader(status)
go func() {
if err := email.ServerError(err); err != nil {
- log.Print(err)
+ log.Println(err)
}
}()
errorTmpl.Execute(w, struct {
diff --git a/src/i18n.go b/src/i18n.go
index 726a75c..cb54e28 100644
--- a/src/i18n.go
+++ b/src/i18n.go
@@ -261,7 +261,7 @@ func (p Printer) M(val any) string {
default:
go func() {
if err := email.ServerError(badMType{"TODO"}); err != nil {
- log.Print(err)
+ log.Println(err)
}
}()
/* Hopefully this never happens */
diff --git a/src/templates.go b/src/templates.go
index 8479759..4deeb67 100644
--- a/src/templates.go
+++ b/src/templates.go
@@ -7,6 +7,9 @@ import (
"log"
"strings"
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
+ "git.thomasvoss.com/euro-cash.eu/pkg/watch"
+
"git.thomasvoss.com/euro-cash.eu/src/dbx"
)
@@ -31,29 +34,36 @@ var (
}
)
-func BuildTemplates(dir fs.FS) {
- ents, err := fs.ReadDir(dir, ".")
- if err != nil {
- log.Fatal(err)
- }
-
+func BuildTemplates(dir fs.FS, debugp bool) {
+ ents := Try2(fs.ReadDir(dir, "."))
notFoundTmpl = buildTemplate(dir, "-404")
errorTmpl = buildTemplate(dir, "-error")
-
templates = make(map[string]*template.Template, len(ents))
+
for _, e := range ents {
- path := "/"
- name := strings.TrimSuffix(e.Name(), ".html.tmpl")
- switch {
- case name[0] == '-':
- continue
- case name != "index":
- path += strings.ReplaceAll(name, "-", "/")
+ name := e.Name()
+ buildAndSetTemplate(dir, name)
+ if debugp {
+ go watch.FileFS(dir, name, func() {
+ buildAndSetTemplate(dir, name)
+ log.Printf("Template ‘%s’ updated\n", name)
+ })
}
- templates[path] = buildTemplate(dir, name)
}
}
+func buildAndSetTemplate(dir fs.FS, name string) {
+ path := "/"
+ name = strings.TrimSuffix(name, ".html.tmpl")
+ switch {
+ case name[0] == '-':
+ return
+ case name != "index":
+ path += strings.ReplaceAll(name, "-", "/")
+ }
+ templates[path] = buildTemplate(dir, name)
+}
+
func buildTemplate(dir fs.FS, name string) *template.Template {
names := [...]string{"-base", "-navbar", name}
for i, s := range names {
diff --git a/src/templates/coins-designs-ad.html.tmpl b/src/templates/coins-designs-ad.html.tmpl
index c42930a..20199bb 100644
--- a/src/templates/coins-designs-ad.html.tmpl
+++ b/src/templates/coins-designs-ad.html.tmpl
@@ -85,7 +85,7 @@
{{ .T `
The bottom of the coat of arms has the motto ‘%sVIRTVS VNITA
FORTIOR%s’ (‘UNITED VIRTUE IS STRONGER’).
- ` `<span lang="la">` `</span>` }}
+ ` `<span lang="la">` `</span>` | safe }}
</p>
</main>
{{ end }} \ No newline at end of file
diff --git a/src/templates/coins-designs-be.html.tmpl b/src/templates/coins-designs-be.html.tmpl
index 22f533f..4dcd325 100644
--- a/src/templates/coins-designs-be.html.tmpl
+++ b/src/templates/coins-designs-be.html.tmpl
@@ -21,8 +21,7 @@
target="_blank"
href="https://www.wikipedia.org/wiki/Royal_cypher"
>`
- `</a>`
- }}
+ `</a>` | safe }}
</p>
<p>
{{ .T `
@@ -44,4 +43,4 @@
` }}
</p>
</main>
-{{ end }}
+{{ end }} \ No newline at end of file
diff --git a/src/templates/coins-designs-hr.html.tmpl b/src/templates/coins-designs-hr.html.tmpl
index b6333ba..8b6976f 100644
--- a/src/templates/coins-designs-hr.html.tmpl
+++ b/src/templates/coins-designs-hr.html.tmpl
@@ -26,10 +26,10 @@
<p>
{{ .T `
The 1-, 2-, and 5 euro cent coins were designed by Maja
- Škripelj and feature a motif of the letters ‘HR’ in the
+ Škripelj and feature a motif of the letters ‘ⰘⰓ’ from the
%sGlagolitic script%s — an old Slavic script that saw use in
- Croatia up until the 19th century — with ‘HR’ representing
- Croatia’s country code.`
+ Croatia up until the 19th century — representing Croatia’s country
+ code (‘HR’ in the Latin alphabet).`
`<a
target="_blank"
href="https://www.wikipedia.org/wiki/Glagolitic_script"
@@ -80,4 +80,4 @@
`</a>` | safe }}
</p>
</main>
-{{ end }}
+{{ end }} \ No newline at end of file
diff --git a/static/fonts/ysabeau-office-regular-italic.otf b/static/fonts/ysabeau-office-regular-italic.otf
new file mode 100644
index 0000000..eb92805
--- /dev/null
+++ b/static/fonts/ysabeau-office-regular-italic.otf
Binary files differ
diff --git a/static/fonts/ysabeau-office-regular.otf b/static/fonts/ysabeau-office-regular.otf
new file mode 100644
index 0000000..cb8d758
--- /dev/null
+++ b/static/fonts/ysabeau-office-regular.otf
Binary files differ
diff --git a/static/fonts/ysabeau-regular-italic.woff2 b/static/fonts/ysabeau-regular-italic.woff2
deleted file mode 100644
index a517fdc..0000000
--- a/static/fonts/ysabeau-regular-italic.woff2
+++ /dev/null
Binary files differ
diff --git a/static/fonts/ysabeau-regular.woff2 b/static/fonts/ysabeau-regular.woff2
deleted file mode 100644
index 95c7715..0000000
--- a/static/fonts/ysabeau-regular.woff2
+++ /dev/null
Binary files differ
diff --git a/static/style.css b/static/style.css
index 023317c..2bce9d4 100644
--- a/static/style.css
+++ b/static/style.css
@@ -27,22 +27,22 @@
*/
@font-face {
- font-family: 'Ysabeau';
- src: url('/fonts/ysabeau-regular.woff2') format('woff2');
+ font-family: 'Ysabeau Office';
+ src: url('/fonts/ysabeau-office-regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
- font-family: 'Ysabeau';
- src: url('/fonts/ysabeau-regular-italic.woff2') format('woff2');
+ font-family: 'Ysabeau Office';
+ src: url('/fonts/ysabeau-office-regular-italic.otf') format('opentype');
font-weight: normal;
font-style: italic;
}
:root {
- --font-family: "Ysabeau", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
- "Segoe UI Symbol", "Noto Color Emoji";
+ --font-family: "Ysabeau Office", sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--line-height: 1.5;
--font-weight: 400;
--font-size: 16px;