0.3.27 - Omni search fixes, Services in genre browser..
This commit is contained in:
@@ -50,18 +50,45 @@ func (s *Server) handleGenreItems(w http.ResponseWriter, r *http.Request, sess s
|
||||
writeError(w, http.StatusBadRequest, "a genre is required")
|
||||
return
|
||||
}
|
||||
s.handleBrowseItems(w, r, sess, genre)
|
||||
s.handleBrowseItems(w, r, sess, "Genres", "genre", genre)
|
||||
}
|
||||
|
||||
func (s *Server) handleLibraryItems(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
s.handleBrowseItems(w, r, sess, "")
|
||||
s.handleBrowseItems(w, r, sess, "Genres", "genre", "")
|
||||
}
|
||||
|
||||
// handleServiceItems answers the Genres page's Services shortcuts — Apple TV+, Netflix,
|
||||
// Disney+ and the rest of the studio/network catalogue in ui/genre/GenreCategories.kt.
|
||||
//
|
||||
// It is the same shelf as a genre, filtered on a different Emby field: services are
|
||||
// filtered on Studios, which is where a metadata agent (TMDb chief among them) records a
|
||||
// title's production or distribution company — "Netflix", "Apple TV+", "Disney+" are
|
||||
// ordinary studio names to Emby, so no new metadata or import step is needed. Like
|
||||
// genres, the catalogue mapping a service to its Emby spellings is a client-side product
|
||||
// list rather than server data, for the same reason genreCategories() is: the order is a
|
||||
// design decision that must never jump around while home rows are arriving, and a service
|
||||
// with no matching titles simply returns an empty page rather than needing to be hidden
|
||||
// from a central registry.
|
||||
func (s *Server) handleServiceItems(w http.ResponseWriter, r *http.Request, sess store.Session) {
|
||||
service := strings.TrimSpace(r.PathValue("service"))
|
||||
if service == "" {
|
||||
writeError(w, http.StatusBadRequest, "a service is required")
|
||||
return
|
||||
}
|
||||
s.handleBrowseItems(w, r, sess, "Studios", "service", service)
|
||||
}
|
||||
|
||||
func (s *Server) handleBrowseItems(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
sess store.Session,
|
||||
genre string,
|
||||
// filterField is the Emby query parameter the filter value is written into — "Genres"
|
||||
// for a genre shelf, "Studios" for a service shelf. filterLabel is only for the cache
|
||||
// key and the log line, so the two shelves' entries can never collide or be confused
|
||||
// for one another in a shared keyspace.
|
||||
filterField string,
|
||||
filterLabel string,
|
||||
filterValue string,
|
||||
) {
|
||||
ctx := r.Context()
|
||||
limit := queryInt(r, "limit", genrePageSize, genrePageMax)
|
||||
@@ -73,8 +100,8 @@ func (s *Server) handleBrowseItems(
|
||||
}
|
||||
|
||||
filterKey := "all"
|
||||
if genre != "" {
|
||||
filterKey = "genre:" + genre
|
||||
if filterValue != "" {
|
||||
filterKey = filterLabel + ":" + filterValue
|
||||
}
|
||||
key := cache.UserKey(viewerKeyOf(ctx, sess), "browse:"+itemType+":"+filterKey+":"+itoa(offset)+":"+itoa(limit))
|
||||
if raw, err := s.cache.Get(ctx, key); err == nil {
|
||||
@@ -95,8 +122,8 @@ func (s *Server) handleBrowseItems(
|
||||
"SortBy": {"PremiereDate,SortName"},
|
||||
"SortOrder": {"Descending"},
|
||||
}, fieldsRow)
|
||||
if genre != "" {
|
||||
params.Set("Genres", genre)
|
||||
if filterValue != "" {
|
||||
params.Set(filterField, filterValue)
|
||||
}
|
||||
// rowParams turns this off for the home rows, which never page. Here it is the number
|
||||
// the scroll stops on.
|
||||
@@ -115,20 +142,20 @@ func (s *Server) handleBrowseItems(
|
||||
|
||||
total := genreTotal(result.TotalRecordCount, offset, len(items), limit)
|
||||
|
||||
// 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 && genre != "" {
|
||||
s.loggerFor(ctx).Info("genre browsed", "genre", genre, "results", len(items), "total", total)
|
||||
// The first page is somebody opening a genre or a service, which is a navigation event
|
||||
// worth the log; the pages after it are one viewer scrolling and would bury it.
|
||||
if offset == 0 && filterValue != "" {
|
||||
s.loggerFor(ctx).Info(filterLabel+" browsed", filterLabel, filterValue, "results", len(items), "total", total)
|
||||
} 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 if filterValue != "" {
|
||||
s.loggerFor(ctx).Debug(filterLabel+" page", filterLabel, filterValue, "offset", offset, "results", len(items))
|
||||
} else {
|
||||
s.loggerFor(ctx).Debug("library page", "type", itemType, "offset", offset, "results", len(items))
|
||||
}
|
||||
|
||||
body, err := json.Marshal(genrePage{
|
||||
Genre: genre,
|
||||
Genre: filterValue,
|
||||
Items: items,
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
|
||||
Reference in New Issue
Block a user