From f6558e3cd7624d3fe25dbad9b03812ebabc6f8b3 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 10:41:36 +0200 Subject: [PATCH 01/13] layed out the basics on how --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b267a9..1fcb891 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ I am using the api of [diyhrt.market](https://diyhrt.market/api/) to get the current stats data of estrogen stocks. -# Installation +## Installation To install the new tab page you can use `go install` @@ -18,6 +18,18 @@ transfem-startpage To configure this new tab page as website, you can install the firefox extension [New Tab Override](https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/). Then just configure the url as `http://127.0.0.1:{port}/`. The default port should be `5500` but it will also print it out when starting the server. Make sure to check the box `Set focus to the web page instead of the address bar` in the extension settings, because the new tab page auto focuses the search bar. +## CLI + +```sh +transfem-startpage {program} {...args} +``` + +program | args | description +---|---|--- +`help` | `program:optional` | get more information on how the cli or one program works +`start` | `profile:optional` | start the webserver for a certain profile +`cache` | `action:emum(clear;clean)` | so something with the cache + ## Config and Profiles This tool works with profiles. The default profile is `default`. If you want to load another profile just write it as command line arg after the command. To write a config File you can create the files here: From 26f1008dc448ba041f3b2e4a397ac96990905be1 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 11:09:18 +0200 Subject: [PATCH 02/13] implemented basic program structure --- internal/cli/cache.go | 8 ++++++ internal/cli/cli.go | 59 +++++++++++++++++++++++++++++++++++++++++++ internal/cli/help.go | 8 ++++++ internal/cli/start.go | 8 ++++++ main.go | 7 ++++- 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 internal/cli/cache.go create mode 100644 internal/cli/cli.go create mode 100644 internal/cli/help.go create mode 100644 internal/cli/start.go diff --git a/internal/cli/cache.go b/internal/cli/cache.go new file mode 100644 index 0000000..33bd1d8 --- /dev/null +++ b/internal/cli/cache.go @@ -0,0 +1,8 @@ +package cli + +import "log" + +func Cache() error { + log.Println("running cache") + return nil +} diff --git a/internal/cli/cli.go b/internal/cli/cli.go new file mode 100644 index 0000000..965bb39 --- /dev/null +++ b/internal/cli/cli.go @@ -0,0 +1,59 @@ +package cli + +import ( + "fmt" + "log" + "os" +) + +type ProgramFunction func() error +type Program struct { + Name string + Function ProgramFunction + Description string +} + +var HelpHeader = `Meow +Ze +Dong` +var Programs = []Program{ + { + Name: "help", + Function: Help, + Description: "get more information on how the cli or a program works", + }, + { + Name: "start", + Function: Start, + Description: "start the webserver", + }, + { + Name: "cache", + Function: Cache, + Description: "do something with the cache", + }, +} + +func Cli() { + fmt.Println("running transfem startpage") + + programName := "help" + if len(os.Args) > 1 { + programName = os.Args[1] + } + + log.Println("running program", programName) + + var selectedProgram *Program = nil + for i, p := range Programs { + if p.Name == programName { + selectedProgram = &Programs[i] + break + } + } + if selectedProgram == nil { + log.Panicln("couldn't find program", programName, ". EXITING") + } + + selectedProgram.Function() +} diff --git a/internal/cli/help.go b/internal/cli/help.go new file mode 100644 index 0000000..2504940 --- /dev/null +++ b/internal/cli/help.go @@ -0,0 +1,8 @@ +package cli + +import "log" + +func Help() error { + log.Println("running help") + return nil +} diff --git a/internal/cli/start.go b/internal/cli/start.go new file mode 100644 index 0000000..08866cf --- /dev/null +++ b/internal/cli/start.go @@ -0,0 +1,8 @@ +package cli + +import "log" + +func Start() error { + log.Println("starting server") + return nil +} diff --git a/main.go b/main.go index 96f3d47..c4bc20c 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "os" "strconv" + "gitea.elara.ws/Hazel/transfem-startpage/internal/cli" "gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt" "gitea.elara.ws/Hazel/transfem-startpage/internal/rendering" "github.com/labstack/echo/v4" @@ -60,7 +61,7 @@ func getFileSystem() http.FileSystem { return http.FS(fsys) } -func main() { +func backMain() { profile := "default" if len(os.Args) > 1 { profile = os.Args[1] @@ -100,3 +101,7 @@ func main() { e.Logger.Fatal(e.Start(":" + strconv.Itoa(CurrentConfig.Server.Port))) } + +func main() { + cli.Cli() +} From 81b960c23157882066f93ea3fc96b50e79ba28aa Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 11:20:58 +0200 Subject: [PATCH 03/13] implemented general help --- internal/cli/cli.go | 32 +++++++++++++++++--------------- internal/cli/help.go | 17 +++++++++++++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 965bb39..39611cb 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -8,35 +8,37 @@ import ( type ProgramFunction func() error type Program struct { - Name string - Function ProgramFunction - Description string + Name string + Function ProgramFunction + ShortDescription string } -var HelpHeader = `Meow -Ze -Dong` +var HelpHeader = `This is the help page of transfem-startpage. +transfem-startpage {program} {...args} +The following Programs are available:` var Programs = []Program{ { - Name: "help", - Function: Help, - Description: "get more information on how the cli or a program works", + Name: "help", + ShortDescription: "get more information on how the cli in general or a specific program works", }, { - Name: "start", - Function: Start, - Description: "start the webserver", + Name: "start", + Function: Start, + ShortDescription: "start the webserver", }, { - Name: "cache", - Function: Cache, - Description: "do something with the cache", + Name: "cache", + Function: Cache, + ShortDescription: "do something with the cache", }, } func Cli() { fmt.Println("running transfem startpage") + // getting around initialization cycle + Programs[0].Function = Help + programName := "help" if len(os.Args) > 1 { programName = os.Args[1] diff --git a/internal/cli/help.go b/internal/cli/help.go index 2504940..546c42d 100644 --- a/internal/cli/help.go +++ b/internal/cli/help.go @@ -1,8 +1,21 @@ package cli -import "log" +import ( + "fmt" + "log" +) + +func generalHelp() error { + fmt.Println() + fmt.Println(HelpHeader) + for _, p := range Programs { + fmt.Println(" - " + p.Name + ":\t" + p.ShortDescription) + } + return nil +} func Help() error { log.Println("running help") - return nil + + return generalHelp() } From 7f43eb43e050ddc4fb914d384dc7f26e892a4cb3 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 11:27:32 +0200 Subject: [PATCH 04/13] added arguments data structure --- internal/cli/cli.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 39611cb..ceea8b2 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -11,6 +11,13 @@ type Program struct { Name string Function ProgramFunction ShortDescription string + Arguments []Argument +} +type Argument struct { + Name string + Type string + Required bool + Description string } var HelpHeader = `This is the help page of transfem-startpage. @@ -20,16 +27,40 @@ var Programs = []Program{ { Name: "help", ShortDescription: "get more information on how the cli in general or a specific program works", + Arguments: []Argument{ + { + Name: "program", + Type: "string", + Required: false, + Description: "defines the program you want to know more about", + }, + }, }, { Name: "start", Function: Start, ShortDescription: "start the webserver", + Arguments: []Argument{ + { + Name: "profile", + Type: "string", + Required: false, + Description: "tells the program which config to load, default is 'default'", + }, + }, }, { Name: "cache", Function: Cache, ShortDescription: "do something with the cache", + Arguments: []Argument{ + { + Name: "action", + Type: "enum(clear;clean)", + Required: true, + Description: "defines what to do with the cache", + }, + }, }, } From 51b788bb5069f07d0dc163dbdf0f56f302b7018d Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 11:45:28 +0200 Subject: [PATCH 05/13] finished general help --- go.mod | 1 + go.sum | 2 ++ internal/cli/cli.go | 4 +++- internal/cli/help.go | 31 ++++++++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 4b7cafc..fc0c587 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.24.2 require github.com/labstack/echo/v4 v4.13.4 require ( + github.com/TwiN/go-color v1.4.1 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/go.sum b/go.sum index ada8512..4748c27 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ 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/TwiN/go-color v1.4.1 h1:mqG0P/KBgHKVqmtL5ye7K0/Gr4l6hTksPgTgMk3mUzc= +github.com/TwiN/go-color v1.4.1/go.mod h1:WcPf/jtiW95WBIsEeY1Lc/b8aaWoiqQpu5cf8WFxu+s= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= diff --git a/internal/cli/cli.go b/internal/cli/cli.go index ceea8b2..cebec4e 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -4,6 +4,8 @@ import ( "fmt" "log" "os" + + "github.com/TwiN/go-color" ) type ProgramFunction func() error @@ -21,7 +23,7 @@ type Argument struct { } var HelpHeader = `This is the help page of transfem-startpage. -transfem-startpage {program} {...args} +` + color.Bold + `transfem-startpage {program} {...args}` + color.Reset + ` The following Programs are available:` var Programs = []Program{ { diff --git a/internal/cli/help.go b/internal/cli/help.go index 546c42d..39980a3 100644 --- a/internal/cli/help.go +++ b/internal/cli/help.go @@ -3,13 +3,42 @@ package cli import ( "fmt" "log" + + "github.com/TwiN/go-color" ) +func padString(s string, n int) string { + missing := n - len(s) + if missing <= 0 { + return s + } + + for _ = range missing { + s = s + " " + } + + return s +} + func generalHelp() error { fmt.Println() fmt.Println(HelpHeader) + fmt.Println() + for _, p := range Programs { - fmt.Println(" - " + p.Name + ":\t" + p.ShortDescription) + fmt.Print(color.Bold + padString(p.Name, 7) + color.Reset) + + argumentString := color.Purple + for _, a := range p.Arguments { + requiredString := "" + if a.Required { + requiredString = "*" + } + argumentString = argumentString + " [" + requiredString + a.Name + ":" + a.Type + "]" + } + argumentString = argumentString + color.Reset + + fmt.Print(padString(argumentString, 40) + p.ShortDescription + "\n") } return nil } From 5bce49eed46c440df64201307dcf418b8825f04e Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 12:08:53 +0200 Subject: [PATCH 06/13] implemented specific help --- internal/cli/cli.go | 41 ++++++++++++++++----------- internal/cli/help.go | 67 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 77 insertions(+), 31 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index cebec4e..ae1ba80 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -1,7 +1,6 @@ package cli import ( - "fmt" "log" "os" @@ -13,6 +12,7 @@ type Program struct { Name string Function ProgramFunction ShortDescription string + LongDescription string Arguments []Argument } type Argument struct { @@ -23,12 +23,13 @@ type Argument struct { } var HelpHeader = `This is the help page of transfem-startpage. -` + color.Bold + `transfem-startpage {program} {...args}` + color.Reset + ` +` + color.Purple + `transfem-startpage {program} {...args}` + color.Reset + ` The following Programs are available:` var Programs = []Program{ { Name: "help", ShortDescription: "get more information on how the cli in general or a specific program works", + LongDescription: "What did you expect to find here?", Arguments: []Argument{ { Name: "program", @@ -42,6 +43,9 @@ var Programs = []Program{ Name: "start", Function: Start, ShortDescription: "start the webserver", + LongDescription: `The start program starts the webserver. +It loads the config file of the according profile. +It uses the default values if no config file was found.`, Arguments: []Argument{ { Name: "profile", @@ -55,6 +59,9 @@ var Programs = []Program{ Name: "cache", Function: Cache, ShortDescription: "do something with the cache", + LongDescription: `Does something with the cache. +- clear: delete the whole cache +- clean: delete all files that aren't used by any program.`, Arguments: []Argument{ { Name: "action", @@ -66,9 +73,18 @@ var Programs = []Program{ }, } -func Cli() { - fmt.Println("running transfem startpage") +func GetProgram(programName string) Program { + for i, p := range Programs { + if p.Name == programName { + return Programs[i] + } + } + log.Panicln("couldn't find program", programName, ". EXITING") + return Program{} +} + +func Cli() { // getting around initialization cycle Programs[0].Function = Help @@ -77,18 +93,9 @@ func Cli() { programName = os.Args[1] } - log.Println("running program", programName) - - var selectedProgram *Program = nil - for i, p := range Programs { - if p.Name == programName { - selectedProgram = &Programs[i] - break - } + var selectedProgram Program = GetProgram(programName) + err := selectedProgram.Function() + if err != nil { + log.Panicln(err) } - if selectedProgram == nil { - log.Panicln("couldn't find program", programName, ". EXITING") - } - - selectedProgram.Function() } diff --git a/internal/cli/help.go b/internal/cli/help.go index 39980a3..61b6ac6 100644 --- a/internal/cli/help.go +++ b/internal/cli/help.go @@ -2,7 +2,8 @@ package cli import ( "fmt" - "log" + "os" + "strings" "github.com/TwiN/go-color" ) @@ -20,6 +21,22 @@ func padString(s string, n int) string { return s } +func getSingleArgumentString(a Argument) string { + requiredString := "" + if a.Required { + requiredString = "*" + } + return requiredString + a.Name + ":" + a.Type +} + +func getArgumentString(arguments []Argument) string { + argumentString := color.Blue + for _, a := range arguments { + argumentString = argumentString + " [" + getSingleArgumentString(a) + "]" + } + return argumentString + color.Reset +} + func generalHelp() error { fmt.Println() fmt.Println(HelpHeader) @@ -27,24 +44,46 @@ func generalHelp() error { for _, p := range Programs { fmt.Print(color.Bold + padString(p.Name, 7) + color.Reset) - - argumentString := color.Purple - for _, a := range p.Arguments { - requiredString := "" - if a.Required { - requiredString = "*" - } - argumentString = argumentString + " [" + requiredString + a.Name + ":" + a.Type + "]" - } - argumentString = argumentString + color.Reset - - fmt.Print(padString(argumentString, 40) + p.ShortDescription + "\n") + fmt.Print(padString(getArgumentString(p.Arguments), 40) + p.ShortDescription + "\n") } return nil } +func specificHelp(programName string) error { + program := GetProgram(programName) + + fmt.Println(color.Bold + "MAN PAGE FOR " + strings.ToUpper(programName) + color.Reset) + fmt.Println() + + fmt.Println(color.Purple + "transfem-startpage " + programName + color.Reset + getArgumentString(program.Arguments)) + fmt.Println() + + fmt.Println(color.Bold + "arguments" + color.Reset) + + argumentStrings := make([]string, len(program.Arguments)) + maxArgumentString := 0 + for i, a := range program.Arguments { + s := getSingleArgumentString(a) + argumentStrings[i] = s + if len(s) > maxArgumentString { + maxArgumentString = len(s) + } + } + + for i, a := range program.Arguments { + fmt.Println(padString(argumentStrings[i], maxArgumentString+4) + a.Description) + } + + fmt.Println() + fmt.Println(program.LongDescription) + + return nil +} + func Help() error { - log.Println("running help") + if len(os.Args) > 2 { + return specificHelp(os.Args[2]) + } return generalHelp() } From f574a00a8f2e5d42affc6f380d8587bdf6eef867 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 12:09:33 +0200 Subject: [PATCH 07/13] not implemented cache --- internal/cli/cache.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/cli/cache.go b/internal/cli/cache.go index 33bd1d8..4951e09 100644 --- a/internal/cli/cache.go +++ b/internal/cli/cache.go @@ -4,5 +4,6 @@ import "log" func Cache() error { log.Println("running cache") + log.Panicln("not implemented yet") return nil } From 94b3f4c0f264341e86d29b1aa0a94f8a12533ede Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 12:31:47 +0200 Subject: [PATCH 08/13] implemented start server --- internal/cli/start.go | 16 ++++-- internal/rendering/config.go | 13 ----- main.go | 97 ++---------------------------------- 3 files changed, 16 insertions(+), 110 deletions(-) diff --git a/internal/cli/start.go b/internal/cli/start.go index 08866cf..8b813a1 100644 --- a/internal/cli/start.go +++ b/internal/cli/start.go @@ -1,8 +1,18 @@ package cli -import "log" +import ( + "log" + "os" + + "gitea.elara.ws/Hazel/transfem-startpage/internal/server" +) func Start() error { - log.Println("starting server") - return nil + profile := "default" + if len(os.Args) > 2 { + profile = os.Args[2] + } + log.Println("starting server with profile " + profile) + + return server.Start(profile) } diff --git a/internal/rendering/config.go b/internal/rendering/config.go index ec56829..d1c4471 100644 --- a/internal/rendering/config.go +++ b/internal/rendering/config.go @@ -3,10 +3,8 @@ package rendering import ( "errors" "fmt" - "maps" "os" "path/filepath" - "slices" "gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt" "github.com/pelletier/go-toml" @@ -102,17 +100,6 @@ func NewConfig() Config { } } -func (c *Config) LoadDiyHrt(listings []diyhrt.Listing) { - existingStores := make(map[int]diyhrt.Store) - - for _, listing := range listings { - existingStores[listing.Store.Id] = listing.Store - } - - c.Template.Listings = c.DiyHrt.ListingFilter.Filter(listings) - c.Template.Stores = c.DiyHrt.StoreFilter.Filter(slices.Collect(maps.Values(existingStores))) -} - func (rc *Config) ScanForConfigFile(profile string) error { profileFile := profile + ".toml" diff --git a/main.go b/main.go index c4bc20c..0bb0db3 100644 --- a/main.go +++ b/main.go @@ -1,107 +1,16 @@ package main import ( - "bytes" "embed" - "fmt" - "html/template" - "io/fs" - "log" - "net/http" - "os" - "strconv" "gitea.elara.ws/Hazel/transfem-startpage/internal/cli" - "gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt" - "gitea.elara.ws/Hazel/transfem-startpage/internal/rendering" - "github.com/labstack/echo/v4" + "gitea.elara.ws/Hazel/transfem-startpage/internal/server" ) -var CurrentConfig = rendering.NewConfig() - -func FetchDiyHrt() error { - fmt.Println("Fetch DiyHrt Marketplaces...") - - l, err := diyhrt.GetListings(CurrentConfig.DiyHrt.ApiKey) - if err != nil { - return err - } - CurrentConfig.LoadDiyHrt(l) - return nil -} - //go:embed frontend/* -var frontendFiles embed.FS - -func getFileContent() string { - content, err := frontendFiles.ReadFile("frontend/index.html") - - if err != nil { - log.Fatal(err) - } - - return string(content) -} - -var IndexTemplate = template.Must(template.New("index").Parse(getFileContent())) - -func getIndex(c echo.Context) error { - var tpl bytes.Buffer - IndexTemplate.Execute(&tpl, CurrentConfig.Template) - - return c.HTML(http.StatusOK, tpl.String()) -} - -func getFileSystem() http.FileSystem { - fsys, err := fs.Sub(frontendFiles, "frontend") - if err != nil { - panic(err) - } - - return http.FS(fsys) -} - -func backMain() { - profile := "default" - if len(os.Args) > 1 { - profile = os.Args[1] - } - fmt.Println("loading profile " + profile) - - err := CurrentConfig.ScanForConfigFile(profile) - if err != nil { - fmt.Println(err) - } - - err = CurrentConfig.Init() - if err != nil { - fmt.Println(err) - } - - err = FetchDiyHrt() - if err != nil { - fmt.Println(err) - } - - e := echo.New() - - // statically serve the file - cacheDir, err := rendering.GetCacheDir() - if err == nil { - e.Static("/cache", cacheDir) - } else { - fmt.Println(err) - } - - // https://echo.labstack.com/docs/cookbook/embed-resources - staticHandler := http.FileServer(getFileSystem()) - e.GET("/assets/*", echo.WrapHandler(http.StripPrefix("/", staticHandler))) - e.GET("/scripts/*", echo.WrapHandler(http.StripPrefix("/", staticHandler))) - e.GET("/", getIndex) - - e.Logger.Fatal(e.Start(":" + strconv.Itoa(CurrentConfig.Server.Port))) -} +var FrontendFiles embed.FS func main() { + server.FrontendFiles = FrontendFiles cli.Cli() } From 4e87c77ccbcc3d57218b1d88add31a388686a4d7 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 12:31:51 +0200 Subject: [PATCH 09/13] implemented start server --- internal/rendering/diyhrt.go | 28 +++++++++++++++++++++ internal/server/embed.go | 42 +++++++++++++++++++++++++++++++ internal/server/server.go | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 internal/rendering/diyhrt.go create mode 100644 internal/server/embed.go create mode 100644 internal/server/server.go diff --git a/internal/rendering/diyhrt.go b/internal/rendering/diyhrt.go new file mode 100644 index 0000000..9c94aac --- /dev/null +++ b/internal/rendering/diyhrt.go @@ -0,0 +1,28 @@ +package rendering + +import ( + "maps" + "slices" + + "gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt" +) + +func (c *Config) LoadDiyHrt(listings []diyhrt.Listing) { + existingStores := make(map[int]diyhrt.Store) + + for _, listing := range listings { + existingStores[listing.Store.Id] = listing.Store + } + + c.Template.Listings = c.DiyHrt.ListingFilter.Filter(listings) + c.Template.Stores = c.DiyHrt.StoreFilter.Filter(slices.Collect(maps.Values(existingStores))) +} + +func (c *Config) FetchDiyHrt() error { + l, err := diyhrt.GetListings(c.DiyHrt.ApiKey) + if err != nil { + return err + } + c.LoadDiyHrt(l) + return nil +} diff --git a/internal/server/embed.go b/internal/server/embed.go new file mode 100644 index 0000000..a1dfc13 --- /dev/null +++ b/internal/server/embed.go @@ -0,0 +1,42 @@ +package server + +import ( + "bytes" + "embed" + "io/fs" + "log" + "net/http" + "text/template" + + "github.com/labstack/echo/v4" +) + +var FrontendFiles embed.FS + +func getFileContent() string { + content, err := FrontendFiles.ReadFile("frontend/index.html") + + if err != nil { + log.Fatal(err) + } + + return string(content) +} + +func getIndex(c echo.Context) error { + IndexTemplate := template.Must(template.New("index").Parse(getFileContent())) + + var tpl bytes.Buffer + IndexTemplate.Execute(&tpl, Config.Template) + + return c.HTML(http.StatusOK, tpl.String()) +} + +func getFileSystem() http.FileSystem { + fsys, err := fs.Sub(FrontendFiles, "frontend") + if err != nil { + panic(err) + } + + return http.FS(fsys) +} diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..f5b333e --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,48 @@ +package server + +import ( + "log" + "net/http" + "strconv" + + "gitea.elara.ws/Hazel/transfem-startpage/internal/rendering" + "github.com/labstack/echo/v4" +) + +var Config = rendering.NewConfig() + +func Start(profile string) error { + err := Config.ScanForConfigFile(profile) + if err != nil { + return err + } + + err = Config.Init() + if err != nil { + return err + } + + err = Config.FetchDiyHrt() + if err != nil { + log.Println(err) + } + + e := echo.New() + + // statically serve the file + cacheDir, err := rendering.GetCacheDir() + if err == nil { + e.Static("/cache", cacheDir) + } else { + log.Println("didn't enable cache dir", err) + } + + // https://echo.labstack.com/docs/cookbook/embed-resources + staticHandler := http.FileServer(getFileSystem()) + e.GET("/assets/*", echo.WrapHandler(http.StripPrefix("/", staticHandler))) + e.GET("/scripts/*", echo.WrapHandler(http.StripPrefix("/", staticHandler))) + e.GET("/", getIndex) + + e.Logger.Fatal(e.Start(":" + strconv.Itoa(Config.Server.Port))) + return nil +} From 16a65df664cbcc7bef1fe1204e34256f06929890 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 12:37:58 +0200 Subject: [PATCH 10/13] rewrote ftm to log --- internal/rendering/config.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/internal/rendering/config.go b/internal/rendering/config.go index d1c4471..bd9f6f2 100644 --- a/internal/rendering/config.go +++ b/internal/rendering/config.go @@ -2,7 +2,7 @@ package rendering import ( "errors" - "fmt" + "log" "os" "path/filepath" @@ -128,7 +128,7 @@ func (rc *Config) LoadConfigFile(file string) error { return err } - fmt.Println("loading config file: " + file) + log.Println("loading config file", file) content, err := os.ReadFile(file) @@ -140,12 +140,10 @@ func (rc *Config) LoadConfigFile(file string) error { } func (c *Config) Init() error { - fmt.Print("downloading website icons") + log.Println("downloading website icons...") for i := range c.Template.Websites { - fmt.Print(".") c.Template.Websites[i].Cache() } - fmt.Print("\n") return nil } From 797e115191e7df4d16d9bec2def0c3cc7a4d9155 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 14:24:42 +0200 Subject: [PATCH 11/13] rewrote cache to work better --- internal/cache/cache.go | 97 ++++++++++++++++++++++++++++++++++++ internal/rendering/config.go | 9 ---- internal/server/server.go | 24 +++++---- 3 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 internal/cache/cache.go diff --git a/internal/cache/cache.go b/internal/cache/cache.go new file mode 100644 index 0000000..950ed43 --- /dev/null +++ b/internal/cache/cache.go @@ -0,0 +1,97 @@ +package cache + +import ( + "crypto/sha1" + "encoding/hex" + "errors" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + + "github.com/labstack/echo/v4" +) + +type Cache struct { + CacheDir string + Disabled bool +} + +func getCacheDir() (string, error) { + baseDir, err := os.UserCacheDir() + if err != nil { + baseDir = "/tmp" + } + cacheDir := filepath.Join(baseDir, "startpage") + err = os.MkdirAll(cacheDir, 0o755) + if err != nil { + return "", err + } + return cacheDir, nil +} + +func getProfileCacheDir(profile string) (string, error) { + var profileCacheDir string + + cacheDir, err := getCacheDir() + if err != nil { + return profileCacheDir, err + } + + profileCacheDir = filepath.Join(cacheDir, profile) + err = os.MkdirAll(cacheDir, 0o755) + return profileCacheDir, err +} + +func NewCache(profile string) Cache { + cacheDir, err := getProfileCacheDir(profile) + + return Cache{ + CacheDir: cacheDir, + Disabled: err != nil, + } +} + +const baseCacheUrl = "cache" + +func (c Cache) StartStaticServer(e *echo.Echo) error { + e.Static("/"+baseCacheUrl, c.CacheDir) + return nil +} + +func hashUrl(url string) string { + h := sha1.New() + io.WriteString(h, url) + return hex.EncodeToString(h.Sum(nil)) +} + +func (c Cache) CacheUrl(urlString string) (string, error) { + filename := hashUrl(urlString) + filepath.Ext(urlString) + targetPath := filepath.Join(c.CacheDir, filename) + + // if the file was already downloaded it doesn't need to be downloaded again + if _, err := os.Stat(targetPath); errors.Is(err, os.ErrNotExist) { + resp, err := http.Get(urlString) + if !errors.Is(err, os.ErrNotExist) { + return urlString, err + } + defer resp.Body.Close() + + file, err := os.Create(targetPath) + if err != nil { + return urlString, err + } + defer file.Close() + + _, err = io.Copy(file, resp.Body) + + if err != nil { + return urlString, err + } + } else { + return url.JoinPath(baseCacheUrl, filename) + } + + return url.JoinPath(baseCacheUrl, filename) +} diff --git a/internal/rendering/config.go b/internal/rendering/config.go index bd9f6f2..8348582 100644 --- a/internal/rendering/config.go +++ b/internal/rendering/config.go @@ -138,12 +138,3 @@ func (rc *Config) LoadConfigFile(file string) error { return toml.Unmarshal(content, rc) } - -func (c *Config) Init() error { - log.Println("downloading website icons...") - for i := range c.Template.Websites { - c.Template.Websites[i].Cache() - } - - return nil -} diff --git a/internal/server/server.go b/internal/server/server.go index f5b333e..a14fa28 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -5,6 +5,7 @@ import ( "net/http" "strconv" + "gitea.elara.ws/Hazel/transfem-startpage/internal/cache" "gitea.elara.ws/Hazel/transfem-startpage/internal/rendering" "github.com/labstack/echo/v4" ) @@ -17,11 +18,6 @@ func Start(profile string) error { return err } - err = Config.Init() - if err != nil { - return err - } - err = Config.FetchDiyHrt() if err != nil { log.Println(err) @@ -30,11 +26,19 @@ func Start(profile string) error { e := echo.New() // statically serve the file - cacheDir, err := rendering.GetCacheDir() - if err == nil { - e.Static("/cache", cacheDir) - } else { - log.Println("didn't enable cache dir", err) + cache := cache.NewCache(profile) + if !cache.Disabled { + cache.StartStaticServer(e) + + log.Println("downloading website icons...") + for i, w := range Config.Template.Websites { + u, err := cache.CacheUrl(w.ImageUrl) + if err != nil { + log.Println(err) + } + Config.Template.Websites[i].ImageUrl = u + Config.Template.Websites[i].IsFetched = true + } } // https://echo.labstack.com/docs/cookbook/embed-resources From 0b7de768744a1ae14c59376500b92368d1db69a8 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 16:13:48 +0200 Subject: [PATCH 12/13] edited readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fcb891..78cecc4 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ go install gitea.elara.ws/Hazel/transfem-startpage Then you can run the program `transfem-startpage` ```sh -transfem-startpage +transfem-startpage help ``` To configure this new tab page as website, you can install the firefox extension [New Tab Override](https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/). Then just configure the url as `http://127.0.0.1:{port}/`. The default port should be `5500` but it will also print it out when starting the server. Make sure to check the box `Set focus to the web page instead of the address bar` in the extension settings, because the new tab page auto focuses the search bar. From 68c89de1a47f7fe15f526a8f200ec8f6fa53a958 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 16 Jul 2025 16:25:22 +0200 Subject: [PATCH 13/13] made some metadata of the program dynamic --- internal/cache/cache.go | 3 ++- internal/cli/cli.go | 5 +++-- internal/cli/help.go | 3 ++- internal/diyhrt/fetch.go | 2 +- internal/rendering/config.go | 3 ++- internal/utils/meta.go | 6 ++++++ tmp/build-errors.log | 2 +- 7 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 internal/utils/meta.go diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 950ed43..fed52cb 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" + "gitea.elara.ws/Hazel/transfem-startpage/internal/utils" "github.com/labstack/echo/v4" ) @@ -23,7 +24,7 @@ func getCacheDir() (string, error) { if err != nil { baseDir = "/tmp" } - cacheDir := filepath.Join(baseDir, "startpage") + cacheDir := filepath.Join(baseDir, utils.Name) err = os.MkdirAll(cacheDir, 0o755) if err != nil { return "", err diff --git a/internal/cli/cli.go b/internal/cli/cli.go index ae1ba80..d76479a 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -4,6 +4,7 @@ import ( "log" "os" + "gitea.elara.ws/Hazel/transfem-startpage/internal/utils" "github.com/TwiN/go-color" ) @@ -22,8 +23,8 @@ type Argument struct { Description string } -var HelpHeader = `This is the help page of transfem-startpage. -` + color.Purple + `transfem-startpage {program} {...args}` + color.Reset + ` +var HelpHeader = `This is the help page of ` + utils.Name + `. +` + color.Purple + utils.BinaryName + ` {program} {...args}` + color.Reset + ` The following Programs are available:` var Programs = []Program{ { diff --git a/internal/cli/help.go b/internal/cli/help.go index 61b6ac6..876b0c3 100644 --- a/internal/cli/help.go +++ b/internal/cli/help.go @@ -5,6 +5,7 @@ import ( "os" "strings" + "gitea.elara.ws/Hazel/transfem-startpage/internal/utils" "github.com/TwiN/go-color" ) @@ -55,7 +56,7 @@ func specificHelp(programName string) error { fmt.Println(color.Bold + "MAN PAGE FOR " + strings.ToUpper(programName) + color.Reset) fmt.Println() - fmt.Println(color.Purple + "transfem-startpage " + programName + color.Reset + getArgumentString(program.Arguments)) + fmt.Println(color.Purple + utils.BinaryName + " " + programName + color.Reset + getArgumentString(program.Arguments)) fmt.Println() fmt.Println(color.Bold + "arguments" + color.Reset) diff --git a/internal/diyhrt/fetch.go b/internal/diyhrt/fetch.go index d2c9fb6..d1db765 100644 --- a/internal/diyhrt/fetch.go +++ b/internal/diyhrt/fetch.go @@ -11,7 +11,7 @@ const endpoint = "https://diyhrt.market/api/listings" func GetListings(apiKey string) ([]Listing, error) { if apiKey == "" { - return nil, errors.New("API_KEY key not set. Set it as env or in DiyHrt.ApiKey") + return nil, errors.New("diyhrt API_KEY key not set. Set it as env or in DiyHrt.ApiKey") } // Create HTTP client diff --git a/internal/rendering/config.go b/internal/rendering/config.go index 8348582..7e56f8f 100644 --- a/internal/rendering/config.go +++ b/internal/rendering/config.go @@ -7,6 +7,7 @@ import ( "path/filepath" "gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt" + "gitea.elara.ws/Hazel/transfem-startpage/internal/utils" "github.com/pelletier/go-toml" ) @@ -105,7 +106,7 @@ func (rc *Config) ScanForConfigFile(profile string) error { baseDir, cacheDirErr := os.UserConfigDir() if cacheDirErr == nil { - configFile := filepath.Join(baseDir, "startpage", profileFile) + configFile := filepath.Join(baseDir, utils.Name, profileFile) if err := rc.LoadConfigFile(configFile); !errors.Is(err, os.ErrNotExist) { return err diff --git a/internal/utils/meta.go b/internal/utils/meta.go new file mode 100644 index 0000000..133bc73 --- /dev/null +++ b/internal/utils/meta.go @@ -0,0 +1,6 @@ +package utils + +import "os" + +var Name = "transfem-startpage" +var BinaryName = os.Args[0] diff --git a/tmp/build-errors.log b/tmp/build-errors.log index 9ba0172..a2a130a 100644 --- a/tmp/build-errors.log +++ b/tmp/build-errors.log @@ -1 +1 @@ -exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file +exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file