"""Feed routes for SocialPhoto.""" import sqlite3 from typing import List from fastapi import APIRouter, Depends, Query from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from app.auth import get_current_user_id from app.database import get_db, row_to_dict from app.schemas import FeedResponse, PostResponse router = APIRouter(prefix="/feed", tags=["Feed"]) security = HTTPBearer() @router.get("", response_model=FeedResponse) async def get_followed_feed( limit: int = Query(default=20, ge=1, le=100), offset: int = Query(default=0, ge=0), credentials: HTTPAuthorizationCredentials = Depends(security), conn: sqlite3.Connection = Depends(get_db), ) -> FeedResponse: """Get feed of posts from users you follow.""" user_id = await get_current_user_id(credentials) cursor = conn.cursor() # Get posts from followed users cursor.execute( """ SELECT p.id, p.user_id, u.username, p.image_path, p.caption, p.created_at, (SELECT COUNT(*) FROM likes WHERE post_id = p.id) as likes_count, (SELECT COUNT(*) FROM dislikes WHERE post_id = p.id) as dislikes_count, (SELECT COUNT(*) FROM comments WHERE post_id = p.id) as comments_count FROM posts p JOIN users u ON p.user_id = u.id WHERE p.user_id IN ( SELECT following_id FROM follows WHERE follower_id = ? ) ORDER BY p.created_at DESC LIMIT ? OFFSET ? """, (user_id, limit, offset), ) posts = [] for row in cursor.fetchall(): post = row_to_dict(row) posts.append( PostResponse( id=post["id"], user_id=post["user_id"], username=post["username"], image_url=f"/uploads/{post['image_path'].split('/')[-1]}", caption=post["caption"], likes_count=post["likes_count"], dislikes_count=post["dislikes_count"], comments_count=post["comments_count"], created_at=post["created_at"], ) ) # Get total count cursor.execute( """ SELECT COUNT(*) as total FROM posts p WHERE p.user_id IN ( SELECT following_id FROM follows WHERE follower_id = ? ) """, (user_id,), ) total = cursor.fetchone()["total"] return FeedResponse(posts=posts, total=total, limit=limit, offset=offset) @router.get("/global", response_model=FeedResponse) async def get_global_feed( limit: int = Query(default=20, ge=1, le=100), offset: int = Query(default=0, ge=0), conn: sqlite3.Connection = Depends(get_db), ) -> FeedResponse: """Get global feed of all posts.""" cursor = conn.cursor() cursor.execute( """ SELECT p.id, p.user_id, u.username, p.image_path, p.caption, p.created_at, (SELECT COUNT(*) FROM likes WHERE post_id = p.id) as likes_count, (SELECT COUNT(*) FROM dislikes WHERE post_id = p.id) as dislikes_count, (SELECT COUNT(*) FROM comments WHERE post_id = p.id) as comments_count FROM posts p JOIN users u ON p.user_id = u.id ORDER BY p.created_at DESC LIMIT ? OFFSET ? """, (limit, offset), ) posts = [] for row in cursor.fetchall(): post = row_to_dict(row) posts.append( PostResponse( id=post["id"], user_id=post["user_id"], username=post["username"], image_url=f"/uploads/{post['image_path'].split('/')[-1]}", caption=post["caption"], likes_count=post["likes_count"], dislikes_count=post["dislikes_count"], comments_count=post["comments_count"], created_at=post["created_at"], ) ) # Get total count cursor.execute("SELECT COUNT(*) as total FROM posts") total = cursor.fetchone()["total"] return FeedResponse(posts=posts, total=total, limit=limit, offset=offset)