2024-07-25 12:19:15 +00:00
|
|
|
|
import math
|
|
|
|
|
from fastapi import APIRouter, Body, Form, Query, Request, Depends, Cookie, HTTPException
|
|
|
|
|
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
|
|
|
|
|
from sqlalchemy import func
|
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from db import crud
|
|
|
|
|
from db.db import async_session
|
2024-07-25 13:08:34 +00:00
|
|
|
|
from function import decrypt_token, get_authenticated_user, send_newsletter, get_user_with_access, send_msg
|
2024-07-25 12:19:15 +00:00
|
|
|
|
from config import templates
|
|
|
|
|
from db.models import User
|
|
|
|
|
from sqlalchemy.future import select
|
|
|
|
|
import asyncio
|
|
|
|
|
import logging
|
|
|
|
|
from models import NewsletterRequest
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from bot.db.models import UserTg, Otdels, Questions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
user_router = APIRouter()
|
|
|
|
|
|
|
|
|
|
@user_router.get("/", response_class=HTMLResponse)
|
|
|
|
|
async def read_root(request: Request, user: User = Depends(get_authenticated_user)):
|
|
|
|
|
return templates.TemplateResponse("index.html", {"request": request, "user": user})
|
|
|
|
|
|
|
|
|
|
@user_router.get("/profile", response_class=HTMLResponse)
|
|
|
|
|
async def profile(request: Request, user: User = Depends(get_authenticated_user)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return templates.TemplateResponse("profile.html", {"request": request, "user": user})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@user_router.get("/users", response_class=HTMLResponse)
|
|
|
|
|
async def users(
|
|
|
|
|
request: Request,
|
|
|
|
|
user: User = Depends(get_user_with_access),
|
|
|
|
|
page: int = Query(1, alias='page', ge=1)
|
|
|
|
|
):
|
|
|
|
|
ITEMS_PER_PAGE = 12
|
|
|
|
|
PAGINATION_BUTTONS = 10
|
|
|
|
|
|
|
|
|
|
async with async_session() as db_session:
|
|
|
|
|
# Подсчитываем общее количество пользователей
|
|
|
|
|
total_users = await db_session.execute(select(func.count(UserTg.id)))
|
|
|
|
|
total_users = total_users.scalar_one()
|
|
|
|
|
total_pages = (total_users + ITEMS_PER_PAGE - 1) // ITEMS_PER_PAGE
|
|
|
|
|
|
|
|
|
|
# Вычисляем смещение и лимит
|
|
|
|
|
offset = (page - 1) * ITEMS_PER_PAGE
|
|
|
|
|
|
|
|
|
|
# Создаем запрос с сортировкой по id
|
|
|
|
|
stmt = select(UserTg).order_by(UserTg.id).offset(offset).limit(ITEMS_PER_PAGE)
|
|
|
|
|
result = await db_session.execute(stmt)
|
|
|
|
|
users = result.scalars().all()
|
|
|
|
|
|
|
|
|
|
# Определяем страницы для отображения пагинации
|
|
|
|
|
start_page = max(1, page - PAGINATION_BUTTONS // 2)
|
|
|
|
|
end_page = min(total_pages, start_page + PAGINATION_BUTTONS - 1)
|
|
|
|
|
start_page = max(1, end_page - PAGINATION_BUTTONS + 1)
|
|
|
|
|
|
|
|
|
|
return templates.TemplateResponse(
|
|
|
|
|
"users.html",
|
|
|
|
|
{
|
|
|
|
|
"request": request,
|
|
|
|
|
"user": user,
|
|
|
|
|
"users": users,
|
|
|
|
|
"current_page": page,
|
|
|
|
|
"total_pages": total_pages,
|
|
|
|
|
"start_page": start_page,
|
|
|
|
|
"end_page": end_page
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@user_router.post("/update_status/{user_id}", response_class=HTMLResponse)
|
|
|
|
|
async def update_status(
|
|
|
|
|
request: Request,
|
|
|
|
|
user_id: int,
|
|
|
|
|
user: User = Depends(get_user_with_access)
|
|
|
|
|
):
|
|
|
|
|
logging.info(f"Received request to update status for user_id: {user_id}")
|
|
|
|
|
async with async_session() as db_session:
|
|
|
|
|
result = await db_session.execute(select(UserTg).filter(UserTg.id == user_id))
|
|
|
|
|
user_record = result.scalars().first()
|
|
|
|
|
|
|
|
|
|
if not user_record:
|
|
|
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
|
|
2024-07-25 13:08:34 +00:00
|
|
|
|
|
|
|
|
|
if user_record.has_access == True:
|
|
|
|
|
user_record.has_access = False
|
|
|
|
|
else:
|
|
|
|
|
user_record.has_access = True
|
|
|
|
|
await send_msg(user_record.user_id)
|
2024-07-25 12:19:15 +00:00
|
|
|
|
|
|
|
|
|
db_session.add(user_record)
|
|
|
|
|
await db_session.commit()
|
|
|
|
|
|
|
|
|
|
logging.info(f"Successfully updated status for user_id: {user_id}")
|
|
|
|
|
return JSONResponse(content={"status": "success"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@user_router.post("/send-newsletter", response_class=JSONResponse)
|
|
|
|
|
async def newsletter(
|
|
|
|
|
request: NewsletterRequest, # Используем Pydantic модель
|
|
|
|
|
user: User = Depends(get_user_with_access)
|
|
|
|
|
):
|
|
|
|
|
async with async_session() as db_session:
|
|
|
|
|
try:
|
|
|
|
|
asyncio.create_task(send_newsletter(str(request.message), db_session))
|
|
|
|
|
except Exception as ex:
|
|
|
|
|
logging.error(ex)
|
|
|
|
|
return JSONResponse(content={"status": f"error", "message": f"error - {ex}"}, status_code=501)
|
|
|
|
|
|
|
|
|
|
return JSONResponse(content={"status": "success"}, status_code=200)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@user_router.get("/logout", response_class=HTMLResponse)
|
|
|
|
|
async def logout(request: Request, session_token: str = Cookie(None)):
|
|
|
|
|
if not session_token:
|
|
|
|
|
raise HTTPException(status_code=401, detail="Not authenticated")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
decrypted_token = decrypt_token(session_token)
|
|
|
|
|
except Exception:
|
|
|
|
|
raise HTTPException(status_code=401, detail="Invalid session token")
|
|
|
|
|
|
|
|
|
|
async with async_session() as db_session:
|
|
|
|
|
await crud.delete_session(db_session, decrypted_token)
|
|
|
|
|
|
|
|
|
|
response = RedirectResponse(url="/", status_code=303)
|
|
|
|
|
response.delete_cookie("session_token")
|
|
|
|
|
return response
|