1+ import os
12from typing import Annotated
23
4+ import jwt
35from fastapi import APIRouter , Depends , Request , status
46from fastapi .params import Header
57from pydantic import BaseModel
68
9+ import app .services .database .orm .news as orm_news
710from app .routers .authentication import get_current_active_community
811from app .schemas import News
912from app .services .database .models import Community as DBCommunity
10- from app .services .database .orm .news import create_news , get_news_by_query_params
13+
14+ SECRET_KEY = os .getenv ("SECRET_KEY" , "default_fallback_key" )
15+ ALGORITHM = os .getenv ("ALGORITHM" , "HS256" )
1116
1217
1318class NewsPostResponse (BaseModel ):
@@ -19,6 +24,19 @@ class NewsGetResponse(BaseModel):
1924 news_list : list = []
2025
2126
27+ class NewsLikeResponse (BaseModel ):
28+ total_likes : int | None
29+
30+
31+ class LikeRequest (BaseModel ):
32+ email : str
33+
34+
35+ def encode_email (email : str ) -> str :
36+ """Encodes the email to be safely stored in database."""
37+ return jwt .encode ({"email" : email }, SECRET_KEY , algorithm = ALGORITHM )
38+
39+
2240def setup ():
2341 router = APIRouter (prefix = "/news" , tags = ["news" ])
2442
@@ -42,7 +60,7 @@ async def post_news(
4260 """
4361 news_dict = news .__dict__
4462 news_dict ["user_email" ] = user_email
45- await create_news (
63+ await orm_news . create_news (
4664 session = request .app .db_session_factory , news = news_dict
4765 )
4866 return NewsPostResponse ()
@@ -67,7 +85,7 @@ async def get_news(
6785 """
6886 Get News endpoint that retrieves news filtered by user and query params.
6987 """
70- news_list = await get_news_by_query_params (
88+ news_list = await orm_news . get_news_by_query_params (
7189 session = request .app .db_session_factory ,
7290 id = id ,
7391 email = user_email ,
@@ -76,4 +94,58 @@ async def get_news(
7694 )
7795 return NewsGetResponse (news_list = news_list )
7896
97+ @router .post (
98+ path = "/{news_id}/like" ,
99+ response_model = NewsLikeResponse ,
100+ status_code = status .HTTP_200_OK ,
101+ summary = "News like endpoint" ,
102+ description = "Allows user to like a news item" ,
103+ )
104+ async def post_like (
105+ request : Request ,
106+ current_community : Annotated [
107+ DBCommunity , Depends (get_current_active_community )
108+ ],
109+ news_id : str ,
110+ body : LikeRequest ,
111+ user_email : str = Header (..., alias = "user-email" ),
112+ ):
113+ """
114+ News endpoint where user can set like to news item.
115+ """
116+ encoded_email = encode_email (body .email )
117+ total_likes = await orm_news .like_news (
118+ session = request .app .db_session_factory ,
119+ news_id = news_id ,
120+ email = encoded_email ,
121+ )
122+ return NewsLikeResponse (total_likes = total_likes )
123+
124+ @router .delete (
125+ path = "/{news_id}/like" ,
126+ response_model = NewsLikeResponse ,
127+ status_code = status .HTTP_200_OK ,
128+ summary = "News undo like endpoint" ,
129+ description = "Allows user to undo a like to a news item" ,
130+ )
131+ async def delete_like (
132+ request : Request ,
133+ current_community : Annotated [
134+ DBCommunity , Depends (get_current_active_community )
135+ ],
136+ news_id : str ,
137+ email : str ,
138+ user_email : str = Header (..., alias = "user-email" ),
139+ ):
140+ """
141+ News endpoint where user can set like to news item.
142+ """
143+ encoded_email = encode_email (email )
144+ total_likes = await orm_news .delete_like (
145+ session = request .app .db_session_factory ,
146+ news_id = news_id ,
147+ email = encoded_email ,
148+ )
149+ return NewsLikeResponse (total_likes = total_likes )
150+
79151 return router
0 commit comments