package main import ( "fmt" "html/template" "log" "net/http" "strconv" "time" "arimelody.me/arimelody.me/api/v1/admin" "arimelody.me/arimelody.me/api/v1/music" ) const DEFAULT_PORT int = 8080 var base_template = template.Must(template.ParseFiles( "views/base.html", "views/header.html", "views/footer.html", "views/prideflag.html", )) func log_request(req *http.Request, code int, start_time time.Time) { now := time.Now() difference := (now.Nanosecond() - start_time.Nanosecond()) / 1_000_000 elapsed := "<1" if difference >= 1 { elapsed = strconv.Itoa(difference) } fmt.Printf("[%s] %s %s - %d (%sms) (%s)\n", now.Format(time.UnixDate), req.Method, req.URL.Path, code, elapsed, req.Header["User-Agent"][0]) } // func handle_request(res http.ResponseWriter, req *http.Request) { // uri := req.URL.Path // start_time := time.Now() // // res.Header().Set("Server", "arimelody.me") // // code := func(res http.ResponseWriter, req *http.Request) int { // var root = template.Must(base_template.Clone()) // // if req.URL.Path == "/" { // return handle_index(res, req, root) // } // // if uri == "/music" || uri == "/music/" { // return handle_music(res, req, root) // } // // if strings.HasPrefix(uri, "/music/") { // return handle_music_gateway(res, req, root) // } // // if strings.HasPrefix(uri, "/admin") { // return admin.Handle(res, req, root) // } // // if strings.HasPrefix(uri, "/api") { // return api.Handle(res, req, root) // } // // return static_handler(res, req, root) // }(res, req) // // log_request(req, code, start_time) // } // // func handle_index(res http.ResponseWriter, req *http.Request, root *template.Template) int { // if !global.IsModified(req, global.LAST_MODIFIED) { // res.WriteHeader(304) // return 304 // } // // index_template := template.Must(root.ParseFiles("views/index.html")) // err := index_template.Execute(res, nil) // if err != nil { // http.Error(res, err.Error(), http.StatusInternalServerError) // return 500 // } // return 200 // } // // func handle_music(res http.ResponseWriter, req *http.Request, root *template.Template) int { // if !global.IsModified(req, global.LAST_MODIFIED) { // res.WriteHeader(304) // return 304 // } // // music_template := template.Must(root.ParseFiles("views/music.html")) // err := music_template.Execute(res, music.Releases) // if err != nil { // http.Error(res, err.Error(), http.StatusInternalServerError) // return 500 // } // return 200 // } // // func handle_music_gateway(res http.ResponseWriter, req *http.Request, root *template.Template) int { // if !global.IsModified(req, global.LAST_MODIFIED) { // res.WriteHeader(304) // return 304 // } // // id := req.URL.Path[len("/music/"):] // release, err := music.GetRelease(id) // if err != nil { // return handle_not_found(res, req, root) // } // gateway_template := template.Must(root.ParseFiles("views/music-gateway.html")) // err = gateway_template.Execute(res, release) // if err != nil { // http.Error(res, err.Error(), http.StatusInternalServerError) // return 500 // } // return 200 // } // // func static_handler(res http.ResponseWriter, req *http.Request, root *template.Template) int { // filename := "public/" + req.URL.Path[1:] // // // check the file's metadata // info, err := os.Stat(filename) // if err != nil { // return handle_not_found(res, req, root) // } // // if !global.IsModified(req, info.ModTime()) { // res.WriteHeader(304) // return 304 // } // // // set Last-Modified to file modification date // res.Header().Set("Last-Modified", info.ModTime().Format(http.TimeFormat)) // // // read the file // body, err := os.ReadFile(filename) // if err != nil { // http.Error(res, err.Error(), http.StatusInternalServerError) // return 500 // } // // // setting MIME types // filetype := filename[strings.LastIndex(filename, ".")+1:] // if mime_type, ok := global.MimeTypes[filetype]; ok { // res.Header().Set("Content-Type", mime_type) // } else { // res.Header().Set("Content-Type", "text/plain; charset=utf-8") // } // // res.Write([]byte(body)) // return 200 // } // // func handle_not_found(res http.ResponseWriter, req *http.Request, root *template.Template) int { // type ErrorData struct { // Target string // } // error_data := ErrorData{ Target: req.URL.Path } // res.WriteHeader(404); // error_template := template.Must(root.ParseFiles("views/404.html")) // err := error_template.Execute(res, error_data) // if err != nil { // http.Error(res, err.Error(), http.StatusInternalServerError) // return 500 // } // return 404 // } // // func parse_markdown(md []byte) []byte { // extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock // p := parser.NewWithExtensions(extensions) // doc := p.Parse(md) // // htmlFlags := html.CommonFlags // opts := html.RendererOptions{Flags: htmlFlags} // renderer := html.NewRenderer(opts) // // return markdown.Render(doc, renderer) // } 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", admin.Handler()) mux.Handle("/api/v1/admin/login", admin.LoginHandler()) mux.Handle("/api/v1/admin/callback", admin.OAuthCallbackHandler()) mux.Handle("/api/v1/admin/verify", admin.AuthorisedHandler(admin.VerifyHandler())) mux.Handle("/api/v1/admin/logout", admin.AuthorisedHandler(admin.LogoutHandler())) 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)) }