package site import ( "encoding/json" "fmt" "html/template" "net/http" "path" "strconv" "strings" "github.com/angelbeltran/templater" "ruben/inventory2/internal/domains/accounts" "ruben/inventory2/internal/domains/authentication" etsy_platform "ruben/inventory2/internal/domains/platforms/etsy" "ruben/inventory2/internal/domains/raw_events" "ruben/inventory2/internal/site/response" ) type Server struct { http.Handler contentDir string templater *templater.Templater rawEvents *raw_events.Store accts *accounts.Store etsy *etsy_platform.Platform auth *authentication.Authenticator } func NewServer( contentDir string, rawEvents *raw_events.Store, accts *accounts.Store, etsy *etsy_platform.Platform, auth *authentication.Authenticator, ) *Server { mux := http.NewServeMux() s := &Server{ contentDir: contentDir, templater: templater.NewTemplater( contentDir+"/templates", func() template.FuncMap { return template.FuncMap{ "buildSitePath": func(parts ...any) string { strParts := make([]string, len(parts)) for i, p := range parts { strParts[i] = fmt.Sprint(p) } // TODO: make "/site" dynamic somehow //return path.Join(append([]string{"/site"}, strParts...)...) return path.Join(strParts...) }, "splitPath": func(p string) []string { if p == "" { return nil } return strings.Split(strings.TrimSuffix(strings.TrimPrefix(p, "/"), "/"), "/") }, "prettyPrintJSON": func(j json.RawMessage) string { b, err := json.MarshalIndent(j, " ", "") if err != nil { return string(j) } return string(b) }, "parseInt64": func(s string) (int64, error) { return strconv.ParseInt(s, 10, 64) }, "addInt": func(a, b int) int { return a + b }, "subInt": func(a, b int) int { return a - b }, "multInt": func(a, b int) int { return a * b }, } }, ), rawEvents: rawEvents, accts: accts, etsy: etsy, auth: auth, } // api routes mux.Handle("GET /login", response.Handler(s.loginPage)) mux.Handle("GET /login/callback", response.Handler(s.loginCallback)) mux.Handle("GET /logout", response.Handler(s.logoutPage)) mux.Handle("POST /accounts", response.Handler(s.authenticateAndAddIdentity(s.createAccount))) // TODO: eliminate once no longer used. mux.HandleFunc("POST /login", response.Handler(s.login)) // webpage content scfs := http.FileServer(http.Dir(contentDir + "/scripts")) mux.Handle("GET /scripts/", http.StripPrefix("/scripts", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/javascript") if path.Ext(r.URL.Path) == ".gz" { w.Header().Set("Content-Encoding", "gzip") } scfs.ServeHTTP(w, r) }))) mux.Handle("GET /styles/", http.StripPrefix("/styles", http.FileServer(http.Dir(contentDir+"/styles")))) // webpages // all non-authenticated webpages mux.HandleFunc("GET /{$}", response.Handler(s.addIdentity(s.serveTemplates))) // all authenticated webpages mux.HandleFunc("GET /", response.Handler(s.authenticateAndAddIdentity(s.serveTemplates))) s.Handler = mux return s }