use background tasks

This commit is contained in:
hay-kot 2021-05-08 17:18:37 -08:00
commit 74fc10cf1c
8 changed files with 94 additions and 32 deletions

View file

@ -2,7 +2,7 @@ import operator
import shutil
from pathlib import Path
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile, status
from mealie.core.config import app_dirs
from mealie.core.root_logger import get_logger
from mealie.core.security import create_file_token
@ -33,7 +33,7 @@ def available_imports():
@router.post("/export/database", status_code=status.HTTP_201_CREATED)
def export_database(data: BackupJob, session: Session = Depends(generate_session)):
def export_database(background_tasks: BackgroundTasks, data: BackupJob, session: Session = Depends(generate_session)):
"""Generates a backup of the recipe database in json format."""
try:
export_path = backup_all(
@ -47,7 +47,9 @@ def export_database(data: BackupJob, session: Session = Depends(generate_session
export_users=data.options.users,
export_groups=data.options.groups,
)
create_backup_event("Database Backup", f"Manual Backup Created '{Path(export_path).name}'", session)
background_tasks.add_task(
create_backup_event, "Database Backup", f"Manual Backup Created '{Path(export_path).name}'", session
)
return {"export_path": export_path}
except Exception as e:
logger.error(e)
@ -75,7 +77,12 @@ async def download_backup_file(file_name: str):
@router.post("/{file_name}/import", status_code=status.HTTP_200_OK)
def import_database(file_name: str, import_data: ImportJob, session: Session = Depends(generate_session)):
def import_database(
background_tasks: BackgroundTasks,
file_name: str,
import_data: ImportJob,
session: Session = Depends(generate_session),
):
""" Import a database backup file generated from Mealie. """
db_import = imports.import_database(
@ -90,7 +97,7 @@ def import_database(file_name: str, import_data: ImportJob, session: Session = D
force_import=import_data.force,
rebase=import_data.rebase,
)
create_backup_event("Database Restore", f"Restore File: {file_name}", session)
background_tasks.add_task(create_backup_event, "Database Restore", f"Restore File: {file_name}", session)
return db_import

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
from mealie.db.database import db
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
@ -32,6 +32,7 @@ async def get_current_user_group(
@router.post("", status_code=status.HTTP_201_CREATED)
async def create_group(
background_tasks: BackgroundTasks,
group_data: GroupBase,
current_user=Depends(get_current_user),
session: Session = Depends(generate_session),
@ -40,7 +41,7 @@ async def create_group(
try:
db.groups.create(session, group_data.dict())
create_group_event("Group Created", f"'{group_data.name}' created")
background_tasks.add_task(create_group_event, "Group Created", f"'{group_data.name}' created", session)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)
@ -58,7 +59,10 @@ async def update_group_data(
@router.delete("/{id}")
async def delete_user_group(
id: int, current_user=Depends(get_current_user), session: Session = Depends(generate_session)
background_tasks: BackgroundTasks,
id: int,
current_user: UserInDB = Depends(get_current_user),
session: Session = Depends(generate_session),
):
""" Removes a user group from the database """
@ -73,5 +77,8 @@ async def delete_user_group(
if group.users != []:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="GROUP_WITH_USERS")
create_group_event("Group Deleted", f"'{group.name}' Deleted")
background_tasks.add_task(
create_group_event, "Group Deleted", f"'{group.name}' deleted by {current_user.full_name}", session
)
db.groups.delete(session, id)

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
from mealie.db.database import db
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
@ -25,16 +25,22 @@ def get_all_meals(
@router.post("/create", status_code=status.HTTP_201_CREATED)
def create_meal_plan(
data: MealPlanIn, session: Session = Depends(generate_session), current_user: UserInDB = Depends(get_current_user)
background_tasks: BackgroundTasks,
data: MealPlanIn,
session: Session = Depends(generate_session),
current_user: UserInDB = Depends(get_current_user),
):
""" Creates a meal plan database entry """
processed_plan = process_meals(session, data)
create_group_event("Meal Plan Created", f"Mealplan Created for '{current_user.group}'")
background_tasks.add_task(
create_group_event, "Meal Plan Created", f"Mealplan Created for '{current_user.group}'", session=session
)
return db.meals.create(session, processed_plan.dict())
@router.put("/{plan_id}")
def update_meal_plan(
background_tasks: BackgroundTasks,
plan_id: str,
meal_plan: MealPlanIn,
session: Session = Depends(generate_session),
@ -45,13 +51,16 @@ def update_meal_plan(
processed_plan = MealPlanInDB(uid=plan_id, **processed_plan.dict())
try:
db.meals.update(session, plan_id, processed_plan.dict())
create_group_event("Meal Plan Updated", f"Mealplan Updated for '{current_user.group}'")
background_tasks.add_task(
create_group_event, "Meal Plan Updated", f"Mealplan Updated for '{current_user.group}'", session=session
)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.delete("/{plan_id}")
def delete_meal_plan(
background_tasks: BackgroundTasks,
plan_id,
session: Session = Depends(generate_session),
current_user: UserInDB = Depends(get_current_user),
@ -60,7 +69,9 @@ def delete_meal_plan(
try:
db.meals.delete(session, plan_id)
create_group_event("Meal Plan Deleted", f"Mealplan Deleted for '{current_user.group}'")
background_tasks.add_task(
create_group_event, "Meal Plan Deleted", f"Mealplan Deleted for '{current_user.group}'", session=session
)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)

View file

@ -1,6 +1,6 @@
from shutil import copyfileobj
from fastapi import APIRouter, Depends, File, Form, HTTPException, status
from fastapi import APIRouter, BackgroundTasks, Depends, File, Form, HTTPException, status
from fastapi.datastructures import UploadFile
from mealie.core.root_logger import get_logger
from mealie.db.database import db
@ -20,6 +20,7 @@ logger = get_logger()
@router.post("/create", status_code=201, response_model=str)
def create_from_json(
background_tasks: BackgroundTasks,
data: Recipe,
session: Session = Depends(generate_session),
current_user=Depends(get_current_user),
@ -27,13 +28,20 @@ def create_from_json(
""" Takes in a JSON string and loads data into the database as a new entry"""
recipe: Recipe = db.recipes.create(session, data.dict())
create_recipe_event("Recipe Created", f"Recipe '{recipe.name}' created", session=session)
background_tasks.add_task(
create_recipe_event,
"Recipe Created (URL)",
f"'{recipe.name}' by {current_user.full_name}",
session=session,
attachment=recipe.image_dir.joinpath("min-original.webp"),
)
return recipe.slug
@router.post("/create-url", status_code=201, response_model=str)
def parse_recipe_url(
background_tasks: BackgroundTasks,
url: RecipeURLIn,
session: Session = Depends(generate_session),
current_user=Depends(get_current_user),
@ -42,7 +50,14 @@ def parse_recipe_url(
recipe = create_from_url(url.url)
recipe: Recipe = db.recipes.create(session, recipe.dict())
create_recipe_event("Recipe Created (URL)", f"'{recipe.name}' by {current_user.full_name}", session=session)
background_tasks.add_task(
create_recipe_event,
"Recipe Created (URL)",
f"'{recipe.name}' by {current_user.full_name}",
session=session,
attachment=recipe.image_dir.joinpath("min-original.webp"),
)
return recipe.slug
@ -64,7 +79,6 @@ def update_recipe(
""" Updates a recipe by existing slug and data. """
recipe: Recipe = db.recipes.update(session, recipe_slug, data.dict())
print(recipe.assets)
check_assets(original_slug=recipe_slug, recipe=recipe)
@ -91,6 +105,7 @@ def patch_recipe(
@router.delete("/{recipe_slug}")
def delete_recipe(
background_tasks: BackgroundTasks,
recipe_slug: str,
session: Session = Depends(generate_session),
current_user=Depends(get_current_user),
@ -100,7 +115,12 @@ def delete_recipe(
try:
recipe: Recipe = db.recipes.delete(session, recipe_slug)
delete_assets(recipe_slug=recipe_slug)
create_recipe_event("Recipe Deleted", f"'{recipe.name}' deleted by {current_user.full_name}", session=session)
background_tasks.add_task(
create_recipe_event,
"Recipe Deleted",
f"'{recipe.name}' deleted by {current_user.full_name}",
session=session,
)
return recipe
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, Request, status
from fastapi import APIRouter, BackgroundTasks, Depends, Request, status
from fastapi.exceptions import HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from mealie.core import security
@ -15,6 +15,7 @@ router = APIRouter(prefix="/api/auth", tags=["Authentication"])
@router.post("/token/long")
@router.post("/token")
def get_token(
background_tasks: BackgroundTasks,
request: Request,
data: OAuth2PasswordRequestForm = Depends(),
session: Session = Depends(generate_session),
@ -25,7 +26,9 @@ def get_token(
user = authenticate_user(session, email, password)
if not user:
create_user_event("Failed Login", f"Username: {email}, Source IP: '{request.client.host}'")
background_tasks.add_task(
create_user_event, "Failed Login", f"Username: {email}, Source IP: '{request.client.host}'"
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
headers={"WWW-Authenticate": "Bearer"},

View file

@ -1,6 +1,6 @@
import shutil
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile, status
from fastapi.responses import FileResponse
from mealie.core import security
from mealie.core.config import app_dirs, settings
@ -17,13 +17,16 @@ router = APIRouter(prefix="/api/users", tags=["Users"])
@router.post("", response_model=UserOut, status_code=201)
async def create_user(
background_tasks: BackgroundTasks,
new_user: UserIn,
current_user=Depends(get_current_user),
session: Session = Depends(generate_session),
):
new_user.password = get_password_hash(new_user.password)
create_user_event("User Created", f"Created by {current_user.full_name}", session=session)
background_tasks.add_task(
create_user_event, "User Created", f"Created by {current_user.full_name}", session=session
)
return db.users.create(session, new_user.dict())
@ -138,6 +141,7 @@ async def update_password(
@router.delete("/{id}")
async def delete_user(
background_tasks: BackgroundTasks,
id: int,
current_user: UserInDB = Depends(get_current_user),
session: Session = Depends(generate_session),
@ -150,6 +154,6 @@ async def delete_user(
if current_user.id == id or current_user.admin:
try:
db.users.delete(session, id)
create_user_event("User Deleted", f"User ID: {id}", session=session)
background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)

View file

@ -1,6 +1,6 @@
import uuid
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
from mealie.core.security import get_password_hash
from mealie.db.database import db
from mealie.db.db_setup import generate_session
@ -25,6 +25,7 @@ async def get_all_open_sign_ups(
@router.post("", response_model=SignUpToken)
async def create_user_sign_up_key(
background_tasks: BackgroundTasks,
key_data: SignUpIn,
current_user: UserInDB = Depends(get_current_user),
session: Session = Depends(generate_session),
@ -39,12 +40,16 @@ async def create_user_sign_up_key(
"name": key_data.name,
"admin": key_data.admin,
}
create_user_event("Sign-up Token Created", f"Created by {current_user.full_name}", session=session)
background_tasks.add_task(
create_user_event, "Sign-up Token Created", f"Created by {current_user.full_name}", session=session
)
return db.sign_ups.create(session, sign_up)
@router.post("/{token}")
async def create_user_with_token(
background_tasks: BackgroundTasks,
token: str,
new_user: UserIn,
session: Session = Depends(generate_session),
@ -62,7 +67,9 @@ async def create_user_with_token(
db.users.create(session, new_user.dict())
# DeleteToken
create_user_event("Sign-up Token Used", f"New User {new_user.full_name}", session=session)
background_tasks.add_task(
create_user_event, "Sign-up Token Used", f"New User {new_user.full_name}", session=session
)
db.sign_ups.delete(session, token)

View file

@ -17,7 +17,7 @@ def test_notification(notification_url, event=None) -> bool:
post_notifications(event, [notification_url], hard_fail=True)
def post_notifications(event: Event, notification_urls=list[str], hard_fail=False):
def post_notifications(event: Event, notification_urls=list[str], hard_fail=False, attachment=None):
asset = apprise.AppriseAsset(async_mode=False)
apobj = apprise.Apprise(asset=asset)
@ -27,20 +27,23 @@ def post_notifications(event: Event, notification_urls=list[str], hard_fail=Fals
if not status and hard_fail:
raise Exception("Apprise URL Add Failed")
print(attachment)
apobj.notify(
body=event.text,
title=event.title,
attach=str(attachment),
)
def save_event(title, text, category, session: Session):
def save_event(title, text, category, session: Session, attachment=None):
event = Event(title=title, text=text, category=category)
session = session or create_session()
db.events.create(session, event.dict())
notification_objects = db.event_notifications.get(session=session, match_value=True, match_key=category, limit=9999)
notification_urls = [x.notification_url for x in notification_objects]
post_notifications(event, notification_urls)
post_notifications(event, notification_urls, attachment=attachment)
def create_general_event(title, text, session=None):
@ -48,10 +51,10 @@ def create_general_event(title, text, session=None):
save_event(title=title, text=text, category=category, session=session)
def create_recipe_event(title, text, session=None):
def create_recipe_event(title, text, session=None, attachment=None):
category = EventCategory.recipe
save_event(title=title, text=text, category=category, session=session)
save_event(title=title, text=text, category=category, session=session, attachment=attachment)
def create_backup_event(title, text, session=None):