Author: Adam <git@apiote.tk>
show TV queue
datastructure/item.go | 9 ++- datastructure/list.go | 6 ++ datastructure/tvqueue.go | 58 +++++++++++++++++++++++ datastructure/watchlist.go | 8 +++ db/db.go | 61 ++++++++++++++++++++++++ front/capnproto.go | 4 + front/html.go | 6 ++ front/renderer.go | 1 libamuse/common.go | 11 ++++ libamuse/tvqueue.go | 55 ++++++++++++++++++++++ libamuse/watchlist.go | 16 +----- router.go | 7 ++ templates/about.html | 1 templates/book.html | 1 templates/bookserie.html | 1 templates/experiences.html | 1 templates/film.html | 1 templates/index.html | 1 templates/person.html | 1 templates/search.html | 1 templates/tvqueue.html | 99 ++++++++++++++++++++++++++++++++++++++++ templates/tvserie.html | 1 templates/watchlist.html | 3 tmdb/genres.go | 20 ++++++- tmdb/serie.go | 2
diff --git a/datastructure/item.go b/datastructure/item.go index 77383d4f284743907f1f204535254f9c2430a99f..44ca31ef527796280cfee1e3f29e38916e646202 100644 --- a/datastructure/item.go +++ b/datastructure/item.go @@ -18,8 +18,9 @@ Collection int Part int } -func (i ItemInfo) IsUnreleased() bool { - return i.Status != "Released" +func (i ItemInfo) IsUnreleased(itemType ItemType) bool { + return (itemType == ItemTypeFilm && i.Status != "Released") || + (itemType == ItemTypeTvserie && i.Status != "Returning Series" && i.Status != "Ended") } func (i ItemInfo) GetGenres(genres map[int]string) string { @@ -28,7 +29,9 @@ genreNames := []string{} for _, genreId := range genreIds { if genreId != "" { genreIdInt, _ := strconv.ParseInt(genreId, 10, 64) - genreNames = append(genreNames, genres[int(genreIdInt)]) + if genres[int(genreIdInt)] != "" { + genreNames = append(genreNames, genres[int(genreIdInt)]) + } } } return strings.Join(genreNames, ", ") diff --git a/datastructure/list.go b/datastructure/list.go new file mode 100644 index 0000000000000000000000000000000000000000..4ba072a0e226c2456e3450178332a51ac7fe4ea3 --- /dev/null +++ b/datastructure/list.go @@ -0,0 +1,6 @@ +package datastructure + +type List interface { + SetGenres(map[int]string) + GetType() ItemType +} diff --git a/datastructure/tvqueue.go b/datastructure/tvqueue.go new file mode 100644 index 0000000000000000000000000000000000000000..33104c0163bb6bf9ced05533192cb3e6f9583e9d --- /dev/null +++ b/datastructure/tvqueue.go @@ -0,0 +1,58 @@ +package datastructure + +import ( + "strconv" +) + +type TvQueueEntry struct { + ItemInfo + Id string + HasPrevious bool + WatchedEpisodes int +} + +func (e TvQueueEntry) GetYears() string { + if e.YearStart == 0 { + return "" + } else if e.Status == "Ended" { + if e.YearEnd == e.YearStart { + return strconv.FormatInt(int64(e.YearStart), 10) + } else { + return strconv.FormatInt(int64(e.YearStart), 10) + "–" + strconv.FormatInt(int64(e.YearEnd), 10) + } + } else { + return strconv.FormatInt(int64(e.YearStart), 10) + "–" + } +} + +type TvQueue struct { + List []TvQueueEntry + Page int + Pages int + Genres map[int]string + Query string +} + +func (q *TvQueue) SetGenres(m map[int]string) { + q.Genres = m +} + +func (q *TvQueue) GetType() ItemType { + return ItemTypeTvserie +} + +func (q TvQueue) NextPage() int { + if q.Page < q.Pages { + return q.Page + 1 + } else { + return q.Page + } +} + +func (q TvQueue) PrevPage() int { + if q.Page > 1 { + return q.Page - 1 + } else { + return q.Page + } +} diff --git a/datastructure/watchlist.go b/datastructure/watchlist.go index 8fbfeaae6aab4a43c6eb35456f0721a4ee467810..ac12a25f399487ca3f68bf76969a97d219812715 100644 --- a/datastructure/watchlist.go +++ b/datastructure/watchlist.go @@ -14,6 +14,14 @@ Genres map[int]string Query string } +func (w *Watchlist) SetGenres(m map[int]string) { + w.Genres = m +} + +func (w *Watchlist) GetType() ItemType { + return ItemTypeFilm +} + func (w Watchlist) NextPage() int { if w.Page < w.Pages { return w.Page + 1 diff --git a/db/db.go b/db/db.go index 1cfb126da492da2624b241c5a2835af7a10bf373..b9cfb57eb676971a4498e8242cd3991625a90107 100644 --- a/db/db.go +++ b/db/db.go @@ -585,6 +585,67 @@ return watchlist, nil } +func GetTvQueue(username, filter string, page int) (datastructure.TvQueue, error) { + tvQueue := datastructure.TvQueue{} + db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") + if err != nil { + fmt.Fprintf(os.Stderr, "DB open err\n") + return tvQueue, err + } + defer db.Close() + + if page <= 0 { + page = 1 + } + + var pages float64 + row := db.QueryRow(`select count(*) from wantlist where item_type = 'tvserie' and username = ?`, username) + err = row.Scan(&pages) + if err != nil { + return tvQueue, err + } + tvQueue.Pages = int(math.Ceil(pages / 18)) + + offset := (page - 1) * 18 + + //todo filter, order by + + var whereClause string + if filter != "" { + whereClause = "and c1.title like '%" + filter + "%'" + } + + rows, err := db.Query(`select item_id, episodes_watched, cover, status, based_on, genres, title, year_start, year_end, substr(e.id, 1, pos-1) as series_id from wantlist w left join (select count(time) as episodes_watched, item_id as id, instr(item_id, '/') as pos from experiences where item_type = 'tvserie' and time != '0001-01-01 00:00:00+00:00' group by substr(id, 1, pos-1)) e on item_id = series_id natural join item_cache c where item_type = 'tvserie' and username = ? `+whereClause+` order by title limit ?,18`, username, offset) + + if err != nil { + fmt.Fprintf(os.Stderr, "Select err: %v\n", err) + return tvQueue, err + } + defer rows.Close() + + for rows.Next() { + var ( + entry datastructure.TvQueueEntry + episodes_watched *int + series_id *int + ) + err := rows.Scan(&entry.Id, &episodes_watched, &entry.Cover, &entry.Status, &entry.BasedOn, &entry.Genres, &entry.Title, &entry.YearStart, &entry.YearEnd, &series_id) + if err != nil { + fmt.Println("Scan error") + return datastructure.TvQueue{}, err + } + if episodes_watched == nil { + entry.WatchedEpisodes = 0 + } else { + entry.WatchedEpisodes = *episodes_watched + } + + tvQueue.List = append(tvQueue.List, entry) + } + + return tvQueue, nil +} + func GetUserExperiences(username, filter string, page int) (datastructure.Experiences, error) { experiences := datastructure.Experiences{} db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") diff --git a/front/capnproto.go b/front/capnproto.go index b2656f82d2d1f393f25a434b94740ce0a079814e..d9459f01145f2671e0533b71a7297dde5baf414a 100644 --- a/front/capnproto.go +++ b/front/capnproto.go @@ -59,6 +59,10 @@ func (CapnprotoRenderer) RenderWatchlist(watchlist datastructure.Watchlist, languages []language.Tag) string { return TODO("implement CapnprotoRenderer.RenderWatchlist").(string) } +func (CapnprotoRenderer) RenderTvQueue(watchlist datastructure.TvQueue, languages []language.Tag) string { + return TODO("implement CapnprotoRenderer.RenderTvQueue").(string) +} + func (CapnprotoRenderer) RenderExperiences(experiences datastructure.Experiences, languages []language.Tag) string { return TODO("implement CapnprotoRenderer.RenderExperiences").(string) } diff --git a/front/html.go b/front/html.go index 3e96480f9dd37dba02c8c689e0f56c57233968ea..032616129d9def0d580a21cca672f9dbdc0b3191 100644 --- a/front/html.go +++ b/front/html.go @@ -144,6 +144,12 @@ data.State.User = r.user return render(languages, data, "watchlist") } +func (r HtmlRenderer) RenderTvQueue(tvqueue datastructure.TvQueue, languages []language.Tag) string { + data := RenderData{Data: tvqueue} + data.State.User = r.user + return render(languages, data, "tvqueue") +} + func (r HtmlRenderer) RenderExperiences(experiences datastructure.Experiences, languages []language.Tag) string { data := RenderData{Data: experiences} data.State.User = r.user diff --git a/front/renderer.go b/front/renderer.go index bb4b743bd5b287c25f4e50b395fe47ed12ed76f8..01a3bac20fd7100d29e9badbc41f0e74dd6d54af 100644 --- a/front/renderer.go +++ b/front/renderer.go @@ -29,6 +29,7 @@ RenderAbout([]language.Tag) string RenderErrorPage(int, []language.Tag) string RenderLogin([]language.Tag, error, string) string RenderWatchlist(datastructure.Watchlist, []language.Tag) string + RenderTvQueue(datastructure.TvQueue, []language.Tag) string RenderExperiences(datastructure.Experiences, []language.Tag) string } diff --git a/libamuse/common.go b/libamuse/common.go index ddd1dde94735b8d8668e09291b90603e38d5a8f7..031c57de1d09eb0d685f27d0d11a8171afa04acf 100644 --- a/libamuse/common.go +++ b/libamuse/common.go @@ -5,6 +5,7 @@ "notabug.org/apiote/amuse/accounts" "notabug.org/apiote/amuse/front" "notabug.org/apiote/amuse/tmdb" "notabug.org/apiote/amuse/wikidata" + "notabug.org/apiote/amuse/datastructure" "notabug.org/apiote/amuse/db" "database/sql" @@ -90,6 +91,16 @@ show := result.result.(tmdb.Show) languages := result.languages book, err := wikidata.GetBookByTmdb(data.id, languages[0].String()) show.AddBasedOn(book) + return gott.Tuple(args), err +} + +func getGenres(args ...interface{}) (interface{}, error) { + result := args[1].(*Result) + list := result.result.(datastructure.List) + genres, err := tmdb.GetGenres(result.languages[0].String(), list.GetType()) + list.SetGenres(genres) + result.result = list + return gott.Tuple(args), err } diff --git a/libamuse/tvqueue.go b/libamuse/tvqueue.go new file mode 100644 index 0000000000000000000000000000000000000000..cd0e5913f37efbddac4bdc3eea4ba35e5fec0856 --- /dev/null +++ b/libamuse/tvqueue.go @@ -0,0 +1,55 @@ +package libamuse + +import ( + "notabug.org/apiote/amuse/accounts" + "notabug.org/apiote/amuse/datastructure" + "notabug.org/apiote/amuse/db" + + "notabug.org/apiote/gott" +) + +func getTvQueue(args ...interface{}) (interface{}, error) { + request := args[0].(*RequestData) + result := args[1].(*Result) + page := args[2].(int) + tvQueue, err := db.GetTvQueue(result.user.Username, request.id, page) + result.result = &tvQueue + + return gott.Tuple(args), err +} + +func renderTvQueue(args ...interface{}) interface{} { + request := args[0].(*RequestData) + result := args[1].(*Result) + page := args[2].(int) + tvQueue := result.result.(*datastructure.TvQueue) + tvQueue.Page = page + tvQueue.Query = request.id + result.page = result.renderer.RenderTvQueue(*tvQueue, result.languages) + + return gott.Tuple(args) +} + +func ShowTvQueue(username string, auth accounts.Authentication, languages, mimetype, filter string, page int) (string, error) { + auth.Necessary = true + if page <= 0 { + page = 1 + } + request := &RequestData{id: filter, language: languages, mimetype: mimetype, auth: auth, username: username} + r, err := gott. + NewResult(gott.Tuple{request, &Result{}, page}). + Bind(parseLanguage). + Bind(verifyToken). + Bind(verifyUser). + Bind(getTvQueue). + Bind(getGenres). + Bind(createRenderer). + Map(renderTvQueue). + Finish() + + if err != nil { + return "", err + } else { + return r.(gott.Tuple)[1].(*Result).page, nil + } +} diff --git a/libamuse/watchlist.go b/libamuse/watchlist.go index cd8e9bc9d161e4b80d7958c77a66c0ac0fd9ca52..31eb870d150a2cc732c856e61e1e07b3b507a64e 100644 --- a/libamuse/watchlist.go +++ b/libamuse/watchlist.go @@ -2,7 +2,6 @@ package libamuse import ( "notabug.org/apiote/amuse/accounts" - "notabug.org/apiote/amuse/tmdb" "notabug.org/apiote/amuse/db" "notabug.org/apiote/amuse/datastructure" @@ -14,7 +13,7 @@ request := args[0].(*RequestData) result := args[1].(*Result) page := args[2].(int) watchlist, err := db.GetWatchlist(result.user.Username, request.id, page) - result.result = watchlist + result.result = &watchlist return gott.Tuple(args), err } @@ -23,21 +22,12 @@ func renderWatchlist(args ...interface{}) interface{} { request := args[0].(*RequestData) result := args[1].(*Result) page := args[2].(int) - watchlist := result.result.(datastructure.Watchlist) + watchlist := result.result.(*datastructure.Watchlist) watchlist.Page = page watchlist.Query = request.id - result.page = result.renderer.RenderWatchlist(watchlist, result.languages) + result.page = result.renderer.RenderWatchlist(*watchlist, result.languages) return gott.Tuple(args) -} - -func getGenres(args ...interface{}) (interface{}, error) { - result := args[1].(*Result) - watchlist := result.result.(datastructure.Watchlist) - genres, err := tmdb.GetGenres(result.languages[0].String()) - watchlist.Genres = genres - result.result = watchlist - return gott.Tuple(args), err } func ShowWatchlist(username string, auth accounts.Authentication, languages, mimetype, filter string, page int) (string, error) { diff --git a/router.go b/router.go index d395cf8677d7a01d89895e384a4860e7766f7a65..dbac71c674fb4f2da21e735fbd8666940a9e4ed8 100644 --- a/router.go +++ b/router.go @@ -301,7 +301,12 @@ } func userTvQueue(w http.ResponseWriter, r *http.Request, username string, auth accounts.Authentication, acceptLanguages string, mimetype string) { if r.Method == "" || r.Method == "GET" { - // todo + var page int + r.ParseForm() + filter := r.Form.Get("filter") + fmt.Sscanf(r.Form.Get("page"), "%d", &page) + tvQueue, err := libamuse.ShowTvQueue(username, auth, acceptLanguages, mimetype, filter, page) + render(tvQueue, err, w, acceptLanguages, mimetype) } else if r.Method == "POST" { r.ParseForm() itemId := r.PostForm.Get("itemId") diff --git a/templates/about.html b/templates/about.html index 6a09a2715f9cac8037ee89813c3d170432954f90..77a7f843ff30b430a39b9ea700c37b5fe89c7e49 100644 --- a/templates/about.html +++ b/templates/about.html @@ -27,6 +27,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/book.html b/templates/book.html index 3d78c812a5ca4d79bf1912e0d4f83ea42133c568..ef7e73ae1536248e5bc0426972541c847a49c42a 100644 --- a/templates/book.html +++ b/templates/book.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg-primary align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/bookserie.html b/templates/bookserie.html index 3d0f4f77f025bf8ce0d771e2b043e83b309caf3d..856888c72f6655087e4960760becfe9d52e9d847 100644 --- a/templates/bookserie.html +++ b/templates/bookserie.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg-primary align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/experiences.html b/templates/experiences.html index b5b07dce0f2cbf4aaf298ccc2a3602ab33dd423c..75d865345e148e260d2f8205a5daf007f8a0b789 100644 --- a/templates/experiences.html +++ b/templates/experiences.html @@ -22,6 +22,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/film.html b/templates/film.html index 4c80b2dc6b51490f8d5e6379ab8e618a6e5b1035..400ff9bb786f84f442db4f14c8dd8ff886b5f71e 100644 --- a/templates/film.html +++ b/templates/film.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg-primary align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/index.html b/templates/index.html index b8607a8b13412deef398b82600bc00cdb0761353..4f4a98a3a4db47089728c41f960bbee5822866b8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -27,6 +27,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/person.html b/templates/person.html index 9717f75edfbbf3ecb35b7cedd9f5b0e02618c78f..a847f7e8865f2dfbf7eeb4c0900f0159cf819d06 100644 --- a/templates/person.html +++ b/templates/person.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg-primary align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/search.html b/templates/search.html index b76e40f7a0fc87c6dc3af3bebd88db8b0f7d252f..2051654f261558d87b593a2b70a7e091fc89f09a 100644 --- a/templates/search.html +++ b/templates/search.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/tvqueue.html b/templates/tvqueue.html new file mode 100644 index 0000000000000000000000000000000000000000..6549f900da3a9e2cbdc079c0145ad5ae1ba3e5c5 --- /dev/null +++ b/templates/tvqueue.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{{.State.User.Username}}’s TV queue — a·muse</title> + <link rel="stylesheet" href="/static/style/style.css" /> + <link rel="icon" type="image/svg+xml" href="/static/img/logo.svg"> + <link rel="apple-touch-icon" type="image/svg+xml" href="/static/img/logo.svg"> + </head> + <body> + <header class="w12 padding-bottom-_25 flex flex-row flex-justify-space flex-align-centre"> + <a href="/" class="decoration-none"> + <h1 class="inline valign-mid text sans margin-lr-1">a·muse</h1> + </a> + <div class="margin-lr-1 text"> + <nav> + <label for="hamburger" class="cursor-hand"> + <img src="/users/{{.State.User.Username}}/avatar?size=small" class="border-radius-25 width-1_5"/> + </label> + <input type="checkbox" id="hamburger" class="display-none" /> + <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> + <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> + <li class="bg-error"> + <form action="/users/{{.State.User.Username}}/sessions/{{.State.User.Session}}" method="POST" class="inline"> + <input type="hidden" value="DELETE" name="method" /> + <input type="submit" value="Log out" class="border-none bg-none font-normal text-accent padding-lr-0 cursor-hand font-1" /> + </form><span class="material-icon padding-lr-_5"></span> + </li> + </ul> + </nav> + </div> + </header> + <main class="margin-lr-1"> + <!-- search, filter, order --> + <div class="flex flex-row flex-wrap flex-centre flex-align-start margin-top-1"> + <form method="GET" class="flex inline margin-lr-1 border-bottom"> + <input type="search" name="filter" class="border-none bg-none sans text" placeholder="filter TV queue" value="{{.Data.Query}}" /> + </form> + </div> + <div class="flex flex-row flex-wrap flex-justify-space flex-align-start margin-top-1"> + <div> + {{if gt .Data.Page 1}} + <a href="/users/{{.State.User.Username}}/tvqueue?filter={{.Data.Query}}&page={{.Data.PrevPage}}" class="decoration-none" title="{{.Strings.Search.prev_link_title}}"><span class="material-icon font-2"></span></a> + {{end}} + </div> + <div> + {{if lt .Data.Page .Data.Pages}} + <a href="/users/{{.State.User.Username}}/tvqueue?filter={{.Data.Query}}&page={{.Data.NextPage}}" class="decoration-none" title="{{.Strings.Search.next_link_title}}"><span class="material-icon font-2"></span></a> + {{end}} + </div> + </div> + <div class="flex flex-row flex-wrap flex-justify-space flex-align-start"> + {{range .Data.List}} + <a href="/tvseries/{{.Id}}" class="decoration-none force-width-18 margin-tb-1 no-outline"> + <div class="flex"> + <div> + {{if .Cover}} + <img src="https://image.tmdb.org/t/p/w154{{.Cover}}" class="width-154px{{if .IsUnreleased "tvseries"}} bw{{end}}" /> + {{else}} + <img src="/static/img/tv_empty.webp" class="width-154px" /> + {{end}} + <!-- todo progress --> + </div> + <div class="margin-lr-1"> + <p class="sans">{{.Title}}</p> + <p class="sans font-_875 text-grey">{{.GetYears}}</p> + <p class="sans font-_875"> + {{.GetGenres $.Data.Genres}} + </p> + <p class="sans font-_875 text-grey">Watched episodes: {{.WatchedEpisodes}}</p> + <p class="font-_875 text-grey"> + <!-- todo based on --> + </p> + <!-- todo if last episode < week old then NEW --> + </div> + </div> + </a> + {{end}} + </div> + <div class="flex flex-row flex-wrap flex-justify-space flex-align-start margin-top-1"> + <div> + {{if gt .Data.Page 1}} + <a href="/users/{{.State.User.Username}}/tvqueue?filter={{.Data.Query}}&page={{.Data.PrevPage}}" class="decoration-none" title="{{.Strings.Search.prev_link_title}}"><span class="material-icon font-2"></span></a> + {{end}} + </div> + <div> + {{if lt .Data.Page .Data.Pages}} + <a href="/users/{{.State.User.Username}}/tvqueue?filter={{.Data.Query}}&page={{.Data.NextPage}}" class="decoration-none" title="{{.Strings.Search.next_link_title}}"><span class="material-icon font-2"></span></a> + {{end}} + </div> + </div> + </main> + </body> +</html> diff --git a/templates/tvserie.html b/templates/tvserie.html index 9a93ff9c763a9025c513cd8553cddacb5262df06..103d2befe076409c819d7f63e404d2434f99aab3 100644 --- a/templates/tvserie.html +++ b/templates/tvserie.html @@ -30,6 +30,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg-primary align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> diff --git a/templates/watchlist.html b/templates/watchlist.html index d65dcfae4dc3ffcfe0f6e600c17f9da9bd75089d..09551dc1d3aa446ba9ebb1a1d2056cb9bc869bac 100644 --- a/templates/watchlist.html +++ b/templates/watchlist.html @@ -22,6 +22,7 @@ <ul class="absolute right top-1 padding-lr-1 padding-tb-_5 bg align-right list-style-none sans"> <li><a href="/users/{{.State.User.Username}}" class="decoration-none text-accent">Profile</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/watchlist" class="decoration-none text-accent">Watchlist</a><span class="material-icon padding-lr-_5"></span></li> + <li><a href="/users/{{.State.User.Username}}/tvqueue" class="decoration-none text-accent">TV Queue</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/readlist" class="decoration-none text-accent">Readlist</a><span class="material-icon padding-lr-_5"></span></li> <li><a href="/users/{{.State.User.Username}}/experiences" class="decoration-none text-accent">Experiences</a><span class="material-icon padding-lr-_5"></span></li> <li class="bg-error"> @@ -59,7 +60,7 @@ <div class="flex"> <div> {{if .Cover}} - <img src="https://image.tmdb.org/t/p/w154{{.Cover}}" class="width-154px{{if .IsUnreleased}} bw{{end}}" /> + <img src="https://image.tmdb.org/t/p/w154{{.Cover}}" class="width-154px{{if .IsUnreleased "film"}} bw{{end}}" /> {{else}} <img src="/static/img/poster_empty.webp" class="width-154px" /> {{end}} diff --git a/tmdb/genres.go b/tmdb/genres.go index d2c049e5fc9fe2e8b1a4e360bf326cb9231be43e..5de0e5f0f20b1f481a36b90c6871b1f59e1c2961 100644 --- a/tmdb/genres.go +++ b/tmdb/genres.go @@ -1,9 +1,11 @@ package tmdb import ( + "notabug.org/apiote/amuse/datastructure" "notabug.org/apiote/amuse/network" "encoding/json" + "errors" "net/http" "notabug.org/apiote/gott" @@ -20,7 +22,17 @@ func createGenresRequest(args ...interface{}) (interface{}, error) { request := args[0].(*network.Request) result := args[1].(*network.Result) result.Client = &http.Client{} - httpRequest, err := http.NewRequest("GET", "https://api.themoviedb.org/3/genre/movie/list?api_key="+API_KEY+"&language="+request.Language, nil) + + var itemType string + if request.Id == datastructure.ItemTypeFilm { + itemType = "movie" + } else if request.Id == datastructure.ItemTypeTvserie { + itemType = "tv" + } else { + return gott.Tuple(args), errors.New("Wrong itemType: " + request.Id) + } + + httpRequest, err := http.NewRequest("GET", "https://api.themoviedb.org/3/genre/"+itemType+"/list?api_key="+API_KEY+"&language="+request.Language, nil) result.Request = httpRequest return gott.Tuple(args), err } @@ -37,14 +49,14 @@ genreMap := map[int]string{} for _, genre := range genres.Genres { genreMap[genre.Id] = genre.Name } - + result.Result = genreMap return gott.Tuple(args), nil } -func GetGenres(language string) (map[int]string, error) { +func GetGenres(language string, itemType datastructure.ItemType) (map[int]string, error) { genres, err := gott. - NewResult(gott.Tuple{&network.Request{Language: language}, &network.Result{}}). + NewResult(gott.Tuple{&network.Request{Id: string(itemType), Language: language}, &network.Result{}}). Bind(createGenresRequest). Bind(getCacheEntry). Map(network.AddHeaders). diff --git a/tmdb/serie.go b/tmdb/serie.go index f7841897b85fb0ceab32e85134623e0ad84b5894..c196e66ce9aa4994b63cc563bf33336d5dd576e0 100644 --- a/tmdb/serie.go +++ b/tmdb/serie.go @@ -60,7 +60,7 @@ Last_air_date_str string `json:"last_air_date"` Last_air_date time.Time Last_episode_to_air Episode `json:"last_episode_to_air"` Name string - Number_of_episodes int `json:"number_of_episodes"` + Number_of_episodes int `json:"number_of_episodes"` // todo to item_cache and to calculating Original_name string `json:"original_name"` Overview string Poster_path string `json:"poster_path"`