add imdb full import mode

This commit is contained in:
ducklet 2021-06-21 18:54:03 +02:00
parent b5cb22822e
commit 7dd10f8bc3
17 changed files with 721 additions and 109 deletions

View file

@ -1,11 +1,42 @@
from collections import defaultdict
import base64
import binascii
from starlette.applications import Starlette
from starlette.authentication import (
AuthCredentials,
AuthenticationBackend,
AuthenticationError,
SimpleUser,
UnauthenticatedUser,
requires,
)
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.responses import JSONResponse
from starlette.routing import Route
from starlette.routing import Mount, Route
from . import config
from . import config, db
from .db import close_connection_pool, find_ratings, open_connection_pool
from .models import Movie, asplain
class BasicAuthBackend(AuthenticationBackend):
async def authenticate(self, request):
if "Authorization" not in request.headers:
return
auth = request.headers["Authorization"]
try:
scheme, credentials = auth.split()
if scheme.lower() != "basic":
return
decoded = base64.b64decode(credentials).decode("ascii")
except (ValueError, UnicodeDecodeError, binascii.Error) as exc:
raise AuthenticationError("Invalid basic auth credentials")
username, _, password = decoded.partition(":")
# TODO: You'd want to verify the username and password here.
return AuthCredentials(["authenticated"]), SimpleUser(username)
def imdb_url(imdb_id: str):
@ -29,7 +60,8 @@ async def ratings(request):
mov = aggr.setdefault(
r["movie_imdb_id"],
{
"title": r["movie_title"],
"canonical_title": r["canonical_title"],
"original_title": r["original_title"],
"year": r["release_year"],
"link": imdb_url(r["movie_imdb_id"]),
"user_scores": [],
@ -44,10 +76,69 @@ async def ratings(request):
return JSONResponse(resp)
not_found = JSONResponse({"error": "Not Found"}, status_code=404)
async def get_movies(request):
imdb_id = request.query_params.get("imdb_id")
movie = await db.get(Movie, imdb_id=imdb_id)
resp = [asplain(movie)] if movie else []
return JSONResponse(resp)
@requires(["authenticated", "admin"])
async def add_movie(request):
pass
@requires(["authenticated", "admin"])
async def add_user(request):
pass
async def ratings_for_user(request):
request.path_params["user_id"]
@requires("authenticated")
async def set_rating_for_user(request):
request.path_params["user_id"]
@requires(["authenticated", "admin"])
async def add_group(request):
pass
@requires(["authenticated", "admin"])
async def add_user_to_group(request):
request.path_params["group_id"]
async def get_ratings_for_group(request):
request.path_params["group_id"]
app = Starlette(
on_startup=[open_connection_pool],
on_shutdown=[close_connection_pool],
routes=[
Route("/ratings", ratings),
Mount(
"/api/v1",
routes=[
Route("/ratings", ratings), # XXX legacy, remove.
Route("/movies", get_movies),
Route("/movies", add_movie, methods=["POST"]),
Route("/users", add_user, methods=["POST"]),
Route("/users/{user_id}/ratings", ratings_for_user),
Route("/users/{user_id}/ratings", set_rating_for_user, methods=["PUT"]),
Route("/groups", add_group, methods=["POST"]),
Route("/groups/{group_id}/users", add_user_to_group, methods=["POST"]),
Route("/groups/{group_id}/ratings", get_ratings_for_group),
],
),
],
middleware=[Middleware(AuthenticationMiddleware, backend=BasicAuthBackend())],
)