package main import ( "fmt" "html/template" "log" "net/http" "os" "path/filepath" "arimelody.me/arimelody.me/api/v1/admin" "arimelody.me/arimelody.me/api/v1/music" "arimelody.me/arimelody.me/global" ) const DEFAULT_PORT int = 8080 func main() { db := InitDatabase() defer db.Close() var err error music.Artists, err = PullAllArtists(db) if err != nil { fmt.Printf("Failed to pull artists from database: %v\n", err); panic(1) } music.Releases, err = PullAllReleases(db) if err != nil { fmt.Printf("Failed to pull releases from database: %v\n", err); panic(1) } mux := http.NewServeMux() mux.Handle("/api/v1/admin/", global.HTTPLog(http.StripPrefix("/api/v1/admin", admin.Handler()))) mux.Handle("/music/", global.HTTPLog(http.StripPrefix("/music", musicGatewayHandler()))) mux.Handle("/music", global.HTTPLog(serveTemplate("music.html", music.Releases))) mux.Handle("/", global.HTTPLog(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" || r.URL.Path == "/index.html" { serveTemplate("index.html", nil).ServeHTTP(w, r) return } staticHandler().ServeHTTP(w, r) }))) port := DEFAULT_PORT fmt.Printf("now serving at http://127.0.0.1:%d\n", port) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), mux)) } func staticHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { info, err := os.Stat(filepath.Join("public", filepath.Clean(r.URL.Path))) // does the file exist? if err != nil { if os.IsNotExist(err) { http.NotFound(w, r) return } } // is thjs a directory? (forbidden) if info.IsDir() { http.NotFound(w, r) return } http.FileServer(http.Dir("./public")).ServeHTTP(w, r) }) } func musicGatewayHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { id := r.URL.Path[1:] release, err := music.GetRelease(id) if err != nil { http.NotFound(w, r) return } lrw := global.LoggingResponseWriter{w, http.StatusOK} serveTemplate("music-gateway.html", release).ServeHTTP(&lrw, r) if lrw.Code != http.StatusOK { fmt.Printf("Error loading music gateway for %s\n", id) return } }) } func serveTemplate(page string, data any) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { lp_layout := filepath.Join("views", "layout.html") lp_header := filepath.Join("views", "header.html") lp_footer := filepath.Join("views", "footer.html") lp_prideflag := filepath.Join("views", "prideflag.html") fp := filepath.Join("views", filepath.Clean(page)) info, err := os.Stat(fp) if err != nil { if os.IsNotExist(err) { http.NotFound(w, r) return } } if info.IsDir() { http.NotFound(w, r) return } template, err := template.ParseFiles(lp_layout, lp_header, lp_footer, lp_prideflag, fp) if err != nil { fmt.Printf("Error parsing template files: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } err = template.ExecuteTemplate(w, "layout.html", data) if err != nil { fmt.Printf("Error executing template: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } }) }