Aykhan f782944caa - Added flake8
- create_user moved to commands
2023-09-16 18:06:47 +04:00

258 lines
6.0 KiB
Python

from datetime import timedelta
from typing import (
Annotated,
Optional
)
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi.templating import Jinja2Templates
from fastapi.responses import (
FileResponse,
HTMLResponse,
RedirectResponse
)
from fastapi import (
APIRouter,
Form,
HTTPException,
Request,
Depends
)
from app import crud
from app.core import security
from app.models.user import User as UserModel
from app.schemas import (
JWTToken,
LoginForm
)
from app.core.config import settings
from app.schemas.post import (
PostCreate,
PostUpdate
)
from app.schemas.post import Post as PostSchema
from app.views.depends import (
get_async_db,
get_current_active_superuser_or_die,
get_current_active_superuser_or_none,
get_post_by_slug_or_die,
handle_post_image_or_die,
handle_post_image_or_none
)
router = APIRouter()
templates = Jinja2Templates(directory=settings.APP_PATH / 'templates')
@router.get(
f"/{settings.LOGIN_URL}",
response_class=HTMLResponse,
include_in_schema=False
)
async def get_login(
request: Request
):
return templates.TemplateResponse(
'admin/login.html',
{
'request': request,
'login_url': f'/{settings.LOGIN_URL}'
}
)
@router.post(
f"/{settings.LOGIN_URL}",
response_model=JWTToken,
include_in_schema=False
)
async def login(
db: AsyncSession = Depends(get_async_db),
form_data: LoginForm = Depends()
):
user = await crud.user.authenticate(
db, email=form_data.email, password=form_data.password
)
if user is None:
raise HTTPException(
status_code=400,
detail="Incorrect email or password"
)
elif user.is_active is False:
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
)
return {
"access_token": security.create_access_token(
user.email,
expires_delta=access_token_expires
),
"token_type": "bearer",
}
@router.get(
'/add-post',
response_class=HTMLResponse,
)
async def get_create_post(
request: Request,
user: UserModel = Depends(get_current_active_superuser_or_die)
):
return templates.TemplateResponse(
'admin/add-post.html',
{
'request': request
}
)
@router.post('/add-post')
async def create_post(
request: Request,
db: AsyncSession = Depends(get_async_db),
user: UserModel = Depends(get_current_active_superuser_or_die),
title: str = Form(...),
text: str = Form(...),
image: str = Depends(handle_post_image_or_die)
):
obj_in = PostCreate(
title=title,
text=text,
image_path=image
)
post = await crud.post.create_with_owner(
db, obj_in=obj_in, owner_id=user.id
)
return RedirectResponse(
str(request.url_for('get_update_post', slug=post.slug)),
status_code=303
)
@router.get('/update-post/{slug}')
async def get_update_post(
request: Request,
user: UserModel = Depends(get_current_active_superuser_or_none),
post: str = Depends(get_post_by_slug_or_die)
):
if user is None:
return RedirectResponse(
f'/{settings.LOGIN_URL}',
status_code=303
)
if user.id != post.owner_id:
raise HTTPException(status_code=404, detail="Post not found")
return templates.TemplateResponse(
'admin/update-post.html',
{
'request': request,
'post': PostSchema.model_validate(post)
}
)
@router.post('/update-post/{slug}')
async def update_post(
request: Request,
user: UserModel = Depends(get_current_active_superuser_or_none),
post: str = Depends(get_post_by_slug_or_die),
db: AsyncSession = Depends(get_async_db),
title: Optional[str] = Form(None),
text: Optional[str] = Form(None),
image: Annotated[str, Depends(handle_post_image_or_none)] = None
):
if user is None:
return RedirectResponse(
f'/{settings.LOGIN_URL}',
status_code=303
)
if user.id != post.owner_id:
raise HTTPException(status_code=404, detail="Post not found")
obj_in = PostUpdate(
title=title,
text=text,
image_path=image
).model_dump(exclude_none=True)
updated_post = await crud.post.update(
db=db,
db_obj=post,
obj_in=obj_in
)
return templates.TemplateResponse(
'admin/update-post.html',
{
'request': request,
'post': PostSchema.model_validate(updated_post)
}
)
@router.get('/delete-post/{slug}')
async def get_delete_post(
request: Request,
user: UserModel = Depends(get_current_active_superuser_or_die),
post: str = Depends(get_post_by_slug_or_die)
):
if user.id != post.owner_id:
raise HTTPException(status_code=404, detail="Post not found")
return templates.TemplateResponse(
'admin/delete-post.html',
{
'request': request,
'post': PostSchema.model_validate(post)
}
)
@router.post('/delete-post/{slug}')
async def delete_post(
request: Request,
user: UserModel = Depends(get_current_active_superuser_or_die),
post: str = Depends(get_post_by_slug_or_die),
db: AsyncSession = Depends(get_async_db)
):
if user.id != post.owner_id:
raise HTTPException(status_code=404, detail="Post not found")
await crud.post.remove_by_slug(db, slug=post.slug)
return RedirectResponse(
str(request.url_for('blog')),
status_code=303
)
@router.get("/admin")
def admin(
request: Request
):
return FileResponse(settings.STATIC_FOLDER / 'just_a.gif')