From 9dca6a57df1c9ee9fb069c2d75726e12f70aed4d Mon Sep 17 00:00:00 2001 From: jbergner Date: Sat, 10 May 2025 19:17:30 +0200 Subject: [PATCH 01/12] Bugfix --- .gitea/workflows/staging.yml | 15 ++++++++++++++- Dockerfile | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/staging.yml b/.gitea/workflows/staging.yml index b3904dd..f80276a 100644 --- a/.gitea/workflows/staging.yml +++ b/.gitea/workflows/staging.yml @@ -48,4 +48,17 @@ jobs: push: true tags: | # replace it with your local IP and tags ${{ vars.DOCKER_REGISTRY }}/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }} - ${{ vars.DOCKER_REGISTRY }}/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }} \ No newline at end of file + ${{ vars.DOCKER_REGISTRY }}/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }} + - name: Build and push StarCitizen + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + build-args: | + CONTENT_REPO=https://git.send.nrw/b1tsblog/sccontent.git + CONTENT_REF=main + platforms: | + linux/amd64 + push: true + tags: | # replace it with your local IP and tags + ${{ vars.DOCKER_REGISTRY }}/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:sc-${{ env.DOCKER_LATEST }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a46e6f3..cff442f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN git clone --depth 1 --branch ${CONTENT_REF} ${CONTENT_REPO} /src # • statische Seiten: /pages/* → /out/pages # (Pfad‑Anpassung hier nach DEINEM Repository‑Layout) -RUN mkdir -p /out/content /out/static /out/pages +RUN mkdir -p /out/content /out/static /out/pages /out/templates/ RUN find /src/articles -name '*.md' -exec cp {} /out/content/ \; RUN cp -r /src/static/* /out/static/ RUN cp -r /src/pages/* /out/pages/ From 278d3aa48f5df44e2b2625d75a5502db7f6e35f9 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sat, 10 May 2025 22:10:09 +0200 Subject: [PATCH 02/12] Invictus 2955 - Das Jahr der Idris-P? --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 4440b00..6f44afc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # b1tsblog +## B1tsBlog + - Windows Server 2025 Domänen-Controller legt Netzwerkprofil auf Öffentlich fest - TLS-Zertifikat mit SHA3 auf Windows Server 2016 einspielen - Warum personenbezogene Daten nie in die Betreffzeile einer E-Mail gehören @@ -15,3 +17,7 @@ - Ein eigenes Docker-Image erstellen - so geht's - Der eigene DNS-Server im Homelab - Content-Update 2025-05-04 + +## B1ts Star Citizen Blog + +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file From 8b7f1127f81648d6423f7fc4ecc7e763dcc5aec9 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sat, 10 May 2025 22:19:11 +0200 Subject: [PATCH 03/12] Fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f44afc..c52be7e 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ ## B1ts Star Citizen Blog -- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file From 847d860144cc21698fa4a97c0abc74c11780543e Mon Sep 17 00:00:00 2001 From: jbergner Date: Sat, 10 May 2025 22:26:03 +0200 Subject: [PATCH 04/12] Patch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c52be7e..6f44afc 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ ## B1ts Star Citizen Blog -- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file From 08ef9c7132a2e210fd186eb3b7804e7da05a73c6 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 10:57:36 +0200 Subject: [PATCH 05/12] Implementierung eines anonymen Counters - Nicht persistent --- Dockerfile | 3 +- cmd/blog/main.go | 68 +++++++++++++++++++++----------- internal/article/model.go | 1 + internal/web/static/main.css | 1 + internal/web/templates/list.html | 1 + 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/Dockerfile b/Dockerfile index cff442f..065aa59 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,7 +48,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY --from=build /blog /usr/local/bin/blog # ─── Content + Assets ─── -RUN mkdir -p /content /static /pages /app +RUN mkdir -p /content /static /pages /app /templates /ticks COPY . /app COPY --from=content /out/content /content COPY --from=content /out/static /static @@ -59,6 +59,7 @@ ENV BLOG_CONTENT_DIR=/content ENV BLOG_STATIC_DIR=/static ENV BLOG_PAGES_DIR=/pages ENV BLOG_TEMPLATES_DIR=/templates +ENV BLOG_TICKS_DIR=/ticks EXPOSE 8080 CMD ["blog"] diff --git a/cmd/blog/main.go b/cmd/blog/main.go index fe652ed..55062bc 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -12,6 +12,35 @@ import ( "git.send.nrw/sendnrw/b1tsblog/internal/article" ) +var TickCatalog []TickEntry + +func IncTick(xSlug string) error { + for a, b := range TickCatalog { + if b.Slug == xSlug { + TickCatalog[a].Count = TickCatalog[a].Count + 1 + return nil + } + } + newEntry := TickEntry{Slug: xSlug, Count: 1} + TickCatalog = append(TickCatalog, newEntry) + return fmt.Errorf("") +} + +func getTick(xSlug string) string { + for _, b := range TickCatalog { + if b.Slug == xSlug { + var n int64 = b.Count + return strconv.FormatInt(n, 10) + } + } + return "-1" +} + +type TickEntry struct { + Slug string + Count int64 +} + func getenv(k, d string) string { if v := os.Getenv(k); v != "" { return v @@ -42,35 +71,17 @@ var ( func main() { // --- Verzeichnisse konfigurierbar machen ------------------------- - contentDir := os.Getenv("BLOG_CONTENT_DIR") - if contentDir == "" { - contentDir = "/content" // Fallback für local run - } - - staticDir := os.Getenv("BLOG_STATIC_DIR") - if staticDir == "" { - staticDir = "/app/internal/web/static" - } - - pagesDir := os.Getenv("BLOG_PAGES_DIR") - if staticDir == "" { - staticDir = "/pages" - } - - templatesDir := os.Getenv("BLOG_TEMPLATES_DIR") - if templatesDir == "" { - templatesDir = "/templates" - } + contentDir := getenv("BLOG_CONTENT_DIR", "/content") + staticDir := getenv("BLOG_STATIC_DIR", "/app/internal/web/static") + pagesDir := getenv("BLOG_PAGES_DIR", "/pages") + templatesDir := getenv("BLOG_TEMPLATES_DIR", "/templates") funcs := template.FuncMap{ "now": time.Now, // jetzt‑Zeit bereitstellen } // Basislayout zuerst parsen - layout := template.Must( - template.New("base").Funcs(funcs). - ParseFiles(templatesDir + "/base.html"), - ) + layout := template.Must(template.New("base").Funcs(funcs).ParseFiles(templatesDir + "/base.html")) // LIST‑Seite: base + list.html tplList = template.Must(layout.Clone()) @@ -90,6 +101,14 @@ func main() { fmt.Println(err) } + /* */ + + for a, b := range articles { + articles[a].Counter = getTick(b.Slug) + } + + /* */ + staticPages, err := article.LoadStatic(pagesDir) if err != nil { fmt.Println(err) @@ -116,6 +135,9 @@ func main() { slug := strings.TrimPrefix(r.URL.Path, "/post/") for _, a := range articles { if a.Slug == slug { + IncTick(slug) + t := getTick(slug) + a.Counter = t if err := tplArticle.ExecuteTemplate(w, "layout", a); err != nil { http.Error(w, err.Error(), 500) } diff --git a/internal/article/model.go b/internal/article/model.go index 0f1dbf6..932bf17 100644 --- a/internal/article/model.go +++ b/internal/article/model.go @@ -13,6 +13,7 @@ type Article struct { Cover string Body template.HTML Description string + Counter string } type ListPage struct { diff --git a/internal/web/static/main.css b/internal/web/static/main.css index 31da770..b1082a8 100644 --- a/internal/web/static/main.css +++ b/internal/web/static/main.css @@ -127,6 +127,7 @@ footer { .card-content { padding: 1rem 1.25rem 1.5rem; } .card h2 { margin: .25rem 0 .5rem; font-size: 1.25rem; line-height: 1.3; } .card time { color: var(--text-muted); font-size: .85rem; } +.card-count { color: var(--text-muted); font-size: .85rem; } /* ---------- Artikel ---------- */ .hero { diff --git a/internal/web/templates/list.html b/internal/web/templates/list.html index eb634b9..4e8a695 100644 --- a/internal/web/templates/list.html +++ b/internal/web/templates/list.html @@ -11,6 +11,7 @@

{{ .Title }}

+

{{ .Counter }}

From 2e31bfdc77a2fa79d5383d7f88cdaa8229d8b72b Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:07:25 +0200 Subject: [PATCH 06/12] =?UTF-8?q?Card-Fix=20f=C3=BCr=20Counter=20und=20Ber?= =?UTF-8?q?echnungs-Fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/blog/main.go | 17 +++++++++-------- internal/web/static/main.css | 1 + internal/web/templates/list.html | 6 ++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cmd/blog/main.go b/cmd/blog/main.go index 55062bc..af5f19a 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -101,14 +101,6 @@ func main() { fmt.Println(err) } - /* */ - - for a, b := range articles { - articles[a].Counter = getTick(b.Slug) - } - - /* */ - staticPages, err := article.LoadStatic(pagesDir) if err != nil { fmt.Println(err) @@ -122,6 +114,15 @@ func main() { http.NotFound(w, r) return } + + /* */ + + for a, b := range articles { + articles[a].Counter = getTick(b.Slug) + } + + /* */ + if err := tplList.ExecuteTemplate(w, "layout", article.ListPage{ Title: "Startseite", Description: "Alle Artikel im Überblick", diff --git a/internal/web/static/main.css b/internal/web/static/main.css index b1082a8..f720532 100644 --- a/internal/web/static/main.css +++ b/internal/web/static/main.css @@ -128,6 +128,7 @@ footer { .card h2 { margin: .25rem 0 .5rem; font-size: 1.25rem; line-height: 1.3; } .card time { color: var(--text-muted); font-size: .85rem; } .card-count { color: var(--text-muted); font-size: .85rem; } +.card-meta { display: flex; gap: 1rem; /* optionaler Abstand zwischen den Elementen */} /* ---------- Artikel ---------- */ .hero { diff --git a/internal/web/templates/list.html b/internal/web/templates/list.html index 4e8a695..ba41d9b 100644 --- a/internal/web/templates/list.html +++ b/internal/web/templates/list.html @@ -10,8 +10,10 @@ {{ end }}

{{ .Title }}

- -

{{ .Counter }}

+
+ +

{{ .Counter }}

+
From 96894516a7412b30804eb9244041779d3f18c6d1 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:11:50 +0200 Subject: [PATCH 07/12] Fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f44afc..c52be7e 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ ## B1ts Star Citizen Blog -- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file From 8cd66c9f59b9c4a0efc03ce2a1f300399e22d642 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:17:45 +0200 Subject: [PATCH 08/12] Anpassungen Counter-Design --- internal/web/static/main.css | 2 -- internal/web/templates/list.html | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/internal/web/static/main.css b/internal/web/static/main.css index f720532..31da770 100644 --- a/internal/web/static/main.css +++ b/internal/web/static/main.css @@ -127,8 +127,6 @@ footer { .card-content { padding: 1rem 1.25rem 1.5rem; } .card h2 { margin: .25rem 0 .5rem; font-size: 1.25rem; line-height: 1.3; } .card time { color: var(--text-muted); font-size: .85rem; } -.card-count { color: var(--text-muted); font-size: .85rem; } -.card-meta { display: flex; gap: 1rem; /* optionaler Abstand zwischen den Elementen */} /* ---------- Artikel ---------- */ .hero { diff --git a/internal/web/templates/list.html b/internal/web/templates/list.html index ba41d9b..1444f02 100644 --- a/internal/web/templates/list.html +++ b/internal/web/templates/list.html @@ -10,10 +10,7 @@ {{ end }}

{{ .Title }}

-
- -

{{ .Counter }}

-
+ ({{ .Counter }})
From 7e21b10a6c6adabb64e3d78a3fff2ee3ca6a5bd8 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:30:52 +0200 Subject: [PATCH 09/12] Persistenz implementiert + Anpassungen --- cmd/blog/main.go | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/cmd/blog/main.go b/cmd/blog/main.go index af5f19a..8c1d4fc 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "html/template" "net/http" @@ -14,6 +15,28 @@ import ( var TickCatalog []TickEntry +func SaveTickCatalog(filename string) error { + file, err := os.Create(filename) + if err != nil { + return err + } + defer file.Close() + + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + return encoder.Encode(TickCatalog) +} + +func LoadTickCatalog(filename string) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + return json.NewDecoder(file).Decode(&TickCatalog) +} + func IncTick(xSlug string) error { for a, b := range TickCatalog { if b.Slug == xSlug { @@ -33,12 +56,12 @@ func getTick(xSlug string) string { return strconv.FormatInt(n, 10) } } - return "-1" + return "0" } type TickEntry struct { - Slug string - Count int64 + Slug string `json:"slug"` + Count int64 `json:"count"` } func getenv(k, d string) string { @@ -75,6 +98,15 @@ func main() { staticDir := getenv("BLOG_STATIC_DIR", "/app/internal/web/static") pagesDir := getenv("BLOG_PAGES_DIR", "/pages") templatesDir := getenv("BLOG_TEMPLATES_DIR", "/templates") + ticksDir := getenv("BLOG_TICKS_DIR", "/ticks") + + TickCatalog = nil + if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil { + fmt.Println("Fehler beim Laden:", err) + return + } + + fmt.Println("Geladener Katalog:", TickCatalog) funcs := template.FuncMap{ "now": time.Now, // jetzt‑Zeit bereitstellen @@ -166,4 +198,11 @@ func main() { http.FileServer(http.Dir(staticDir))))) http.ListenAndServe(":8080", mux) + + if err := SaveTickCatalog(ticksDir + "/ticks.json"); err != nil { + fmt.Println("Fehler beim Speichern:", err) + return + } + + fmt.Println("Geladener Katalog:", TickCatalog) } From 621db424f057585baa581610ab4a124478fa96c9 Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:34:48 +0200 Subject: [PATCH 10/12] =?UTF-8?q?Fix=20f=C3=BCr=20Boot-Loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/blog/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/blog/main.go b/cmd/blog/main.go index 8c1d4fc..46cfebf 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -103,7 +103,6 @@ func main() { TickCatalog = nil if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil { fmt.Println("Fehler beim Laden:", err) - return } fmt.Println("Geladener Katalog:", TickCatalog) @@ -201,7 +200,6 @@ func main() { if err := SaveTickCatalog(ticksDir + "/ticks.json"); err != nil { fmt.Println("Fehler beim Speichern:", err) - return } fmt.Println("Geladener Katalog:", TickCatalog) From 98de9b1b9876c70663919f314e1b391fda28a08b Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 11:49:10 +0200 Subject: [PATCH 11/12] Potentieller Persistenz-Fix --- cmd/blog/main.go | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/cmd/blog/main.go b/cmd/blog/main.go index 46cfebf..756496c 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -6,8 +6,10 @@ import ( "html/template" "net/http" "os" + "os/signal" "strconv" "strings" + "syscall" "time" "git.send.nrw/sendnrw/b1tsblog/internal/article" @@ -93,6 +95,18 @@ var ( func main() { + // Signal-Kanal einrichten + stop := make(chan os.Signal, 1) + signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) + + // Goroutine, die auf Signale wartet + go func() { + <-stop + fmt.Println("Stop Sign...") + prepareExit() + os.Exit(0) + }() + // --- Verzeichnisse konfigurierbar machen ------------------------- contentDir := getenv("BLOG_CONTENT_DIR", "/content") staticDir := getenv("BLOG_STATIC_DIR", "/app/internal/web/static") @@ -196,11 +210,21 @@ func main() { cacheControl(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))) - http.ListenAndServe(":8080", mux) + StopServer(http.ListenAndServe(":8080", mux)) - if err := SaveTickCatalog(ticksDir + "/ticks.json"); err != nil { +} + +func prepareExit() { + fmt.Println("~", "Running exit tasks...") + if err := SaveTickCatalog(getenv("BLOG_TICKS_DIR", "/ticks") + "/ticks.json"); err != nil { fmt.Println("Fehler beim Speichern:", err) } - fmt.Println("Geladener Katalog:", TickCatalog) + fmt.Println("~", "Exit completed.") +} + +func StopServer(e error) { + fmt.Println("~", "Stopping server...") + prepareExit() + fmt.Println("~", "Server stopped!") } From 4c41bb8838423fc4ea871b83d7986f3b4044aa1a Mon Sep 17 00:00:00 2001 From: jbergner Date: Sun, 11 May 2025 12:02:29 +0200 Subject: [PATCH 12/12] =?UTF-8?q?Anpassung=20Datenschutzerkl=C3=A4rung=20+?= =?UTF-8?q?=20ReleaseCandidate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c52be7e..865f5c7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ## B1tsBlog +- Anpassung Datenschutzerklärung - Windows Server 2025 Domänen-Controller legt Netzwerkprofil auf Öffentlich fest - TLS-Zertifikat mit SHA3 auf Windows Server 2016 einspielen - Warum personenbezogene Daten nie in die Betreffzeile einer E-Mail gehören @@ -20,4 +21,5 @@ ## B1ts Star Citizen Blog -- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file +- Anpassung Datenschutzerklärung +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file