allow loading group ratings for a single movie

This commit is contained in:
ducklet 2022-01-13 23:18:09 +01:00
parent adfead81fc
commit 23bba3e2cc
2 changed files with 48 additions and 14 deletions

View file

@ -4,7 +4,7 @@ import logging
import re import re
import threading import threading
from pathlib import Path from pathlib import Path
from typing import Iterable, Literal, Optional, Type, TypeVar, Union from typing import Any, Iterable, Literal, Optional, Type, TypeVar, Union
import sqlalchemy import sqlalchemy
from databases import Database from databases import Database
@ -487,7 +487,28 @@ async def find_ratings(
) )
movie_ids += tuple(r["movie_id"] for r in rows) movie_ids += tuple(r["movie_id"] for r in rows)
sqlin, sqlin_vals = sql_in(f"{Movie._table}.id", movie_ids) return await ratings_for_movie_ids(ids=movie_ids)
async def ratings_for_movie_ids(
ids: Iterable[ULID | str] = [], imdb_ids: Iterable[str] = []
) -> Iterable[dict[str, Any]]:
conds: list[str] = []
vals: dict[str, str] = {}
if ids:
sqlin, sqlin_vals = sql_in(f"{Movie._table}.id", (str(x) for x in ids))
conds.append(sqlin)
vals.update(sqlin_vals)
if imdb_ids:
sqlin, sqlin_vals = sql_in(f"{Movie._table}.imdb_id", imdb_ids)
conds.append(sqlin)
vals.update(sqlin_vals)
if not conds:
return []
query = f""" query = f"""
SELECT SELECT
{Rating._table}.score AS user_score, {Rating._table}.score AS user_score,
@ -501,11 +522,11 @@ async def find_ratings(
{Movie._table}.release_year AS release_year {Movie._table}.release_year AS release_year
FROM {Movie._table} FROM {Movie._table}
LEFT JOIN {Rating._table} ON {Movie._table}.id={Rating._table}.movie_id LEFT JOIN {Rating._table} ON {Movie._table}.id={Rating._table}.movie_id
WHERE {sqlin} WHERE {(' OR '.join(conds))}
""" """
async with locked_connection() as conn: async with locked_connection() as conn:
rows = await conn.fetch_all(bindparams(query, {**values, **sqlin_vals})) rows = await conn.fetch_all(bindparams(query, vals))
return tuple(dict(r) for r in rows) return tuple(dict(r) for r in rows)

View file

@ -200,16 +200,29 @@ async def get_ratings_for_group(request):
user_ids = {u["id"] for u in group.users} user_ids = {u["id"] for u in group.users}
params = request.query_params params = request.query_params
rows = await find_ratings(
title=params.get("title"), imdb_id: str | None = params.get("imdb_id")
media_type=params.get("media_type"), unwind_id: str | None = params.get("unwind_id")
exact=truthy(params.get("exact")),
ignore_tv_episodes=truthy(params.get("ignore_tv_episodes")), # if (imdb_id or unwind_id) and (movie := await db.get(Movie, id=unwind_id, imdb_id=imdb_id)):
include_unrated=truthy(params.get("include_unrated")), if unwind_id:
yearcomp=yearcomp(params["year"]) if "year" in params else None, rows = await db.ratings_for_movie_ids(ids=[unwind_id])
limit_rows=as_int(params.get("per_page"), max=10, default=5),
user_ids=user_ids, elif imdb_id:
) rows = await db.ratings_for_movie_ids(imdb_ids=[imdb_id])
else:
rows = await find_ratings(
title=params.get("title"),
media_type=params.get("media_type"),
exact=truthy(params.get("exact")),
ignore_tv_episodes=truthy(params.get("ignore_tv_episodes")),
include_unrated=truthy(params.get("include_unrated")),
yearcomp=yearcomp(params["year"]) if "year" in params else None,
limit_rows=as_int(params.get("per_page"), max=10, default=5),
user_ids=user_ids,
)
ratings = (web_models.Rating(**r) for r in rows) ratings = (web_models.Rating(**r) for r in rows)
aggr = web_models.aggregate_ratings(ratings, user_ids) aggr = web_models.aggregate_ratings(ratings, user_ids)