pages.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package pages
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "html/template"
  6. "net/http"
  7. "os"
  8. "strings"
  9. "gogs.gildas.ch/gildas/movies"
  10. "gogs.gildas.ch/gildas/movies/omdb"
  11. "gopkg.in/russross/blackfriday.v2"
  12. )
  13. func Router(c *movies.Collection) http.HandlerFunc {
  14. homeHandler := Home(c)
  15. movieHandler := Movie(c)
  16. listHandler := List(c)
  17. filesHandler := Files(c)
  18. fileHandler := File(c, "/files/")
  19. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  20. path := r.URL.Path
  21. switch {
  22. case path == "/":
  23. homeHandler(w, r)
  24. return
  25. case path == "/style.css":
  26. http.ServeFile(w, r, "templates/style.css")
  27. return
  28. case strings.HasPrefix(path, "/l/"):
  29. listHandler(w, r)
  30. return
  31. case strings.HasPrefix(path, "/tt"):
  32. movieHandler(w, r)
  33. return
  34. case path == "/files":
  35. filesHandler(w, r)
  36. return
  37. case strings.HasPrefix(path, "/files/"):
  38. fileHandler(w, r)
  39. return
  40. }
  41. })
  42. }
  43. func Home(c *movies.Collection) http.HandlerFunc {
  44. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  45. t, err := template.ParseFiles("templates/home.html")
  46. if err != nil {
  47. fmt.Println(err)
  48. return
  49. }
  50. var errs []error
  51. if r.Method == "POST" {
  52. if r.FormValue("omdb_json") != "" {
  53. m, err := movies.UnmarshalFromOMDB([]byte(r.FormValue("omdb_json")))
  54. if err != nil {
  55. w.WriteHeader(http.StatusBadRequest)
  56. errs = append(errs, err)
  57. } else {
  58. c.Add(m)
  59. }
  60. }
  61. if r.FormValue("list-id") != "" {
  62. if err := c.AddList(r.FormValue("list-id"), r.FormValue("list-title")); err != nil {
  63. errs = append(errs, err)
  64. }
  65. }
  66. }
  67. var omdbString string
  68. if imdbID := r.URL.Query().Get("imdb_id"); imdbID != "" {
  69. b, err := omdb.Get(imdbID)
  70. if err != nil {
  71. errs = append(errs, err)
  72. } else {
  73. omdbString = string(b)
  74. }
  75. }
  76. if err := t.Execute(w, map[string]interface{}{
  77. "Collection": c,
  78. "IMDBID": r.URL.Query().Get("imdb_id"),
  79. "OMDBString": omdbString,
  80. "Errors": errs,
  81. }); err != nil {
  82. fmt.Println(err)
  83. }
  84. })
  85. }
  86. func Movie(c *movies.Collection) http.HandlerFunc {
  87. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  88. t, err := template.ParseFiles("templates/movie.html")
  89. if err != nil {
  90. fmt.Println(err)
  91. return
  92. }
  93. var errs []error
  94. splitted := strings.Split(r.URL.Path, "/")
  95. if len(splitted) < 2 {
  96. w.WriteHeader(http.StatusNotFound)
  97. return
  98. }
  99. imdbID := splitted[1]
  100. m, ok := c.Get(imdbID)
  101. if !ok {
  102. w.WriteHeader(http.StatusNotFound)
  103. return
  104. }
  105. if r.Method == "POST" {
  106. if movieJSON := r.FormValue("movie_json"); movieJSON != "" {
  107. updated, err := movies.Unmarshal([]byte(movieJSON))
  108. if err != nil {
  109. errs = append(errs, err)
  110. } else if imdbID != updated.IMDBID {
  111. errs = append(errs, fmt.Errorf("you cannot change the imdb id."))
  112. } else {
  113. m = updated
  114. fmt.Println("Update with", m)
  115. c.Update(updated)
  116. }
  117. }
  118. if files := r.FormValue("files"); files != "" {
  119. files = strings.ReplaceAll(files, "\r", "")
  120. m.Files = strings.Split(files, "\n")
  121. fmt.Println("Update with", m)
  122. c.Update(m)
  123. }
  124. if r.FormValue("generate_mediainfo") != "" {
  125. if err := m.GenerateMediaInfo(); err != nil {
  126. errs = append(errs, err)
  127. } else {
  128. c.Update(m)
  129. }
  130. }
  131. }
  132. fileQuery := r.URL.Query().Get("file_query")
  133. var fileResults string
  134. if fileQuery != "" {
  135. fileResults = strings.Join(c.SearchFiles(fileQuery), "\n")
  136. }
  137. b, err := json.MarshalIndent(m, "", " ")
  138. if err != nil {
  139. errs = append(errs, err)
  140. }
  141. if err := t.Execute(w, map[string]interface{}{
  142. "Movie": m,
  143. "MovieJSON": string(b),
  144. "Files": strings.Join(m.Files, "\n"),
  145. "FileQuery": fileQuery,
  146. "FileResults": fileResults,
  147. "Errors": errs,
  148. }); err != nil {
  149. fmt.Println(err)
  150. }
  151. })
  152. }
  153. func List(c *movies.Collection) http.HandlerFunc {
  154. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  155. t, err := template.ParseFiles("templates/list.html")
  156. if err != nil {
  157. fmt.Println(err)
  158. return
  159. }
  160. var errs []error
  161. splitted := strings.Split(r.URL.Path, "/")
  162. if len(splitted) < 3 {
  163. w.WriteHeader(http.StatusNotFound)
  164. return
  165. }
  166. listID := splitted[2]
  167. l, ok := c.GetList(listID)
  168. if !ok {
  169. w.WriteHeader(http.StatusNotFound)
  170. return
  171. }
  172. if r.Method == "POST" {
  173. if r.FormValue("title") != "" || r.FormValue("description") != "" {
  174. l.Title = r.FormValue("title")
  175. l.Description = r.FormValue("description")
  176. c.UpdateList(l)
  177. } else if r.FormValue("imdb_id") != "" {
  178. l.Movies = append(l.Movies, r.FormValue("imdb_id"))
  179. c.UpdateList(l)
  180. }
  181. }
  182. b, err := json.MarshalIndent(l, "", " ")
  183. if err != nil {
  184. errs = append(errs, err)
  185. }
  186. var ms []*movies.Movie
  187. for _, imdbID := range l.Movies {
  188. if m, ok := c.Get(imdbID); ok {
  189. ms = append(ms, m)
  190. }
  191. }
  192. if err := t.Execute(w, map[string]interface{}{
  193. "List": l,
  194. "Description": template.HTML(
  195. blackfriday.Run(
  196. []byte(strings.ReplaceAll(l.Description, "\r\n", "\n")),
  197. blackfriday.WithExtensions(blackfriday.CommonExtensions))),
  198. "Movies": ms,
  199. "ListJSON": string(b),
  200. "Errors": errs,
  201. }); err != nil {
  202. fmt.Println(err)
  203. }
  204. })
  205. }
  206. func Files(c *movies.Collection) http.HandlerFunc {
  207. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  208. if query := r.URL.Query().Get("query"); query != "" {
  209. matches := c.SearchFiles(query)
  210. for _, match := range matches {
  211. fmt.Fprintf(w, "%s\n", match)
  212. }
  213. return
  214. }
  215. t, err := template.ParseFiles("templates/files.html")
  216. if err != nil {
  217. fmt.Println(err)
  218. return
  219. }
  220. var errs []error
  221. if r.Method == "POST" && r.FormValue("scan") == "1" {
  222. if err := c.ScanFiles(os.Getenv("FILE_ROOT")); err != nil {
  223. errs = append(errs, err)
  224. }
  225. }
  226. if err := t.Execute(w, map[string]interface{}{
  227. "Files": c.AllFiles(),
  228. "Errors": errs,
  229. }); err != nil {
  230. fmt.Println(err)
  231. }
  232. })
  233. }
  234. func File(c *movies.Collection, prefix string) http.HandlerFunc {
  235. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  236. file := "/" + strings.TrimPrefix(r.URL.Path, prefix)
  237. c.Files.Serve(w, r, file)
  238. })
  239. }