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..065aa59 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/ @@ -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/README.md b/README.md index 4440b00..865f5c7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # b1tsblog +## 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 @@ -15,3 +18,8 @@ - Ein eigenes Docker-Image erstellen - so geht's - Der eigene DNS-Server im Homelab - Content-Update 2025-05-04 + +## B1ts Star Citizen Blog + +- Anpassung Datenschutzerklärung +- Invictus 2955 - Das Jahr der Idris-P? \ No newline at end of file diff --git a/cmd/blog/main.go b/cmd/blog/main.go index fe652ed..756496c 100644 --- a/cmd/blog/main.go +++ b/cmd/blog/main.go @@ -1,17 +1,71 @@ package main import ( + "encoding/json" "fmt" "html/template" "net/http" "os" + "os/signal" "strconv" "strings" + "syscall" "time" "git.send.nrw/sendnrw/b1tsblog/internal/article" ) +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 { + 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 "0" +} + +type TickEntry struct { + Slug string `json:"slug"` + Count int64 `json:"count"` +} + func getenv(k, d string) string { if v := os.Getenv(k); v != "" { return v @@ -41,36 +95,38 @@ 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 := os.Getenv("BLOG_CONTENT_DIR") - if contentDir == "" { - contentDir = "/content" // Fallback für local run + 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") + ticksDir := getenv("BLOG_TICKS_DIR", "/ticks") + + TickCatalog = nil + if err := LoadTickCatalog(ticksDir + "/ticks.json"); err != nil { + fmt.Println("Fehler beim Laden:", err) } - 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" - } + fmt.Println("Geladener Katalog:", TickCatalog) 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()) @@ -103,6 +159,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", @@ -116,6 +181,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) } @@ -142,5 +210,21 @@ func main() { cacheControl(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))) - http.ListenAndServe(":8080", mux) + StopServer(http.ListenAndServe(":8080", mux)) + +} + +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!") } 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/templates/list.html b/internal/web/templates/list.html index eb634b9..1444f02 100644 --- a/internal/web/templates/list.html +++ b/internal/web/templates/list.html @@ -10,7 +10,7 @@ {{ end }}

{{ .Title }}

- + ({{ .Counter }})