258 lines
9.3 KiB
Python
258 lines
9.3 KiB
Python
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,
|
||
}
|