Files
thisORthat/app/main.py
T
2025-03-08 21:44:06 +03:00

191 lines
7.8 KiB
Python

import os
import uvicorn
import asyncio
from dotenv import load_dotenv
from fastapi import FastAPI, Depends, Response, status
from schemas.api_schemas import *
from schemas.base_schemas import *
from mongo_worker import MongoWorker
from tools.base_moderation import moderate_text
load_dotenv()
disable_docs = os.getenv("DISABLE_DOCS", "true").lower() == "true"
app: FastAPI = FastAPI(title="This OR That",
summary="OpenAPI schema for \"This OR That\" project!",
version="0.1",
contact={"GitHub": "https://github.com/IgorVolochay/thisORthat"},
docs_url=None if disable_docs else "/docs",
redoc_url=None if disable_docs else "/redoc",
openapi_url=None if disable_docs else "/openapi.json")
mongo_worker = MongoWorker()
@app.get("/check_user", status_code=200)
async def check_user(user_id: NonNegativeInt,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
result = mongo.check_user(user_id)
return BaseResponse(result=result)
@app.get("/get_user", status_code=200)
async def get_user(user_id: NonNegativeInt,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
if mongo.check_user(user_id):
result = mongo.get_user(user_id)
return BaseResponse(result=result)
else:
response.status_code = status.HTTP_404_NOT_FOUND
return BaseResponse(result="User doesn't exist", error=True)
@app.post("/add_user", status_code=201)
async def add_user(new_user: AddUserBody,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
if not mongo.check_user(new_user.user_id):
result = mongo.add_user(new_user.user_id,
new_user.username,
new_user.first_name,
new_user.last_name,
new_user.photo_url)
return BaseResponse(result=result)
else:
response.status_code = status.HTTP_409_CONFLICT
return BaseResponse(result="User already exist", error=True)
@app.get("/get_card", status_code=200)
async def get_card(card_id: NonNegativeInt,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
card = mongo.get_card(card_id)
if card:
return BaseResponse(result=card)
else:
response.status_code = status.HTTP_404_NOT_FOUND
return BaseResponse(result="There is no card with this card_id", error=True)
@app.get("/get_random_cards", status_code=200)
async def get_random_cards(user_id: NonNegativeInt,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
cards_visited = mongo.get_visited_cards(user_id)
if cards_visited.error:
response.status_code = status.HTTP_401_UNAUTHORIZED
return cards_visited
elif not cards_visited.result.cards_visited:
random_cards = mongo.get_random_cards(10, True)
if random_cards:
return BaseResponse(result=random_cards)
else:
response.status_code = status.HTTP_404_NOT_FOUND
return BaseResponse(result="No active cards", error=True)
result: list[Card] = list()
trys = 3
while len(result) < 10 and trys != 0:
random_cards = mongo.get_random_cards(10, True)
if not random_cards:
response.status_code = status.HTTP_404_NOT_FOUND
return BaseResponse(result="No active cards", error=True)
filtered_cards, filtered_cards_id = mongo.filter_cards(random_cards, cards_visited.result.cards_visited)
trys -= 1
if not filtered_cards:
continue
else:
result.extend(filtered_cards)
cards_visited.result.cards_visited.update(filtered_cards_id)
if not result:
response.status_code = status.HTTP_404_NOT_FOUND
return BaseResponse(result="No active cards fo this user", error=True)
else:
return BaseResponse(result=result)
@app.post("/add_card", status_code=201)
async def add_card(new_card: AddCardBody,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
if moderate_text(new_card.choice_A) and moderate_text(new_card.choice_B):
card = mongo.add_card_by_api(new_card.choice_A,
new_card.choice_B,
new_card.author_id)
return BaseResponse(result=card)
else:
response.status_code = status.HTTP_400_BAD_REQUEST
return BaseResponse(result="Card has not passed base moderation", error=True)
@app.patch("/select_choice", status_code=200)
async def select_choice(choice_data: SelectChoice,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
check_visited = mongo.get_visited_cards(choice_data.user_id)
if check_visited.error:
response.status_code = status.HTTP_404_NOT_FOUND
return check_visited
elif not check_visited.error and choice_data.card_id in check_visited.result.cards_visited:
response.status_code = status.HTTP_403_FORBIDDEN
return BaseResponse(result="Card already visited!", error=True)
else:
select_choice_result = mongo.select_choice(choice_data.card_id, choice_data.choice)
if select_choice_result.error:
response.status_code = status.HTTP_404_NOT_FOUND
return select_choice_result
else:
update_visited_result = mongo.update_visited_cards(choice_data.user_id, choice_data.card_id)
return BaseResponse(result="Select choice complite!")
@app.patch("/like_card", status_code=200)
async def like_card(like_data: ReactionCard,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
result = mongo.like_card(like_data.card_id, like_data.user_id)
if not result.error and result.result:
return BaseResponse(result="Added like to card")
else:
response.status_code = status.HTTP_404_NOT_FOUND
return result
@app.patch("/dislike_card", status_code=200)
async def dislike_card(dislike_data: ReactionCard,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
result = mongo.dislike_card(dislike_data.card_id, dislike_data.user_id)
if not result.error and result.result:
return BaseResponse(result="Added dislike to card")
else:
response.status_code = status.HTTP_404_NOT_FOUND
return result
@app.post("/comment", status_code=201)
async def comment(comment_info: AddCommentBody,
response: Response,
mongo: MongoWorker = Depends(lambda: mongo_worker)) -> BaseResponse:
if not moderate_text(comment_info.comment_text):
response.status_code = status.HTTP_400_BAD_REQUEST
return BaseResponse(result="Comment has not passed base moderation", error=True)
result = mongo.add_comment(comment_info.author_id, comment_info.card_id, comment_info.comment_text)
if result.error and result.result in ["User doesn't exist", "Card doesn't exist"]:
response.status_code = status.HTTP_404_NOT_FOUND
return result
elif result.error:
response.status_code = status.HTTP_400_BAD_REQUEST
return result
else:
return result
async def main():
config = uvicorn.Config("main:app", port=5000, log_level="debug")
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
asyncio.run(main())