Files
reddit-bot/backend/services/author_service.py
dat972 bc2203524f Add Reddit monitoring bot — backend, frontend, and Docker config
Python/FastAPI backend with PostgreSQL for collecting Reddit data via
public .json endpoints. React/Vite dashboard for analytics. Docker Compose
setup with API and worker services connecting to shared PostgreSQL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 19:29:58 -05:00

80 lines
2.6 KiB
Python

from datetime import datetime
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from backend.models.author import Author
from backend.models.post import Post
from backend.models.comment import Comment
async def list_authors(
db: AsyncSession,
subreddit_id: int | None = None,
sort_by: str = "total_comments",
sort_order: str = "desc",
since: datetime | None = None,
until: datetime | None = None,
page: int = 1,
per_page: int = 25,
) -> tuple[list[dict], int]:
base = select(Author)
if subreddit_id or since or until:
# Need to compute activity counts with filters
post_count = (
select(func.count(Post.id))
.where(Post.author_id == Author.id)
)
comment_count = (
select(func.count(Comment.id))
.where(Comment.author_id == Author.id)
)
if subreddit_id:
post_count = post_count.where(Post.subreddit_id == subreddit_id)
comment_count = comment_count.join(Post).where(Post.subreddit_id == subreddit_id)
if since:
post_count = post_count.where(Post.created_utc >= since)
comment_count = comment_count.where(Comment.created_utc >= since)
if until:
post_count = post_count.where(Post.created_utc <= until)
comment_count = comment_count.where(Comment.created_utc <= until)
base = select(
Author,
post_count.correlate(Author).scalar_subquery().label("filtered_posts"),
comment_count.correlate(Author).scalar_subquery().label("filtered_comments"),
)
else:
base = select(Author)
count_stmt = select(func.count()).select_from(base.subquery())
total = (await db.execute(count_stmt)).scalar() or 0
sort_col = getattr(Author, sort_by, Author.total_comments)
if sort_order == "asc":
base = base.order_by(sort_col.asc())
else:
base = base.order_by(sort_col.desc())
base = base.offset((page - 1) * per_page).limit(per_page)
result = await db.execute(base)
authors = []
for row in result.all():
if isinstance(row, tuple):
author = row[0]
else:
author = row
data = {c.name: getattr(author, c.name) for c in author.__table__.columns}
authors.append(data)
return authors, total
async def get_author(db: AsyncSession, author_id: int) -> dict | None:
author = await db.get(Author, author_id)
if not author:
return None
return {c.name: getattr(author, c.name) for c in author.__table__.columns}