package pages import ( "encoding/json" "fmt" "html/template" "net/http" "os" "strings" "gogs.gildas.ch/gildas/movies" "gogs.gildas.ch/gildas/movies/omdb" "gopkg.in/russross/blackfriday.v2" ) func Router(c *movies.Collection) http.HandlerFunc { homeHandler := Home(c) movieHandler := Movie(c) listHandler := List(c) filesHandler := Files(c) fileHandler := File(c, "/files/") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { path := r.URL.Path switch { case path == "/": homeHandler(w, r) return case path == "/style.css": http.ServeFile(w, r, "templates/style.css") return case strings.HasPrefix(path, "/l/"): listHandler(w, r) return case strings.HasPrefix(path, "/tt"): movieHandler(w, r) return case path == "/files": filesHandler(w, r) return case strings.HasPrefix(path, "/files/"): fileHandler(w, r) return } }) } func Home(c *movies.Collection) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t, err := template.ParseFiles("templates/home.html") if err != nil { fmt.Println(err) return } var errs []error if r.Method == "POST" { if r.FormValue("omdb_json") != "" { m, err := movies.UnmarshalFromOMDB([]byte(r.FormValue("omdb_json"))) if err != nil { w.WriteHeader(http.StatusBadRequest) errs = append(errs, err) } else { c.Add(m) } } if r.FormValue("list-id") != "" { if err := c.AddList(r.FormValue("list-id"), r.FormValue("list-title")); err != nil { errs = append(errs, err) } } } var omdbString string if imdbID := r.URL.Query().Get("imdb_id"); imdbID != "" { b, err := omdb.Get(imdbID) if err != nil { errs = append(errs, err) } else { omdbString = string(b) } } if err := t.Execute(w, map[string]interface{}{ "Collection": c, "IMDBID": r.URL.Query().Get("imdb_id"), "OMDBString": omdbString, "Errors": errs, }); err != nil { fmt.Println(err) } }) } func Movie(c *movies.Collection) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t, err := template.ParseFiles("templates/movie.html") if err != nil { fmt.Println(err) return } var errs []error splitted := strings.Split(r.URL.Path, "/") if len(splitted) < 2 { w.WriteHeader(http.StatusNotFound) return } imdbID := splitted[1] m, ok := c.Get(imdbID) if !ok { w.WriteHeader(http.StatusNotFound) return } if r.Method == "POST" { if movieJSON := r.FormValue("movie_json"); movieJSON != "" { updated, err := movies.Unmarshal([]byte(movieJSON)) if err != nil { errs = append(errs, err) } else if imdbID != updated.IMDBID { errs = append(errs, fmt.Errorf("you cannot change the imdb id.")) } else { m = updated fmt.Println("Update with", m) c.Update(updated) } } if files := r.FormValue("files"); files != "" { m.Files = strings.Split(files, "\n") fmt.Println("Update with", m) c.Update(m) } if r.FormValue("generate_mediainfo") != "" { if err := m.GenerateMediaInfo(); err != nil { errs = append(errs, err) } else { c.Update(m) } } } fileQuery := r.URL.Query().Get("file_query") var fileResults string if fileQuery != "" { fileResults = strings.Join(c.SearchFiles(fileQuery), "\n") } b, err := json.MarshalIndent(m, "", " ") if err != nil { errs = append(errs, err) } if err := t.Execute(w, map[string]interface{}{ "Movie": m, "MovieJSON": string(b), "Files": strings.Join(m.Files, "\n"), "FileQuery": fileQuery, "FileResults": fileResults, "Errors": errs, }); err != nil { fmt.Println(err) } }) } func List(c *movies.Collection) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t, err := template.ParseFiles("templates/list.html") if err != nil { fmt.Println(err) return } var errs []error splitted := strings.Split(r.URL.Path, "/") if len(splitted) < 3 { w.WriteHeader(http.StatusNotFound) return } listID := splitted[2] l, ok := c.GetList(listID) if !ok { w.WriteHeader(http.StatusNotFound) return } if r.Method == "POST" { if r.FormValue("title") != "" || r.FormValue("description") != "" { l.Title = r.FormValue("title") l.Description = r.FormValue("description") c.UpdateList(l) } else if r.FormValue("imdb_id") != "" { l.Movies = append(l.Movies, r.FormValue("imdb_id")) c.UpdateList(l) } } b, err := json.MarshalIndent(l, "", " ") if err != nil { errs = append(errs, err) } var ms []*movies.Movie for _, imdbID := range l.Movies { if m, ok := c.Get(imdbID); ok { ms = append(ms, m) } } if err := t.Execute(w, map[string]interface{}{ "List": l, "Description": template.HTML( blackfriday.Run( []byte(strings.ReplaceAll(l.Description, "\r\n", "\n")), blackfriday.WithExtensions(blackfriday.CommonExtensions))), "Movies": ms, "ListJSON": string(b), "Errors": errs, }); err != nil { fmt.Println(err) } }) } func Files(c *movies.Collection) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if query := r.URL.Query().Get("query"); query != "" { matches := c.SearchFiles(query) for _, match := range matches { fmt.Fprintf(w, "%s\n", match) } return } t, err := template.ParseFiles("templates/files.html") if err != nil { fmt.Println(err) return } var errs []error if r.Method == "POST" && r.FormValue("scan") == "1" { if err := c.ScanFiles(os.Getenv("FILE_ROOT")); err != nil { errs = append(errs, err) } } if err := t.Execute(w, map[string]interface{}{ "Files": c.AllFiles(), "Errors": errs, }); err != nil { fmt.Println(err) } }) } func File(c *movies.Collection, prefix string) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { file := "/" + strings.TrimPrefix(r.URL.Path, prefix) c.Files.Serve(w, r, file) }) }