Improve playback, preroll and TV experience
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/ponzischeme89/memby/server/internal/cache"
|
||||
"github.com/ponzischeme89/memby/server/internal/store"
|
||||
)
|
||||
|
||||
type personFilmographyResponse struct {
|
||||
Items []json.RawMessage `json:"items"`
|
||||
}
|
||||
|
||||
// handlePerson returns Emby's person item. PremiereDate and EndDate are the person's
|
||||
// birth and death dates; Overview is their biography.
|
||||
func (s *Server) handlePerson(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
ctx := r.Context()
|
||||
personID := r.PathValue("id")
|
||||
if personID == "" {
|
||||
writeError(w, http.StatusBadRequest, "person id is required")
|
||||
return
|
||||
}
|
||||
key := cache.UserKey(sess.EmbyUserID, "person:v1:"+personID)
|
||||
if raw, err := s.cache.Get(ctx, key); err == nil {
|
||||
w.Header().Set("X-Memby-Cache", "hit")
|
||||
writeRaw(w, http.StatusOK, raw)
|
||||
return
|
||||
}
|
||||
person, err := s.emby.Item(
|
||||
ctx,
|
||||
credentials(sess),
|
||||
personID,
|
||||
"Overview,Genres,PrimaryImageAspectRatio",
|
||||
)
|
||||
if err != nil {
|
||||
s.writeUpstreamError(ctx, w, err, "could not load the person")
|
||||
return
|
||||
}
|
||||
if err := s.cache.Set(ctx, key, person, s.cfg.ItemTTL); err != nil {
|
||||
s.loggerFor(ctx).Warn("person cache write failed", "error", err)
|
||||
}
|
||||
w.Header().Set("X-Memby-Cache", "miss")
|
||||
writeRaw(w, http.StatusOK, person)
|
||||
}
|
||||
|
||||
// Filmography is kept separate from the biography so life dates can decorate the cast
|
||||
// row without also loading every cast member's credits.
|
||||
func (s *Server) handlePersonFilmography(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
ctx := r.Context()
|
||||
personID := r.PathValue("id")
|
||||
if personID == "" {
|
||||
writeError(w, http.StatusBadRequest, "person id is required")
|
||||
return
|
||||
}
|
||||
key := cache.UserKey(sess.EmbyUserID, "person-filmography:v1:"+personID)
|
||||
if raw, err := s.cache.Get(ctx, key); err == nil {
|
||||
w.Header().Set("X-Memby-Cache", "hit")
|
||||
writeRaw(w, http.StatusOK, raw)
|
||||
return
|
||||
}
|
||||
result, err := s.emby.Items(ctx, credentials(sess), url.Values{
|
||||
"PersonIds": {personID},
|
||||
"IncludeItemTypes": {"Movie,Series"},
|
||||
"Recursive": {"true"},
|
||||
"SortBy": {"ProductionYear,SortName"},
|
||||
"SortOrder": {"Descending"},
|
||||
"Limit": {"60"},
|
||||
"Fields": {"Overview,ProductionYear,PrimaryImageAspectRatio"},
|
||||
"EnableImages": {"true"},
|
||||
"EnableImageTypes": {"Primary"},
|
||||
"ImageTypeLimit": {"1"},
|
||||
"EnableUserData": {"true"},
|
||||
})
|
||||
if err != nil {
|
||||
s.writeUpstreamError(ctx, w, err, "could not load the person's filmography")
|
||||
return
|
||||
}
|
||||
items := result.Items
|
||||
if items == nil {
|
||||
items = []json.RawMessage{}
|
||||
}
|
||||
body, err := json.Marshal(personFilmographyResponse{Items: items})
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "could not encode the filmography")
|
||||
return
|
||||
}
|
||||
if err := s.cache.Set(ctx, key, body, s.cfg.ItemTTL); err != nil {
|
||||
s.loggerFor(ctx).Warn("person filmography cache write failed", "error", err)
|
||||
}
|
||||
w.Header().Set("X-Memby-Cache", "miss")
|
||||
writeRaw(w, http.StatusOK, body)
|
||||
}
|
||||
Reference in New Issue
Block a user