diff --git a/endpoint.go b/endpoint.go new file mode 100644 index 00000000..bef3d035 --- /dev/null +++ b/endpoint.go @@ -0,0 +1,17 @@ +package main + +import ( + "net/http" +) +func getFavicon(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-type", "image/x-icon") + + http.ServeFile(w, r, "static/favicon.ico") +} + +func getRoot(w http.ResponseWriter, r *http.Request) { + err := htmlRoot(w, r.URL.Path) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} diff --git a/go.mod b/go.mod index bfd0d64e..77f59ad7 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/Gleipnir-Technology/nidus-sync go 1.24.9 + +require ( + github.com/alexedwards/scs/v2 v2.9.0 + github.com/go-chi/chi/v5 v5.2.3 +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..428aef0e --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/alexedwards/scs/v2 v2.9.0 h1:xa05mVpwTBm1iLeTMNFfAWpKUm4fXAW7CeAViqBVS90= +github.com/alexedwards/scs/v2 v2.9.0/go.mod h1:ToaROZxyKukJKT/xLcVQAChi5k6+Pn1Gvmdl7h3RRj8= +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= diff --git a/html.go b/html.go new file mode 100644 index 00000000..8474f286 --- /dev/null +++ b/html.go @@ -0,0 +1,103 @@ +package main + +import ( + "errors" + "html/template" + "io" + "log" + "os" +) + +var ( + root = newBuiltTemplate("root", "base") + dashboard = newBuiltTemplate("dashboard", "base") +) + +type BuiltTemplate struct { + files []string + template *template.Template +} + +type Link struct { + Href string + Title string +} +type ContentDashboard struct { + BabbleLinks []Link + Username string +} +type ContentRoot struct { + BabbleLinks []Link +} + +func (bt *BuiltTemplate) ExecuteTemplate(w io.Writer, data any) error { + name := bt.files[0] + ".html" + if bt.template == nil { + templ := parseFromDisk(bt.files) + if templ == nil { + w.Write([]byte("Failed to read from disk")) + return errors.New("Template parsing failed") + } + return templ.ExecuteTemplate(w, name, data) + } else { + return bt.template.ExecuteTemplate(w, name, data) + } +} + +func htmlDashboard(w io.Writer, path string, username string) error { + data := ContentDashboard{ + Username: username, + } + return dashboard.ExecuteTemplate(w, data) +} + +func htmlRoot(w io.Writer, path string) error { + data := ContentRoot{ + } + return root.ExecuteTemplate(w, data) +} + +func makeFuncMap() template.FuncMap { + funcMap := template.FuncMap{} + return funcMap +} +func newBuiltTemplate(files ...string) BuiltTemplate { + files_on_disk := true + for _, f := range files { + full_path := "templates/" + f + ".html" + _, err := os.Stat(full_path) + if err != nil { + files_on_disk = false + break + } + } + if files_on_disk { + return BuiltTemplate{ + files: files, + template: nil, + } + } + return BuiltTemplate{ + files: files, + template: parseEmbedded(files), + } +} + +func parseEmbedded(files []string) *template.Template { + return nil +} + +func parseFromDisk(files []string) *template.Template { + funcMap := makeFuncMap() + paths := make([]string, 0) + for _, f := range files { + paths = append(paths, "templates/"+f+".html") + } + name := files[0] + ".html" + templ, err := template.New(name).Funcs(funcMap).ParseFiles(paths...) + if err != nil { + log.Println("TEMPLATE FAILED", err) + return nil + } + return templ +} diff --git a/main.go b/main.go index 04621e58..a34fc64d 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,51 @@ package main + import ( - "fmt" + "log" + "net/http" + "os" + "time" + + "github.com/alexedwards/scs/v2" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" ) + +var sessionManager *scs.SessionManager + +var BaseURL, ClientID, ClientSecret string + func main() { - fmt.Println("Hello World!") + ClientID = os.Getenv("ARCGIS_CLIENT_ID") + if ClientID == "" { + log.Println("You must specify a non-empty CLIENT_ID") + os.Exit(1) + } + ClientSecret = os.Getenv("ARCGIS_CLIENT_SECRET") + if ClientSecret == "" { + log.Println("You must specify a non-empty CLIENT_SECRET") + os.Exit(1) + } + BaseURL = os.Getenv("BASE_URL") + if BaseURL == "" { + log.Println("You must specify a non-empty BASE_URL") + os.Exit(1) + } + bind := os.Getenv("BIND") + if bind == "" { + bind = ":9001" + } + + log.Println("Starting...") + sessionManager = scs.New() + sessionManager.Lifetime = 24 * time.Hour + + r := chi.NewRouter() + r.Use(middleware.Logger) + r.Use(sessionManager.LoadAndSave) + + r.Get("/", getRoot) + r.Get("/favicon.ico", getFavicon) + log.Printf("Serving on %s", bind) + log.Fatal(http.ListenAndServe(bind, r)) } diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 00000000..2f7e078a Binary files /dev/null and b/static/favicon.ico differ diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 00000000..a433c331 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,10 @@ + + +
+ +Imagine there's cool stuff here.
+{{end}}