Release v0.2.36
This commit is contained in:
@@ -139,6 +139,7 @@ func (s *Server) Routes() http.Handler {
|
||||
// A genre is browsed, not searched: the chip is a filter and this is the route that
|
||||
// treats it as one. Paged, because a household's Drama shelf is not a screenful.
|
||||
v1.Handle("GET /v1/genres/{genre}/items", s.authed(s.handleGenreItems))
|
||||
v1.Handle("GET /v1/library/items", s.authed(s.handleLibraryItems))
|
||||
v1.Handle("GET /v1/search/history", s.authed(s.handleRecentSearches))
|
||||
v1.Handle("POST /v1/search/history", s.authed(s.handleSearchHistory))
|
||||
v1.Handle("GET /v1/requests/lookup", s.authed(s.handleRequestLookup))
|
||||
|
||||
@@ -45,21 +45,38 @@ type genrePage struct {
|
||||
}
|
||||
|
||||
func (s *Server) handleGenreItems(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
ctx := r.Context()
|
||||
genre := strings.TrimSpace(r.PathValue("genre"))
|
||||
if genre == "" {
|
||||
writeError(w, http.StatusBadRequest, "a genre is required")
|
||||
return
|
||||
}
|
||||
s.handleBrowseItems(w, r, sess, genre)
|
||||
}
|
||||
|
||||
func (s *Server) handleLibraryItems(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
s.handleBrowseItems(w, r, sess, "")
|
||||
}
|
||||
|
||||
func (s *Server) handleBrowseItems(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
sess store.Session,
|
||||
genre string,
|
||||
) {
|
||||
ctx := r.Context()
|
||||
limit := queryInt(r, "limit", genrePageSize, genrePageMax)
|
||||
offset := queryOffset(r, "offset")
|
||||
itemType, ok := genreItemType(r.URL.Query().Get("type"))
|
||||
if !ok {
|
||||
if !ok || (genre == "" && itemType == "Movie,Series") {
|
||||
writeError(w, http.StatusBadRequest, "type must be Movie or Series")
|
||||
return
|
||||
}
|
||||
|
||||
key := cache.UserKey(sess.EmbyUserID, "genre:"+itemType+":"+genre+":"+itoa(offset)+":"+itoa(limit))
|
||||
filterKey := "all"
|
||||
if genre != "" {
|
||||
filterKey = "genre:" + genre
|
||||
}
|
||||
key := cache.UserKey(sess.EmbyUserID, "browse:"+itemType+":"+filterKey+":"+itoa(offset)+":"+itoa(limit))
|
||||
if raw, err := s.cache.Get(ctx, key); err == nil {
|
||||
w.Header().Set("X-Memby-Cache", "hit")
|
||||
writeRaw(w, http.StatusOK, raw)
|
||||
@@ -67,7 +84,6 @@ func (s *Server) handleGenreItems(w http.ResponseWriter, r *http.Request, sess s
|
||||
}
|
||||
|
||||
params := rowParams(url.Values{
|
||||
"Genres": {genre},
|
||||
"IncludeItemTypes": {itemType},
|
||||
"Recursive": {"true"},
|
||||
"StartIndex": {itoa(offset)},
|
||||
@@ -79,6 +95,9 @@ func (s *Server) handleGenreItems(w http.ResponseWriter, r *http.Request, sess s
|
||||
"SortBy": {"PremiereDate,SortName"},
|
||||
"SortOrder": {"Descending"},
|
||||
}, fieldsRow)
|
||||
if genre != "" {
|
||||
params.Set("Genres", genre)
|
||||
}
|
||||
// rowParams turns this off for the home rows, which never page. Here it is the number
|
||||
// the scroll stops on.
|
||||
params.Set("EnableTotalRecordCount", "true")
|
||||
@@ -98,10 +117,14 @@ func (s *Server) handleGenreItems(w http.ResponseWriter, r *http.Request, sess s
|
||||
|
||||
// The first page is somebody opening a genre, which is a navigation event worth the
|
||||
// log; the pages after it are one viewer scrolling and would bury it.
|
||||
if offset == 0 {
|
||||
if offset == 0 && genre != "" {
|
||||
s.loggerFor(ctx).Info("genre browsed", "genre", genre, "results", len(items), "total", total)
|
||||
} else {
|
||||
} else if offset == 0 {
|
||||
s.loggerFor(ctx).Info("library browsed", "type", itemType, "results", len(items), "total", total)
|
||||
} else if genre != "" {
|
||||
s.loggerFor(ctx).Debug("genre page", "genre", genre, "offset", offset, "results", len(items))
|
||||
} else {
|
||||
s.loggerFor(ctx).Debug("library page", "type", itemType, "offset", offset, "results", len(items))
|
||||
}
|
||||
|
||||
body, err := json.Marshal(genrePage{
|
||||
|
||||
@@ -137,7 +137,7 @@ func componentFor(path string) string {
|
||||
return "settings"
|
||||
case path == "/v1/screensaver", path == "/v1/preroll":
|
||||
return "screensaver"
|
||||
case strings.HasPrefix(path, "/v1/search"), strings.HasPrefix(path, "/v1/genres/"):
|
||||
case strings.HasPrefix(path, "/v1/search"), strings.HasPrefix(path, "/v1/genres/"), path == "/v1/library/items":
|
||||
return "search"
|
||||
case strings.HasPrefix(path, "/v1/requests"):
|
||||
return "requests"
|
||||
|
||||
@@ -43,6 +43,7 @@ func TestComponentNamesThePartOfTheAppARouteBelongsTo(t *testing.T) {
|
||||
"/v1/auth/devices/tv-1": "devices",
|
||||
"/v1/search": "search",
|
||||
"/v1/genres/Comedy/items": "search",
|
||||
"/v1/library/items": "search",
|
||||
"/v1/items/42": "details",
|
||||
"/v1/items/42/related": "details",
|
||||
"/v1/items/42/playback": "playback",
|
||||
|
||||
Reference in New Issue
Block a user