92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from sqlalchemy import CursorResult, select, tuple_, update
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.db.models import ScholarProfile, ScholarPublication
|
|
|
|
|
|
def _normalized_selection_pairs(selections: list[tuple[int, int]]) -> set[tuple[int, int]]:
|
|
pairs: set[tuple[int, int]] = set()
|
|
for scholar_profile_id, publication_id in selections:
|
|
normalized = (int(scholar_profile_id), int(publication_id))
|
|
if normalized[0] <= 0 or normalized[1] <= 0:
|
|
continue
|
|
pairs.add(normalized)
|
|
return pairs
|
|
|
|
|
|
def _scoped_scholar_ids_query(*, user_id: int):
|
|
return select(ScholarProfile.id).where(ScholarProfile.user_id == user_id).scalar_subquery()
|
|
|
|
|
|
async def mark_all_unread_as_read_for_user(
|
|
db_session: AsyncSession,
|
|
*,
|
|
user_id: int,
|
|
) -> int:
|
|
scholar_ids = _scoped_scholar_ids_query(user_id=user_id)
|
|
stmt = (
|
|
update(ScholarPublication)
|
|
.where(
|
|
ScholarPublication.scholar_profile_id.in_(scholar_ids),
|
|
ScholarPublication.is_read.is_(False),
|
|
)
|
|
.values(is_read=True)
|
|
)
|
|
result: CursorResult[Any] = await db_session.execute(stmt) # type: ignore[assignment]
|
|
await db_session.commit()
|
|
return int(result.rowcount or 0)
|
|
|
|
|
|
async def mark_selected_as_read_for_user(
|
|
db_session: AsyncSession,
|
|
*,
|
|
user_id: int,
|
|
selections: list[tuple[int, int]],
|
|
) -> int:
|
|
normalized_pairs = _normalized_selection_pairs(selections)
|
|
if not normalized_pairs:
|
|
return 0
|
|
|
|
scholar_ids = _scoped_scholar_ids_query(user_id=user_id)
|
|
stmt = (
|
|
update(ScholarPublication)
|
|
.where(
|
|
ScholarPublication.scholar_profile_id.in_(scholar_ids),
|
|
tuple_(
|
|
ScholarPublication.scholar_profile_id,
|
|
ScholarPublication.publication_id,
|
|
).in_(list(normalized_pairs)),
|
|
ScholarPublication.is_read.is_(False),
|
|
)
|
|
.values(is_read=True)
|
|
)
|
|
result: CursorResult[Any] = await db_session.execute(stmt) # type: ignore[assignment]
|
|
await db_session.commit()
|
|
return int(result.rowcount or 0)
|
|
|
|
|
|
async def set_publication_favorite_for_user(
|
|
db_session: AsyncSession,
|
|
*,
|
|
user_id: int,
|
|
scholar_profile_id: int,
|
|
publication_id: int,
|
|
is_favorite: bool,
|
|
) -> int:
|
|
scholar_ids = _scoped_scholar_ids_query(user_id=user_id)
|
|
stmt = (
|
|
update(ScholarPublication)
|
|
.where(
|
|
ScholarPublication.scholar_profile_id.in_(scholar_ids),
|
|
ScholarPublication.scholar_profile_id == int(scholar_profile_id),
|
|
ScholarPublication.publication_id == int(publication_id),
|
|
)
|
|
.values(is_favorite=bool(is_favorite))
|
|
)
|
|
result: CursorResult[Any] = await db_session.execute(stmt) # type: ignore[assignment]
|
|
await db_session.commit()
|
|
return int(result.rowcount or 0)
|