Publish current app and server
This commit is contained in:
@@ -78,6 +78,46 @@ type RowStat struct {
|
||||
SelectRate float64 `json:"selectRate"`
|
||||
}
|
||||
|
||||
// UserRowStats is the per-profile counterpart to the admin aggregate. It gives the
|
||||
// home composer enough evidence to gently demote shelves that a viewer repeatedly
|
||||
// passes over without turning a couple of accidental focus moves into a preference.
|
||||
func (s *Store) UserRowStats(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
since time.Time,
|
||||
) ([]RowStat, error) {
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT row_id,
|
||||
(array_agg(row_kind ORDER BY occurred_at DESC))[1] AS row_kind,
|
||||
count(*) FILTER (WHERE event = 'impression') AS impressions,
|
||||
count(*) FILTER (WHERE event = 'focus') AS focuses,
|
||||
count(*) FILTER (WHERE event = 'select') AS selects,
|
||||
coalesce(sum(dwell_ms), 0) AS dwell_ms
|
||||
FROM row_events
|
||||
WHERE emby_user_id = $1 AND occurred_at >= $2
|
||||
GROUP BY row_id`, userID, since)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store: user row stats: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
stats := []RowStat{}
|
||||
for rows.Next() {
|
||||
var stat RowStat
|
||||
if err := rows.Scan(
|
||||
&stat.RowID, &stat.RowKind, &stat.Impressions, &stat.Focuses,
|
||||
&stat.Selects, &stat.DwellMs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stat.Viewers = 1
|
||||
if stat.Impressions > 0 {
|
||||
stat.SelectRate = float64(stat.Selects) / float64(stat.Impressions)
|
||||
}
|
||||
stats = append(stats, stat)
|
||||
}
|
||||
return stats, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) InsertRowEvents(ctx context.Context, events []RowEvent) error {
|
||||
if len(events) == 0 {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user