2025-06-10 16:38:27 +03:00

258 lines
9.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from core.db import get_db, Poster, PosterLike
from core.crypt import decode_jwt, is_admin
from core.file import get_upload_dir, save_file, get_poster_dir, generate_file_url
from pydantic import BaseModel, EmailStr
from datetime import datetime
router = APIRouter()
security = HTTPBearer()
@router.get("/getallposter")
async def get_all_poster(
db: Session = Depends(get_db),
):
posters = db.query(Poster).all()
if not posters:
raise HTTPException(status_code=404, detail="Постеры не найдены.")
return {
"posters": [
{
"id": poster.id,
"title": poster.title,
"description": (poster.description[:250] + "...") if poster.description and len(poster.description) > 250 else poster.description,
"image": poster.image,
"date": poster.date.isoformat() if poster.date else None,
"price": poster.price,
"like": poster.like,
}
for poster in posters
]
}
@router.post("/postercreate")
def create_poster(
title: str = Form(...),
description: str = Form(...),
price: int = Form(...),
date: datetime = Form(...),
file: UploadFile = File(...),
db: Session = Depends(get_db),
credentials: HTTPAuthorizationCredentials = Depends(security),
request: Request = None,
):
token = credentials.credentials
decoded_data = decode_jwt(token)
user_id = decoded_data.get("user_id")
if not is_admin(user_id, db):
raise HTTPException(status_code=403, detail="Недостаточно прав для выполнения этого действия.")
if not file:
raise HTTPException(status_code=400, detail="Файл не был загружен.")
if not file.filename.endswith(('.jpg', '.jpeg', '.png')):
raise HTTPException(status_code=400, detail="Недопустимый формат файла. Допустимые форматы: .jpg, .jpeg, .png.")
try:
poster_id = db.query(Poster).count() + 1
upload_dir = get_poster_dir(poster_id)
file_path = save_file(file, upload_dir)
file_url = generate_file_url(request, file_path)
new_poster = Poster(
title=title,
description=description,
date=date,
price=price,
like=0,
datecreation=datetime.utcnow(),
image=str(file_url),
)
db.add(new_poster)
db.commit()
db.refresh(new_poster)
except Exception as e:
db.rollback()
raise HTTPException(status_code=500, detail=f"Ошибка при загрузке файла: {str(e)}")
return {"message": "Постер успешно создан.", "poster": new_poster}
@router.post("/posterupdate")
def update_poster(
poster_id: int = Form(...),
title: str = Form(...),
description: str = Form(...),
price: int = Form(...),
date: datetime = Form(...),
file: UploadFile = File(None),
db: Session = Depends(get_db),
credentials: HTTPAuthorizationCredentials = Depends(security),
request: Request = None,
):
token = credentials.credentials
decoded_data = decode_jwt(token)
user_id = decoded_data.get("user_id")
if not is_admin(user_id, db):
raise HTTPException(status_code=403, detail="Недостаточно прав для выполнения этого действия.")
poster = db.query(Poster).filter(Poster.id == poster_id).first()
if not poster:
raise HTTPException(status_code=404, detail="Постер не найден.")
if file:
if not file.filename.endswith(('.jpg', '.jpeg', '.png')):
raise HTTPException(status_code=400, detail="Недопустимый формат файла. Допустимые форматы: .jpg, .jpeg, .png.")
try:
upload_dir = get_poster_dir(poster_id)
file_path = save_file(file, upload_dir)
file_url = generate_file_url(request, file_path)
poster.image = str(file_url)
except Exception as e:
db.rollback()
raise HTTPException(status_code=500, detail=f"Ошибка при загрузке файла: {str(e)}")
poster.title = title
poster.description = description
poster.date = date
poster.price = price
try:
db.commit()
db.refresh(poster)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Ошибка при обновлении постера.")
return {"message": "Постер успешно обновлен.", "poster": poster}
@router.post("/setlike")
def set_like(
poster_id: int = Form(...),
like: int = Form(...),
db: Session = Depends(get_db),
credentials: HTTPAuthorizationCredentials = Depends(security),
):
token = credentials.credentials
decoded_data = decode_jwt(token)
user_id = decoded_data.get("user_id")
if not user_id:
raise HTTPException(status_code=401, detail="Пользователь не авторизован.")
# Проверка существования постера
poster = db.query(Poster).filter(Poster.id == poster_id).first()
if not poster:
raise HTTPException(status_code=404, detail="Постер не найден.")
# Валидация значения like
if like not in [1, -1]:
raise HTTPException(status_code=400, detail="Значение like должно быть 1 или -1.")
try:
# Проверка на существующий лайк
existing_like = db.query(PosterLike).filter(
PosterLike.poster_id == poster_id,
PosterLike.user_id == user_id
).first()
if like == 1:
# Пользователь хочет поставить лайк
if existing_like:
# Лайк уже есть - ничего не делаем
return {
"message": "Вы уже оценили этот постер.",
"poster": {
"id": poster.id,
"title": poster.title,
"like": poster.like,
"image": poster.image,
"price": poster.price,
"date": poster.date.isoformat(),
"description": poster.description
}
}
else:
# Добавляем лайк
new_like = PosterLike(poster_id=poster_id, user_id=user_id)
db.add(new_like)
poster.like += 1
else:
# Пользователь хочет убрать лайк
if existing_like:
# Удаляем запись о лайке
db.delete(existing_like)
poster.like -= 1
else:
# Лайка не было - ничего не делаем
return {
"message": "Вы еще не ставили лайк этому постеру.",
"poster": {
"id": poster.id,
"title": poster.title,
"like": poster.like,
"image": poster.image,
"price": poster.price,
"date": poster.date.isoformat(),
"description": poster.description
}
}
db.commit()
db.refresh(poster)
return {
"message": "Лайк успешно обновлен.",
"poster": {
"id": poster.id,
"title": poster.title,
"like": poster.like,
"image": poster.image,
"price": poster.price,
"date": poster.date.isoformat(),
"description": poster.description
}
}
except IntegrityError as e:
db.rollback()
print(f"Ошибка IntegrityError: {str(e)}")
raise HTTPException(status_code=400, detail="Ошибка при обновлении лайка постера.")
except Exception as e:
db.rollback()
print(f"Неожиданная ошибка: {str(e)}")
raise HTTPException(status_code=500, detail=f"Произошла ошибка: {str(e)}")
@router.get("/getposter/{poster_id}")
async def get_poster(
poster_id: int,
db: Session = Depends(get_db),
):
poster = db.query(Poster).filter(Poster.id == poster_id).first()
if not poster:
raise HTTPException(status_code=404, detail="Постер не найден.")
return {
"id": poster.id,
"title": poster.title,
"description": poster.description,
"image": poster.image,
"date": poster.date.isoformat() if poster.date else None,
"price": poster.price,
"like": poster.like,
}