Files
inventory-plus-plus/internal/site/site.go
T
2025-12-30 14:42:04 -07:00

127 lines
3.3 KiB
Go

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 {
mux *http.ServeMux
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 {
s := &Server{
mux: http.NewServeMux(),
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
s.mux.HandleFunc("GET /login", response.Handler(s.loginPage))
s.mux.HandleFunc("GET /login/callback", response.Handler(s.loginCallback))
s.mux.HandleFunc("GET /logout", response.Handler(s.logoutPage))
s.mux.Handle("POST /accounts", response.Handler(s.authenticate(s.createAccount)))
// TODO: eliminate once no longer used.
s.mux.HandleFunc("POST /login", response.Handler(s.login))
// TODO: get rid of this, once we're confident this isn't needed...
s.mux.Handle("GET /test-auth", response.Handler(s.authenticate(s.testAuthEndpoint)))
// webpage content
scfs := http.FileServer(http.Dir(contentDir + "/scripts"))
s.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)
})))
s.mux.Handle("GET /styles/", http.StripPrefix("/styles", http.FileServer(http.Dir(contentDir+"/styles"))))
// TODO: put auth on individual templates, somehow...
s.mux.HandleFunc("GET /", s.serveTemplates)
return s
}
// http.Handler implementation
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.mux.ServeHTTP(w, r)
}