- Fixed main.py to include all route routers (posts, users, comments, feed) - Renamed app/models.py to app/schemas.py and split into proper schema modules - Fixed schema imports in routes - Updated app/models/__init__.py to properly export SQLAlchemy models - Fixed database imports in route files - App imports and runs correctly
125 lines
4.0 KiB
Python
125 lines
4.0 KiB
Python
"""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)
|