From 2600b60b8b4a8ad1982bcf149bdebc728a1aeeef Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 9 Jan 2026 11:43:09 -0500 Subject: [PATCH] Now you can configure the email system from the config.json and using .json instead of toml. --- .gitignore | 2 +- common/auth.go | 2 +- common/email/api.go | 43 +++++++++++++++++++++-------------- common/email/data.go | 8 ------- config/server.go | 36 ------------------------------ config/settings.go | 48 ++++++++++++++++++++++++++++++++++++++++ config_example.json | 24 ++++++++++++++++++++ config_example.toml | 8 ------- go.mod | 1 - go.sum | 2 -- main.go | 10 ++++----- tools/cmd/mailer/main.go | 10 ++++----- tools/cmd/qmgr/main.go | 7 +++--- 13 files changed, 113 insertions(+), 88 deletions(-) delete mode 100644 config/server.go create mode 100644 config/settings.go create mode 100644 config_example.json delete mode 100644 config_example.toml diff --git a/.gitignore b/.gitignore index 51ec17d..852de2d 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,7 @@ coverage coverage/* .venv *.gz -config.toml +config.json public *.idx *.sqlite3 diff --git a/common/auth.go b/common/auth.go index 90f4a51..8816606 100644 --- a/common/auth.go +++ b/common/auth.go @@ -15,7 +15,7 @@ import ( ) func IsAdmin(user *data.User) bool { - return user.Username == config.Settings.Admin + return user.Username == config.Settings.Server.Admin } func AuthCheck(c *fiber.Ctx, needs_admin bool) (*session.Session, error) { diff --git a/common/email/api.go b/common/email/api.go index cfb4b82..bf20430 100644 --- a/common/email/api.go +++ b/common/email/api.go @@ -6,32 +6,33 @@ import ( "context" "log" "github.com/redis/go-redis/v9" + "MY/webapp/config" ) -func NewSender(ctx context.Context, config Config) (Sender){ +func NewSender(ctx context.Context) (Sender){ client := redis.NewClient(&redis.Options{ - Addr: config.RedisHostPort, - Password: config.RedisPassword, - DB: config.RedisDB, + Addr: config.Settings.Redis.HostPort, + Password: config.Settings.Redis.Password, + DB: config.Settings.Redis.DB, }) return Sender{client, ctx} } -func NewRouter(ctx context.Context, config Config) (Router, error) { +func NewRouter(ctx context.Context) (Router, error) { var router Router var err error router.ctx = ctx router.redis_client = redis.NewClient(&redis.Options{ - Addr: config.RedisHostPort, - Password: config.RedisPassword, - DB: config.RedisDB, + Addr: config.Settings.Redis.HostPort, + Password: config.Settings.Redis.Password, + DB: config.Settings.Redis.DB, }) - router.smtp_client, err = mail.NewClient(config.SMTPHost, - mail.WithPort(config.SMTPPort), + router.smtp_client, err = mail.NewClient(config.Settings.Email.Host, + mail.WithPort(config.Settings.Email.Port), mail.WithTLSPolicy(mail.NoTLS)) return router, err @@ -58,8 +59,13 @@ func (router *Router) DeliverEmail(msg EmailMessage) error { email_msg.SetBodyString(mail.TypeTextPlain, msg.Text) email_msg.SetBodyString(mail.TypeTextHTML, msg.HTML) - email_msg.SetGenHeader(mail.HeaderXMailer, "nunya-business") - email_msg.SetGenHeader(mail.HeaderUserAgent, "nunya-business") + if config.Settings.Email.XMailer != "" { + email_msg.SetGenHeader(mail.HeaderXMailer, config.Settings.Email.XMailer) + } + + if config.Settings.Email.UserAgent != "" { + email_msg.SetGenHeader(mail.HeaderUserAgent, config.Settings.Email.UserAgent) + } if err != nil { return err } @@ -72,7 +78,9 @@ func (router *Router) DeliverEmail(msg EmailMessage) error { func (router *Router) ReceiveEmail() (EmailMessage, error) { var msg EmailMessage - result, err := router.redis_client.BRPop(router.ctx, 0, "queue").Result() + result, err := router.redis_client.BRPop( + router.ctx, 0, + config.Settings.Email.RedisQueue).Result() if err != nil { return msg, err } // NOTE: 0=queue name, 1=message @@ -96,7 +104,10 @@ func (sender *Sender) QueueEmail(msg EmailMessage) error { msg_json, err := json.Marshal(msg) if err != nil { return err } - _, err = sender.redis_client.LPush(sender.ctx, "queue", string(msg_json)).Result() + _, err = sender.redis_client.LPush( + sender.ctx, + config.Settings.Email.RedisQueue, + string(msg_json)).Result() if err != nil { return err } return nil @@ -105,9 +116,7 @@ func (sender *Sender) QueueEmail(msg EmailMessage) error { func OneShotSend(msg EmailMessage) { ctx := context.Background() - sender := NewSender(ctx, Config{ - RedisHostPort: "127.0.0.1:6379", - }) + sender := NewSender(ctx) defer sender.Close() err := sender.QueueEmail(msg) diff --git a/common/email/data.go b/common/email/data.go index 750db8a..c8ef520 100644 --- a/common/email/data.go +++ b/common/email/data.go @@ -6,14 +6,6 @@ import ( "context" ) -type Config struct { - RedisHostPort string - RedisPassword string - RedisDB int - SMTPHost string - SMTPPort int -} - type EmailMessage struct { To string From string diff --git a/config/server.go b/config/server.go deleted file mode 100644 index d9df934..0000000 --- a/config/server.go +++ /dev/null @@ -1,36 +0,0 @@ -package config - - -import ( - "log" - - "github.com/BurntSushi/toml" -) - -type config struct { - Admin string `toml:"admin"` - Views string `toml:"views"` - Layouts string `toml:"layouts"` - Port string `toml:"port"` - - Database struct { - Driver string `toml:"driver"` - Url string `toml:"url"` - } `toml:"database"` -} - -var Settings config - -func Load(path string) { - metadata, err := toml.DecodeFile(path, &Settings) - - if err != nil { - log.Fatalf("error loading config.toml: %v", err) - } - - bad_keys := metadata.Undecoded() - - if len(bad_keys) > 0 { - log.Fatalf("unknown configuration keys: %v", bad_keys); - } -} diff --git a/config/settings.go b/config/settings.go new file mode 100644 index 0000000..5c2da54 --- /dev/null +++ b/config/settings.go @@ -0,0 +1,48 @@ +package config + +import ( + "log" + "encoding/json" + "os" +) + +type config struct { + Server struct { + Admin string + Views string + Layouts string + Port string + } + Database struct { + Driver string + Url string + } + Redis struct { + HostPort string + Password string + DB int + } + Email struct { + Host string + Port int + XMailer string + UserAgent string + RedisQueue string + } +} + +var Settings config + +func Load(path string) { + data, err := os.ReadFile(path) + + if err != nil { + log.Fatalf("error loading %s: %v", path, err) + } + + err = json.Unmarshal(data, &Settings) + + if err != nil { + log.Fatal("error parsing %s: %v", path, err) + } +} diff --git a/config_example.json b/config_example.json new file mode 100644 index 0000000..8cb528e --- /dev/null +++ b/config_example.json @@ -0,0 +1,24 @@ +{ + "Server": { + "Admin": "admin", + "Views": "./views", + "Layouts": "layouts/main", + "Port": ":7001" + }, + "Database": { + "Driver": "sqlite3", + "Url": "db.sqlite3" + }, + "Redis": { + "HostPort": "localhost:6379", + "Password": "", + "DB": 0 + }, + "Email": { + "Host": "localhost", + "Port": 1025, + "XMailer": "nunya-business", + "UserAgent": "nunya-business", + "RedisQueue": "email" + } +} diff --git a/config_example.toml b/config_example.toml deleted file mode 100644 index e0e3d57..0000000 --- a/config_example.toml +++ /dev/null @@ -1,8 +0,0 @@ -admin = "admin" -views = "./views" -layouts = "layouts/main" -port = ":7001" - -[database] -driver = "sqlite3" -url = "db.sqlite3" diff --git a/go.mod b/go.mod index 71953ea..1b7c6a5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module MY/webapp go 1.25.3 require ( - github.com/BurntSushi/toml v1.5.0 github.com/Masterminds/squirrel v1.5.4 github.com/chromedp/chromedp v0.14.2 github.com/go-playground/validator/v10 v10.28.0 diff --git a/go.sum b/go.sum index 559f455..ae35c64 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= diff --git a/main.go b/main.go index b26fc56..178e43e 100644 --- a/main.go +++ b/main.go @@ -23,17 +23,17 @@ import ( ) func main() { - config.Load("config.toml") - log.Printf("ADMIN is %s", config.Settings.Admin) + config.Load("config.json") + log.Printf("ADMIN is %s", config.Settings.Server.Admin) log.SetFlags(log.LstdFlags | log.Lshortfile) - engine := html.New(config.Settings.Views, ".html") + engine := html.New(config.Settings.Server.Views, ".html") engine.Reload(true) app := fiber.New(fiber.Config{ Views: engine, - ViewsLayout: config.Settings.Layouts, + ViewsLayout: config.Settings.Server.Layouts, CaseSensitive: true, StrictRouting: true, }) @@ -55,7 +55,7 @@ func main() { // this sets up graceful shutdown go func() { - if err := app.Listen(config.Settings.Port); err != nil { + if err := app.Listen(config.Settings.Server.Port); err != nil { log.Panic(err) } }() diff --git a/tools/cmd/mailer/main.go b/tools/cmd/mailer/main.go index 73afeb8..e3d1e8c 100644 --- a/tools/cmd/mailer/main.go +++ b/tools/cmd/mailer/main.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "syscall" + "MY/webapp/config" email "MY/webapp/common/email" ) @@ -21,14 +22,11 @@ func EmailReceiver(router *email.Router) { } func main() { - ctx := context.Background() + config.Load("config.json") - router, err := email.NewRouter(ctx, email.Config{ - RedisHostPort: "127.0.0.1:6379", - SMTPHost: "localhost", - SMTPPort: 1025, - }) + ctx := context.Background() + router, err := email.NewRouter(ctx) if err != nil { panic(err) } defer router.Close() diff --git a/tools/cmd/qmgr/main.go b/tools/cmd/qmgr/main.go index ac43c22..264ab63 100644 --- a/tools/cmd/qmgr/main.go +++ b/tools/cmd/qmgr/main.go @@ -1,12 +1,15 @@ package main import ( + "MY/webapp/config" email "MY/webapp/common/email" "fmt" "context" ) func main() { + config.Load("config.json") + ctx := context.Background() msg := email.EmailMessage{ @@ -17,9 +20,7 @@ func main() { HTML: fmt.Sprintf("

Random number %v

", 200), } - sender := email.NewSender(ctx, email.Config{ - RedisHostPort: "127.0.0.1:6379", - }) + sender := email.NewSender(ctx) defer sender.Close() err := sender.QueueEmail(msg)