updated users page to calculate post data correctly
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import select, func
|
from sqlalchemy import select, func, desc as sa_desc, asc as sa_asc, literal
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from backend.models.author import Author
|
from backend.models.author import Author
|
||||||
@@ -17,60 +17,75 @@ async def list_authors(
|
|||||||
page: int = 1,
|
page: int = 1,
|
||||||
per_page: int = 25,
|
per_page: int = 25,
|
||||||
) -> tuple[list[dict], int]:
|
) -> tuple[list[dict], int]:
|
||||||
base = select(Author)
|
# Always compute counts from actual data
|
||||||
|
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 or since or until:
|
if subreddit_id:
|
||||||
# Need to compute activity counts with filters
|
post_count = post_count.where(Post.subreddit_id == subreddit_id)
|
||||||
post_count = (
|
comment_count = comment_count.join(Post).where(Post.subreddit_id == subreddit_id)
|
||||||
select(func.count(Post.id))
|
if since:
|
||||||
.where(Post.author_id == Author.id)
|
post_count = post_count.where(Post.created_utc >= since)
|
||||||
)
|
comment_count = comment_count.where(Comment.created_utc >= since)
|
||||||
comment_count = (
|
if until:
|
||||||
select(func.count(Comment.id))
|
post_count = post_count.where(Post.created_utc <= until)
|
||||||
.where(Comment.author_id == Author.id)
|
comment_count = comment_count.where(Comment.created_utc <= until)
|
||||||
)
|
|
||||||
|
|
||||||
if subreddit_id:
|
post_sub = post_count.correlate(Author).scalar_subquery().label("total_posts")
|
||||||
post_count = post_count.where(Post.subreddit_id == subreddit_id)
|
comment_sub = comment_count.correlate(Author).scalar_subquery().label("total_comments")
|
||||||
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(
|
base = select(Author, post_sub, comment_sub)
|
||||||
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())
|
# Only show authors with activity
|
||||||
|
having_activity = base.having(
|
||||||
|
(post_sub > 0) | (comment_sub > 0)
|
||||||
|
).group_by(Author.id)
|
||||||
|
|
||||||
|
# Count total active authors
|
||||||
|
count_stmt = select(func.count()).select_from(having_activity.subquery())
|
||||||
total = (await db.execute(count_stmt)).scalar() or 0
|
total = (await db.execute(count_stmt)).scalar() or 0
|
||||||
|
|
||||||
sort_col = getattr(Author, sort_by, Author.total_comments)
|
# Sort by computed counts
|
||||||
if sort_order == "asc":
|
if sort_by == "total_posts":
|
||||||
base = base.order_by(sort_col.asc())
|
sort_col = post_sub
|
||||||
else:
|
else:
|
||||||
base = base.order_by(sort_col.desc())
|
sort_col = comment_sub
|
||||||
|
|
||||||
base = base.offset((page - 1) * per_page).limit(per_page)
|
order_fn = sa_desc if sort_order == "desc" else sa_asc
|
||||||
|
query = base.order_by(order_fn(sort_col)).offset((page - 1) * per_page).limit(per_page)
|
||||||
|
|
||||||
result = await db.execute(base)
|
result = await db.execute(query)
|
||||||
authors = []
|
authors = []
|
||||||
for row in result.all():
|
for row in result.all():
|
||||||
author = row[0]
|
author = row[0]
|
||||||
data = {c.name: getattr(author, c.name) for c in author.__table__.columns}
|
data = {c.name: getattr(author, c.name) for c in author.__table__.columns}
|
||||||
|
data["total_posts"] = row[1] or 0
|
||||||
|
data["total_comments"] = row[2] or 0
|
||||||
authors.append(data)
|
authors.append(data)
|
||||||
|
|
||||||
return authors, total
|
return authors, total
|
||||||
|
|
||||||
|
|
||||||
async def get_author(db: AsyncSession, author_id: int) -> dict | None:
|
async def get_author(db: AsyncSession, author_id: int) -> dict | None:
|
||||||
author = await db.get(Author, author_id)
|
post_count = (
|
||||||
if not author:
|
select(func.count(Post.id))
|
||||||
|
.where(Post.author_id == author_id)
|
||||||
|
.scalar_subquery()
|
||||||
|
)
|
||||||
|
comment_count = (
|
||||||
|
select(func.count(Comment.id))
|
||||||
|
.where(Comment.author_id == author_id)
|
||||||
|
.scalar_subquery()
|
||||||
|
)
|
||||||
|
result = await db.execute(
|
||||||
|
select(Author, post_count.label("total_posts"), comment_count.label("total_comments"))
|
||||||
|
.where(Author.id == author_id)
|
||||||
|
)
|
||||||
|
row = result.first()
|
||||||
|
if not row:
|
||||||
return None
|
return None
|
||||||
return {c.name: getattr(author, c.name) for c in author.__table__.columns}
|
author = row[0]
|
||||||
|
data = {c.name: getattr(author, c.name) for c in author.__table__.columns}
|
||||||
|
data["total_posts"] = row[1] or 0
|
||||||
|
data["total_comments"] = row[2] or 0
|
||||||
|
return data
|
||||||
|
|||||||
Reference in New Issue
Block a user