0.3.22 - PINs
This commit is contained in:
@@ -41,7 +41,10 @@ const (
|
||||
fieldsDetail = "Overview,Taglines,Genres,MediaStreams,People,Studios,ProductionYear,PremiereDate,OriginalTitle,ProductionLocations,OfficialRating,CommunityRating,RunTimeTicks,SeriesId,SeriesName,Status,ProviderIds,ParentIndexNumber,IndexNumber,PrimaryImageAspectRatio,CollectionName"
|
||||
fieldsScreensaver = "Overview,Taglines,Genres,ProductionYear,CommunityRating,Studios,OfficialRating,RunTimeTicks"
|
||||
|
||||
rowImageTypes = "Backdrop,Primary,Logo"
|
||||
// Thumb rides every row, not only Continue Watching's: rowParams is the one query
|
||||
// shape every row shares, and Emby only reports ParentThumbItemId/ParentThumbImageTag
|
||||
// on an item when Thumb is among the requested types.
|
||||
rowImageTypes = "Backdrop,Primary,Logo,Thumb"
|
||||
screensaverImageTypes = "Backdrop,Logo"
|
||||
)
|
||||
|
||||
@@ -90,6 +93,11 @@ func (s *Server) handleHome(w http.ResponseWriter, r *http.Request, sess store.S
|
||||
continueDefinition,
|
||||
ProtocolVersion,
|
||||
).Enabled
|
||||
// The For You window is the viewer's own device clock, not the household's: the
|
||||
// greeting above this row already draws from the TV's local time, and a gateway
|
||||
// hosted (or configured) in a different zone must not tell somebody "Good morning"
|
||||
// while leading with "Late-night picks for you". See clientLocalNow.
|
||||
forYouWindow := homeForYouWindowAt(clientLocalNow(r, now.In(s.householdLocation())))
|
||||
// The hero revision is part of the key rather than something to invalidate. An
|
||||
// operator's change therefore makes the entries built under the old policy simply
|
||||
// unreachable, and they age out on their own TTL — where the sweep it replaced dropped
|
||||
@@ -102,7 +110,7 @@ func (s *Server) handleHome(w http.ResponseWriter, r *http.Request, sess store.S
|
||||
":r"+strconv.FormatBool(radarrSchedule)+":h"+strconv.FormatBool(hero)+
|
||||
":c"+strconv.FormatBool(continueWatching)+
|
||||
":f"+strconv.FormatInt(featurePolicy.Revision, 10)+
|
||||
":hr"+heroRev+":d"+sess.DeviceID,
|
||||
":hr"+heroRev+":w"+forYouWindow.ID+":d"+sess.DeviceID,
|
||||
)
|
||||
|
||||
if raw, err := s.cache.Get(ctx, key); err == nil {
|
||||
@@ -298,9 +306,7 @@ func (s *Server) handleHome(w http.ResponseWriter, r *http.Request, sess store.S
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
location := s.householdLocation()
|
||||
window := homeForYouWindowAt(time.Now().In(location))
|
||||
prepared, hit, stale, err := s.forYou.PreparedRows(ctx, sess, window.Minutes)
|
||||
prepared, hit, stale, err := s.forYou.PreparedRows(ctx, sess, forYouWindow.Minutes)
|
||||
if err != nil {
|
||||
s.loggerFor(ctx).Warn("prepared Home For You row failed", "user", sess.EmbyUserID, "error", err)
|
||||
return
|
||||
@@ -308,7 +314,7 @@ func (s *Server) handleHome(w http.ResponseWriter, r *http.Request, sess store.S
|
||||
if !hit || len(prepared) == 0 {
|
||||
return
|
||||
}
|
||||
homeRows := preparedHomeForYouRows(prepared, window)
|
||||
homeRows := preparedHomeForYouRows(prepared, forYouWindow)
|
||||
if len(homeRows) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -850,6 +856,42 @@ type homeForYouWindow struct {
|
||||
Minutes int
|
||||
}
|
||||
|
||||
// clientLocalHourHeader carries the viewer's own device clock, in hours, on every request.
|
||||
// It exists so a time-sensitive row can agree with the greeting drawn above it: the
|
||||
// greeting is the TV's own local time, and a household's configured timezone (or the
|
||||
// gateway's host clock, when none is set) is a different fact that happens to usually
|
||||
// agree with it — usually, not always, and the times it disagrees are exactly what "Good
|
||||
// morning" beside "Late-night picks for you" looks like.
|
||||
const clientLocalHourHeader = "X-Memby-Local-Hour"
|
||||
|
||||
// clientLocalNow substitutes the client's reported hour into householdFallback, so an
|
||||
// older client (or one that failed to send the header) still gets an answer — the
|
||||
// household's own idea of the time, which is what this row used before there was
|
||||
// anything to disagree with it.
|
||||
func clientLocalNow(r *http.Request, householdFallback time.Time) time.Time {
|
||||
hour, ok := parseClientLocalHour(r.Header.Get(clientLocalHourHeader))
|
||||
if !ok {
|
||||
return householdFallback
|
||||
}
|
||||
return time.Date(
|
||||
householdFallback.Year(), householdFallback.Month(), householdFallback.Day(),
|
||||
hour, householdFallback.Minute(), householdFallback.Second(), 0,
|
||||
householdFallback.Location(),
|
||||
)
|
||||
}
|
||||
|
||||
func parseClientLocalHour(value string) (int, bool) {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return 0, false
|
||||
}
|
||||
hour, err := strconv.Atoi(value)
|
||||
if err != nil || hour < 0 || hour > 23 {
|
||||
return 0, false
|
||||
}
|
||||
return hour, true
|
||||
}
|
||||
|
||||
// homeForYouWindowAt keeps Home useful without asking the viewer for a duration.
|
||||
// These deliberately broad windows suit a household TV: short before lunch, an
|
||||
// episode-sized pick in the afternoon/late evening, and film headroom at night.
|
||||
|
||||
Reference in New Issue
Block a user