89 lines
3.2 KiB
Python
Raw Normal View History

2026-05-10 09:08:12 +02:00
import logging
from fastapi import APIRouter, Request
2026-05-11 03:14:43 +02:00
from fastapi.responses import HTMLResponse
2026-05-23 10:54:45 +02:00
from devplacepy.database import get_table, get_daily_topic, get_users_by_uids, get_comment_counts_by_post_uids, get_site_stats, get_top_authors
2026-05-12 15:07:34 +02:00
from devplacepy.attachments import get_attachments_batch
2026-05-23 08:34:13 +02:00
from devplacepy.content import enrich_items
2026-05-10 09:08:12 +02:00
from devplacepy.templating import templates
2026-05-23 08:34:13 +02:00
from devplacepy.utils import get_current_user
2026-05-30 20:16:39 +02:00
from devplacepy.seo import list_page_seo
2026-05-10 09:08:12 +02:00
logger = logging.getLogger(__name__)
router = APIRouter()
2026-05-11 03:14:43 +02:00
PAGE_SIZE = 25
2026-05-10 09:08:12 +02:00
2026-05-11 03:14:43 +02:00
def get_feed_posts(user, tab: str = "all", topic: str = None, before: str = None):
posts_table = get_table("posts")
2026-05-29 00:45:07 +02:00
order = ["-stars", "-created_at"] if tab == "trending" else ["-created_at"]
2026-05-10 09:08:12 +02:00
if tab == "following":
2026-05-12 12:45:52 +02:00
if not user:
return [], None
2026-05-10 09:08:12 +02:00
follows = get_table("follows")
following = [f["following_uid"] for f in follows.find(follower_uid=user["uid"])]
2026-05-11 03:14:43 +02:00
if not following:
return [], None
2026-05-29 00:45:07 +02:00
clauses = [posts_table.table.columns.user_uid.in_(following)]
if before:
clauses.append(posts_table.table.columns.created_at < before)
posts = list(posts_table.find(*clauses, order_by=order, _limit=PAGE_SIZE + 1))
2026-05-11 03:14:43 +02:00
else:
2026-05-29 00:45:07 +02:00
filters = {}
if topic:
filters["topic"] = topic
2026-05-11 03:14:43 +02:00
if before:
2026-05-29 00:45:07 +02:00
filters["created_at"] = {"<": before}
posts = list(posts_table.find(**filters, order_by=order, _limit=PAGE_SIZE + 1))
2026-05-11 03:14:43 +02:00
has_more = len(posts) > PAGE_SIZE
posts = posts[:PAGE_SIZE]
2026-05-29 00:45:07 +02:00
next_cursor = posts[-1]["created_at"] if has_more and posts else None
2026-05-10 09:08:12 +02:00
2026-05-11 03:14:43 +02:00
if not posts:
return [], next_cursor
2026-05-10 09:08:12 +02:00
2026-05-23 08:34:13 +02:00
authors = get_users_by_uids([p["user_uid"] for p in posts])
counts = get_comment_counts_by_post_uids([p["uid"] for p in posts])
2026-05-10 09:08:12 +02:00
2026-05-30 20:16:39 +02:00
result = enrich_items(posts, "post", authors, {"comment_count": counts}, user=user)
2026-05-11 03:14:43 +02:00
return result, next_cursor
2026-05-10 09:08:12 +02:00
@router.get("", response_class=HTMLResponse)
2026-05-11 03:14:43 +02:00
async def feed_page(request: Request, tab: str = "all", topic: str = None, before: str = None):
2026-05-12 12:45:52 +02:00
user = get_current_user(request)
2026-05-11 03:14:43 +02:00
posts, next_cursor = get_feed_posts(user, tab, topic, before)
2026-05-23 06:20:27 +02:00
stats = get_site_stats()
2026-05-23 10:54:45 +02:00
top_authors = get_top_authors(5)
2026-05-11 00:41:41 +02:00
daily_topic = get_daily_topic()
2026-05-10 09:08:12 +02:00
2026-05-12 15:07:34 +02:00
post_uids_list = [item["post"]["uid"] for item in posts]
attachments_map = get_attachments_batch("post", post_uids_list)
for item in posts:
item["attachments"] = attachments_map.get(item["post"]["uid"], [])
2026-05-30 20:16:39 +02:00
seo_ctx = list_page_seo(
2026-05-11 05:30:51 +02:00
request,
title="Feed",
description="Discover the latest developer discussions, projects, and community activity on DevPlace.",
breadcrumbs=[{"name": "Home", "url": "/feed"}, {"name": "Feed", "url": "/feed"}],
)
2026-05-13 23:03:06 +02:00
return templates.TemplateResponse(request, "feed.html", {
2026-05-11 05:30:51 +02:00
**seo_ctx,
2026-05-10 09:08:12 +02:00
"request": request,
"user": user,
"posts": posts,
"current_tab": tab,
"current_topic": topic,
2026-05-23 06:20:27 +02:00
"total_members": stats["total_members"],
"posts_today": stats["posts_today"],
"total_projects": stats["total_projects"],
"total_gists": stats["total_gists"],
2026-05-10 09:08:12 +02:00
"top_authors": top_authors,
2026-05-11 00:41:41 +02:00
"daily_topic": daily_topic,
2026-05-11 03:14:43 +02:00
"next_cursor": next_cursor,
2026-05-10 09:08:12 +02:00
})