|
import logging
|
|
from datetime import datetime, timezone
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import RedirectResponse
|
|
from devplacepy.database import get_table
|
|
from devplacepy.utils import generate_uid, require_user, create_notification, award_rewards, XP_FOLLOW
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/{username}")
|
|
async def follow_user(request: Request, username: str):
|
|
user = require_user(request)
|
|
users = get_table("users")
|
|
target = users.find_one(username=username)
|
|
if not target or target["uid"] == user["uid"]:
|
|
return RedirectResponse(url=f"/profile/{username}", status_code=302)
|
|
|
|
follows = get_table("follows")
|
|
existing = follows.find_one(follower_uid=user["uid"], following_uid=target["uid"])
|
|
if existing:
|
|
return RedirectResponse(url=f"/profile/{username}", status_code=302)
|
|
|
|
follows.insert({
|
|
"uid": generate_uid(),
|
|
"follower_uid": user["uid"],
|
|
"following_uid": target["uid"],
|
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
|
})
|
|
|
|
create_notification(target["uid"], "follow", f"{user['username']} started following you", user["uid"], f"/profile/{user['username']}")
|
|
award_rewards(target["uid"], XP_FOLLOW)
|
|
|
|
logger.info(f"{user['username']} followed {username}")
|
|
return RedirectResponse(url=f"/profile/{username}", status_code=302)
|
|
|
|
|
|
@router.post("/unfollow/{username}")
|
|
async def unfollow_user(request: Request, username: str):
|
|
user = require_user(request)
|
|
users = get_table("users")
|
|
target = users.find_one(username=username)
|
|
if not target:
|
|
return RedirectResponse(url=f"/profile/{username}", status_code=302)
|
|
|
|
follows = get_table("follows")
|
|
existing = follows.find_one(follower_uid=user["uid"], following_uid=target["uid"])
|
|
if existing:
|
|
follows.delete(id=existing["id"])
|
|
logger.info(f"{user['username']} unfollowed {username}")
|
|
|
|
return RedirectResponse(url=f"/profile/{username}", status_code=302)
|