feat: configuration
/ publish (push) Successful in 3m12s

This commit is contained in:
2026-03-07 16:43:25 +01:00
parent 4efd3ee396
commit 0f2fe19c01
19 changed files with 169 additions and 26 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/translate"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/filesystem"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/filesystem"
"github.com/studio-b12/gowebdav"
)
+1 -1
View File
@@ -1,7 +1,7 @@
package page
import (
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/filesystem"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/filesystem"
)
type Service struct {
+65
View File
@@ -0,0 +1,65 @@
package config
import (
"context"
"log/slog"
"os"
"github.com/sethvargo/go-envconfig"
)
type Cfg struct {
FileSystem *WebdavConfig `env:", prefix=FILESYSTEM_"`
Cache *ValkeyConfig `env:", prefix=CACHE_"`
}
type WebdavConfig struct {
URL string `env:"URL"`
User string `env:"USERNAME"`
Password string `env:"PASSWORD"`
}
type ValkeyConfig struct {
ClientName string `env:"CLIENTNAME"`
Username string `env:"USERNAME"`
Password string `env:"PASSWORD"`
// InitAddress point to valkey nodes.
// Valkey will connect to them one by one and issue a CLUSTER SLOT command to initialize the cluster client until success.
// If len(InitAddress) == 1 and the address is not running in cluster mode, valkey will fall back to the single client mode.
// If ClientOption.Sentinel.MasterSet is set, then InitAddress will be used to connect sentinels
// You can bypass this behavior by using ClientOption.ForceSingleClient.
InitAddress []string `env:"ADDRESS"`
}
func Read(ctx context.Context) (cfg Cfg, err error) {
// ex, err := os.Executable()
// if err != nil {
// panic(err)
// }
// slog.Debug("loading .env", "pwd", filepath.Dir(ex))
// err = godotenv.Load(".")
// if err != nil {
// return
// }
//
slog.Info("adsf", "test", os.Getenv("TEST"))
err = envconfig.ProcessWith(ctx, &envconfig.Config{
Target: &cfg,
// All fields will use a ";" delimiter and "@" separator, unless locally
// overridden.
DefaultDelimiter: ";",
DefaultSeparator: "@",
Lookuper: envconfig.MultiLookuper(secretLookuper(), envconfig.OsLookuper()),
})
if err != nil {
return
}
slog.Info("ca", "cacjhe", cfg.Cache)
return
}
+34
View File
@@ -0,0 +1,34 @@
package config
import (
"io"
"os"
"strings"
"github.com/sethvargo/go-envconfig"
)
func secretLookuper() envconfig.LookuperFunc {
return func(key string) (string, bool) {
fileName := os.Getenv(key + "_FILE")
if fileName == "" {
return "", false
}
file, err := os.Open(fileName)
if err != nil {
return "", false
}
defer file.Close()
sb := &strings.Builder{}
_, err = io.Copy(sb, file)
if err != nil {
return "", false
}
return sb.String(), true
}
}
+9 -14
View File
@@ -3,16 +3,15 @@ package server
import (
"log/slog"
"net/http"
"os"
"time"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/page"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/translate"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/filesystem"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/resthome"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/restimage"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/templer"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/filesystem"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/templer"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/web"
"github.com/studio-b12/gowebdav"
"github.com/valkey-io/valkey-go"
@@ -22,7 +21,7 @@ func (s *Server) RegisterRoutes() (h http.Handler) {
mux := http.NewServeMux()
registerStatic(mux)
mux.Handle("/", registerOther())
mux.Handle("/", s.registerOther())
h = mux
h = templer.Middleware(h)
@@ -30,23 +29,19 @@ func (s *Server) RegisterRoutes() (h http.Handler) {
return h
}
func registerOther() (h http.Handler) {
func (s *Server) registerOther() (h http.Handler) {
mux := http.NewServeMux()
webdavClient := gowebdav.NewClient("https://cloud.schreifuchs.ch/remote.php/dav/files/test/website", "test", os.Getenv("TEST_PW"))
webdavClient := gowebdav.NewClient(s.cfg.FileSystem.URL, s.cfg.FileSystem.User, s.cfg.FileSystem.Password)
if err := webdavClient.Connect(); err != nil {
slog.Error("could not connect webdavClient", "err", err, "pw", os.Getenv("TEST_PW"))
slog.Error("could not connect webdavClient", "err", err)
}
var fs filesystem.FS = webdavClient
valkeyAddr := os.Getenv("VALKEY_ADDR")
if valkeyAddr == "" {
valkeyAddr = "127.0.0.1:6379"
}
valkeyClient, err := valkey.NewClient(valkey.ClientOption{
InitAddress: []string{valkeyAddr},
Password: os.Getenv("VALKEY_PASSWORD"),
InitAddress: s.cfg.Cache.InitAddress,
Password: s.cfg.Cache.Password,
})
if err != nil {
slog.Error("failed to create valkey client", "err", err)
@@ -63,7 +58,7 @@ func registerOther() (h http.Handler) {
h = mux
h = translator.Middleware(h)
h = cacheMiddleware(time.Second * 45)(h)
h = cacheMiddleware(time.Minute * 5)(h)
return h
}
+29 -3
View File
@@ -1,34 +1,60 @@
package server
import (
"context"
"fmt"
"log/slog"
"net/http"
"os"
"strconv"
"time"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/config"
)
type Server struct {
port int
cfg config.Cfg
}
func NewServer() *http.Server {
func Start(ctx context.Context, cfg config.Cfg) (err error) {
port, _ := strconv.Atoi(os.Getenv("PORT"))
if port == 0 {
port = 8080
}
s := &Server{
port: port,
cfg: cfg,
}
// Declare Server config
server := &http.Server{
srv := &http.Server{
Addr: fmt.Sprintf(":%d", s.port),
Handler: s.RegisterRoutes(),
IdleTimeout: time.Minute,
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
}
idleConnsClosed := make(chan struct{})
return server
go func() {
<-ctx.Done()
slog.Info("shutting down server")
// Shutdown server when ctx done
if err = srv.Shutdown(context.Background()); err != nil {
// Error from closing listeners, or context timeout:
err = fmt.Errorf("error whilse shutting down server: %w", err)
}
close(idleConnsClosed)
}()
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
return fmt.Errorf("error while server ListenAndServe: %w", err)
}
<-idleConnsClosed
return err
}