package admin import ( "fmt" "net/http" "os" "arimelody-web/admin/account" "arimelody-web/admin/auth" "arimelody-web/admin/blog" "arimelody-web/admin/core" "arimelody-web/admin/logs" "arimelody-web/admin/music" "arimelody-web/admin/templates" "arimelody-web/controller" "arimelody-web/model" "arimelody-web/view" ) func Handler(app *model.AppState) http.Handler { mux := http.NewServeMux() mux.Handle("/register", auth.RegisterAccountHandler(app)) mux.Handle("/login", auth.LoginHandler(app)) mux.Handle("/totp", auth.LoginTOTPHandler(app)) mux.Handle("/logout", core.RequireAccount(auth.LogoutHandler(app))) mux.Handle("/logs", core.RequireAccount(logs.Handler(app))) mux.Handle("/music/", core.RequireAccount(http.StripPrefix("/music", music.Handler(app)))) mux.Handle("/blogs/", core.RequireAccount(http.StripPrefix("/blogs", blog.Handler(app)))) mux.Handle("/account/", core.RequireAccount(http.StripPrefix("/account", account.Handler(app)))) mux.Handle("/static/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/static/admin.css" { http.ServeFile(w, r, "./admin/static/admin.css") return } if r.URL.Path == "/static/admin.js" { http.ServeFile(w, r, "./admin/static/admin.js") return } core.RequireAccount( http.StripPrefix("/static", view.ServeFiles("./admin/static"))).ServeHTTP(w, r) })) mux.Handle("/", core.RequireAccount(adminIndexHandler(app))) // response wrapper to make sure a session cookie exists return core.EnforceSession(app, mux) } func adminIndexHandler(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } session := r.Context().Value("session").(*model.Session) releases, err := controller.GetAllReleases(app.DB, false, 3, true) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull releases: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } releaseCount, err := controller.GetReleaseCount(app.DB, false) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull releases count: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } artists, err := controller.GetAllArtists(app.DB) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull artists: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } artistCount, err := controller.GetArtistCount(app.DB) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull artist count: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } tracks, err := controller.GetOrphanTracks(app.DB) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull orphan tracks: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } trackCount, err := controller.GetTrackCount(app.DB) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to pull track count: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } type IndexData struct { core.AdminPageData Releases []*model.Release ReleaseCount int Artists []*model.Artist ArtistCount int Tracks []*model.Track TrackCount int } err = templates.IndexTemplate.Execute(w, IndexData{ AdminPageData: core.AdminPageData{ Path: r.URL.Path, Session: session }, Releases: releases, ReleaseCount: releaseCount, Artists: artists, ArtistCount: artistCount, Tracks: tracks, TrackCount: trackCount, }) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to render admin index: %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } }) } /* //go:embed "static" var staticFS embed.FS func staticHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { uri := strings.TrimPrefix(r.URL.Path, "/static") file, err := staticFS.ReadFile(filepath.Join("static", filepath.Clean(uri))) if err != nil { http.NotFound(w, r) return } w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path))) w.WriteHeader(http.StatusOK) w.Write(file) }) } */