Merge pull request #38 from markbeep/36-fr-auto-download-prefer-or-set-score-for-preferred-file-type

add title attribute to show who requested a book
This commit is contained in:
Mark
2025-03-12 08:41:25 +01:00
committed by GitHub
4 changed files with 35 additions and 18 deletions
+5 -1
View File
@@ -72,9 +72,13 @@ class BookSearchResult(BaseBook):
class BookWishlistResult(BaseBook):
amount_requested: int = 0
requested_by: list[str] = []
download_error: Optional[str] = None
@property
def amount_requested(self):
return len(self.requested_by)
class BookRequest(BaseBook, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
+20 -11
View File
@@ -1,3 +1,4 @@
from collections import defaultdict
import uuid
from typing import Annotated, Literal, Optional
@@ -12,7 +13,6 @@ from fastapi import (
Response,
)
from fastapi.responses import RedirectResponse
from sqlalchemy import func
from sqlmodel import Session, col, select
from app.internal.models import (
@@ -41,23 +41,32 @@ def get_wishlist_books(
username: Optional[str] = None,
response_type: Literal["all", "downloaded", "not_downloaded"] = "all",
) -> list[BookWishlistResult]:
query = select(
BookRequest, func.count(col(BookRequest.user_username)).label("count")
)
"""
Gets the books that have been requested. If a username is given only the books requested by that
user are returned. If no username is given, all book requests are returned.
"""
if username:
query = query.where(BookRequest.user_username == username)
query = select(BookRequest).where(BookRequest.user_username == username)
else:
query = query.where(col(BookRequest.user_username).is_not(None))
query = select(BookRequest).where(col(BookRequest.user_username).is_not(None))
book_requests = session.exec(
query.select_from(BookRequest).group_by(BookRequest.asin)
).all()
book_requests = session.exec(query).all()
# group by asin and aggregate all usernames
usernames: dict[str, list[str]] = defaultdict(list)
distinct_books: dict[str, BookRequest] = {}
for book in book_requests:
if book.asin not in distinct_books:
distinct_books[book.asin] = book
if book.user_username:
usernames[book.asin].append(book.user_username)
# add information of what users requested the book
books: list[BookWishlistResult] = []
downloaded: list[BookWishlistResult] = []
for book, count in book_requests:
for asin, book in distinct_books.items():
b = BookWishlistResult.model_validate(book)
b.amount_requested = count
b.requested_by = usernames[asin]
if b.downloaded:
downloaded.append(b)
else:
+7 -5
View File
@@ -9,7 +9,7 @@ from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
from fastapi import Depends, HTTPException, Request, status
from fastapi.security import HTTPBasic, OAuth2PasswordBearer
from sqlmodel import Session
from sqlmodel import Session, select
from app.internal.models import GroupEnum, User
from app.util.cache import StringConfigCache
@@ -164,7 +164,7 @@ def get_authenticated_user(lowest_allowed_group: GroupEnum = GroupEnum.untrusted
if login_type == LoginTypeEnum.forms:
user = await _get_forms_auth(request, session)
elif login_type == LoginTypeEnum.none:
user = await _get_none_auth()
user = await _get_none_auth(session)
else:
user = await _get_basic_auth(request, session)
@@ -237,6 +237,8 @@ async def _get_forms_auth(
return user
async def _get_none_auth() -> User:
"""Treats every request as being root / turns off authentication"""
return User(username="no-login", password="", group=GroupEnum.admin, root=True)
async def _get_none_auth(session: Session) -> User:
"""Treats every request as being root by returning the first admin user"""
return session.exec(
select(User).where(User.group == GroupEnum.admin).limit(1)
).one()
+3 -1
View File
@@ -78,7 +78,9 @@
</td>
<td class="lg:hidden">{{ book.release_date.strftime("%Y") }}</td>
<td>{{ book.runtime_length_hrs }}</td>
<td>{{ book.amount_requested }}</td>
<td title="{{ book.requested_by|join('\n') }}">
{{ book.amount_requested }}
</td>
<td class="grid grid-cols-2 min-w-[8rem] gap-1">
<!--prettier-ignore -->