mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-02-12 10:53:12 -05:00
refactor(backend): ♻️ cleanup HTTP service classes and remove database singleton (#687)
* refactor(backend): ♻️ cleanup duplicate code in http services * refactor(backend): ♻️ refactor database away from singleton design removed the database single and instead injected the session into a new Database class that is created during each request life-cycle. Now sessions no longer need to be passed into each method on the database All tests pass, but there are likely some hidden breaking changes that were not discovered. * fix venv * disable venv cache * fix install script * bump poetry version * postgres fixes * revert install * fix db initialization for postgres * add postgres to docker * refactor(backend): ♻️ cleanup unused and duplicate code in http services * refactor(backend): remove sessions from arguments * refactor(backend): ♻️ convert units and ingredients to use http service class * test(backend): ✅ add unit and food tests * lint * update tags * re-enable cache * fix missing fraction in db * fix lint Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
@@ -2,7 +2,7 @@ from fastapi import Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter
|
||||
from mealie.schema.events import EventsOut
|
||||
@@ -15,18 +15,20 @@ logger = get_logger()
|
||||
@router.get("", response_model=EventsOut)
|
||||
async def get_events(session: Session = Depends(generate_session)):
|
||||
""" Get event from the Database """
|
||||
# Get Item
|
||||
return EventsOut(total=db.events.count_all(session), events=db.events.get_all(session, order_by="time_stamp"))
|
||||
db = get_database(session)
|
||||
|
||||
return EventsOut(total=db.events.count_all(), events=db.events.get_all(order_by="time_stamp"))
|
||||
|
||||
|
||||
@router.delete("")
|
||||
async def delete_events(session: Session = Depends(generate_session)):
|
||||
""" Get event from the Database """
|
||||
# Get Item
|
||||
db = get_database(session)
|
||||
return db.events.delete_all(session)
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
async def delete_event(id: int, session: Session = Depends(generate_session)):
|
||||
""" Delete event from the Database """
|
||||
db = get_database(session)
|
||||
return db.events.delete(session, id)
|
||||
|
||||
@@ -4,7 +4,7 @@ from fastapi import Depends, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter
|
||||
from mealie.schema.events import EventNotificationIn, EventNotificationOut, TestEvent
|
||||
@@ -21,8 +21,9 @@ async def create_event_notification(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Create event_notification in the Database """
|
||||
db = get_database(session)
|
||||
|
||||
return db.event_notifications.create(session, event_data)
|
||||
return db.event_notifications.create(event_data)
|
||||
|
||||
|
||||
@router.post("/notifications/test")
|
||||
@@ -31,9 +32,10 @@ async def test_notification_route(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Create event_notification in the Database """
|
||||
db = get_database(session)
|
||||
|
||||
if test_data.id:
|
||||
event_obj: EventNotificationIn = db.event_notifications.get(session, test_data.id)
|
||||
event_obj: EventNotificationIn = db.event_notifications.get(test_data.id)
|
||||
test_data.test_url = event_obj.notification_url
|
||||
|
||||
try:
|
||||
@@ -46,8 +48,8 @@ async def test_notification_route(
|
||||
@router.get("/notifications", response_model=list[EventNotificationOut])
|
||||
async def get_all_event_notification(session: Session = Depends(generate_session)):
|
||||
""" Get all event_notification from the Database """
|
||||
# Get Item
|
||||
return db.event_notifications.get_all(session, override_schema=EventNotificationOut)
|
||||
db = get_database(session)
|
||||
return db.event_notifications.get_all(override_schema=EventNotificationOut)
|
||||
|
||||
|
||||
@router.put("/notifications/{id}")
|
||||
@@ -61,4 +63,5 @@ async def update_event_notification(id: int, session: Session = Depends(generate
|
||||
async def delete_event_notification(id: int, session: Session = Depends(generate_session)):
|
||||
""" Delete event_notification from the Database """
|
||||
# Delete Item
|
||||
return db.event_notifications.delete(session, id)
|
||||
db = get_database(session)
|
||||
return db.event_notifications.delete(id)
|
||||
|
||||
@@ -28,11 +28,11 @@ async def get_app_info():
|
||||
|
||||
@router.get("/statistics", response_model=AppStatistics)
|
||||
async def get_app_statistics(session: Session = Depends(generate_session)):
|
||||
db = get_database()
|
||||
db = get_database(session)
|
||||
return AppStatistics(
|
||||
total_recipes=db.recipes.count_all(session),
|
||||
uncategorized_recipes=db.recipes.count_uncategorized(session),
|
||||
untagged_recipes=db.recipes.count_untagged(session),
|
||||
total_users=db.users.count_all(session),
|
||||
total_groups=db.groups.count_all(session),
|
||||
total_recipes=db.recipes.count_all(),
|
||||
uncategorized_recipes=db.recipes.count_uncategorized(),
|
||||
untagged_recipes=db.recipes.count_untagged(),
|
||||
total_users=db.users.count_all(),
|
||||
total_groups=db.groups.count_all(),
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@ from fastapi import BackgroundTasks, Depends, HTTPException, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter
|
||||
from mealie.schema.user import GroupBase, GroupInDB, PrivateUser, UpdateGroup
|
||||
@@ -14,8 +14,9 @@ router = AdminAPIRouter(prefix="/groups")
|
||||
@router.get("", response_model=list[GroupInDB])
|
||||
async def get_all_groups(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of all groups in the database """
|
||||
db = get_database(session)
|
||||
|
||||
return db.groups.get_all(session)
|
||||
return db.groups.get_all()
|
||||
|
||||
|
||||
@router.post("", status_code=status.HTTP_201_CREATED, response_model=GroupInDB)
|
||||
@@ -25,9 +26,10 @@ async def create_group(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Creates a Group in the Database """
|
||||
db = get_database(session)
|
||||
|
||||
try:
|
||||
new_group = db.groups.create(session, group_data.dict())
|
||||
new_group = db.groups.create(group_data.dict())
|
||||
background_tasks.add_task(create_group_event, "Group Created", f"'{group_data.name}' created", session)
|
||||
return new_group
|
||||
except Exception:
|
||||
@@ -37,7 +39,8 @@ async def create_group(
|
||||
@router.put("/{id}")
|
||||
async def update_group_data(id: int, group_data: UpdateGroup, session: Session = Depends(generate_session)):
|
||||
""" Updates a User Group """
|
||||
db.groups.update(session, id, group_data.dict())
|
||||
db = get_database(session)
|
||||
db.groups.update(id, group_data.dict())
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
@@ -48,11 +51,12 @@ async def delete_user_group(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Removes a user group from the database """
|
||||
db = get_database(session)
|
||||
|
||||
if id == 1:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="DEFAULT_GROUP")
|
||||
|
||||
group: GroupInDB = db.groups.get(session, id)
|
||||
group: GroupInDB = db.groups.get(id)
|
||||
|
||||
if not group:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="GROUP_NOT_FOUND")
|
||||
@@ -64,4 +68,4 @@ async def delete_user_group(
|
||||
create_group_event, "Group Deleted", f"'{group.name}' deleted by {current_user.full_name}", session
|
||||
)
|
||||
|
||||
db.groups.delete(session, id)
|
||||
db.groups.delete(id)
|
||||
|
||||
@@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import is_logged_in
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
|
||||
@@ -15,13 +15,15 @@ admin_router = AdminAPIRouter()
|
||||
@public_router.get("")
|
||||
async def get_all_recipe_categories(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of available categories in the database """
|
||||
return db.categories.get_all_limit_columns(session, ["slug", "name"])
|
||||
db = get_database(session)
|
||||
return db.categories.get_all_limit_columns(fields=["slug", "name"])
|
||||
|
||||
|
||||
@public_router.get("/empty")
|
||||
def get_empty_categories(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of categories that do not contain any recipes"""
|
||||
return db.categories.get_empty(session)
|
||||
db = get_database(session)
|
||||
return db.categories.get_empty()
|
||||
|
||||
|
||||
@public_router.get("/{category}", response_model=RecipeCategoryResponse)
|
||||
@@ -29,8 +31,9 @@ def get_all_recipes_by_category(
|
||||
category: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
|
||||
):
|
||||
""" Returns a list of recipes associated with the provided category. """
|
||||
db = get_database(session)
|
||||
|
||||
category_obj = db.categories.get(session, category)
|
||||
category_obj = db.categories.get(category)
|
||||
category_obj = RecipeCategoryResponse.from_orm(category_obj)
|
||||
|
||||
if not is_user:
|
||||
@@ -42,9 +45,10 @@ def get_all_recipes_by_category(
|
||||
@user_router.post("")
|
||||
async def create_recipe_category(category: CategoryIn, session: Session = Depends(generate_session)):
|
||||
""" Creates a Category in the database """
|
||||
db = get_database(session)
|
||||
|
||||
try:
|
||||
return db.categories.create(session, category.dict())
|
||||
return db.categories.create(category.dict())
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@@ -52,9 +56,10 @@ async def create_recipe_category(category: CategoryIn, session: Session = Depend
|
||||
@admin_router.put("/{category}", response_model=RecipeCategoryResponse)
|
||||
async def update_recipe_category(category: str, new_category: CategoryIn, session: Session = Depends(generate_session)):
|
||||
""" Updates an existing Tag in the database """
|
||||
db = get_database(session)
|
||||
|
||||
try:
|
||||
return db.categories.update(session, category, new_category.dict())
|
||||
return db.categories.update(category, new_category.dict())
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@@ -66,8 +71,9 @@ async def delete_recipe_category(category: str, session: Session = Depends(gener
|
||||
category does not impact a recipe. The category will be removed
|
||||
from any recipes that contain it
|
||||
"""
|
||||
db = get_database(session)
|
||||
|
||||
try:
|
||||
db.categories.delete(session, category)
|
||||
db.categories.delete(category)
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@@ -7,12 +7,10 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("", response_model=list[ReadInviteToken])
|
||||
def get_invite_tokens(g_service: GroupSelfService = Depends(GroupSelfService.write_existing)):
|
||||
def get_invite_tokens(g_service: GroupSelfService = Depends(GroupSelfService.private)):
|
||||
return g_service.get_invite_tokens()
|
||||
|
||||
|
||||
@router.post("", response_model=ReadInviteToken, status_code=status.HTTP_201_CREATED)
|
||||
def create_invite_token(
|
||||
uses: CreateInviteToken, g_service: GroupSelfService = Depends(GroupSelfService.write_existing)
|
||||
):
|
||||
def create_invite_token(uses: CreateInviteToken, g_service: GroupSelfService = Depends(GroupSelfService.private)):
|
||||
return g_service.create_invite_token(uses.uses)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from . import crud, helpers, mealplans
|
||||
|
||||
meal_plan_router = APIRouter()
|
||||
|
||||
meal_plan_router.include_router(crud.router)
|
||||
meal_plan_router.include_router(crud.public_router)
|
||||
meal_plan_router.include_router(helpers.router)
|
||||
meal_plan_router.include_router(mealplans.router)
|
||||
@@ -1,126 +0,0 @@
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.meal_plan import MealPlanIn, MealPlanOut
|
||||
from mealie.schema.user import GroupInDB, PrivateUser
|
||||
from mealie.services.events import create_group_event
|
||||
from mealie.services.image import image
|
||||
from mealie.services.meal_services import get_todays_meal, set_mealplan_dates
|
||||
|
||||
router = UserAPIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
|
||||
public_router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
|
||||
|
||||
|
||||
@router.get("/all", response_model=list[MealPlanOut])
|
||||
def get_all_meals(
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Returns a list of all available Meal Plan """
|
||||
|
||||
return db.groups.get_meals(session, current_user.group)
|
||||
|
||||
|
||||
@router.get("/this-week", response_model=MealPlanOut)
|
||||
def get_this_week(session: Session = Depends(generate_session), current_user: PrivateUser = Depends(get_current_user)):
|
||||
""" Returns the meal plan data for this week """
|
||||
plans = db.groups.get_meals(session, current_user.group)
|
||||
if plans:
|
||||
return plans[0]
|
||||
|
||||
|
||||
@router.get("/today", tags=["Meal Plan"])
|
||||
def get_today(session: Session = Depends(generate_session), current_user: PrivateUser = Depends(get_current_user)):
|
||||
"""
|
||||
Returns the recipe slug for the meal scheduled for today.
|
||||
If no meal is scheduled nothing is returned
|
||||
"""
|
||||
|
||||
group_in_db: GroupInDB = db.groups.get(session, current_user.group, "name")
|
||||
recipe = get_todays_meal(session, group_in_db)
|
||||
if recipe:
|
||||
return recipe
|
||||
|
||||
|
||||
@public_router.get("/today/image", tags=["Meal Plan"])
|
||||
def get_todays_image(session: Session = Depends(generate_session), group_name: str = "Home"):
|
||||
"""
|
||||
Returns the image for todays meal-plan.
|
||||
"""
|
||||
|
||||
group_in_db: GroupInDB = db.groups.get(session, group_name, "name")
|
||||
recipe = get_todays_meal(session, group_in_db)
|
||||
recipe_image = recipe.image_dir.joinpath(image.ImageOptions.ORIGINAL_IMAGE)
|
||||
|
||||
if not recipe and not recipe_image.exists():
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
||||
|
||||
return FileResponse(recipe_image)
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=MealPlanOut)
|
||||
def get_meal_plan(
|
||||
id,
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Returns a single Meal Plan from the Database """
|
||||
|
||||
return db.meals.get(session, id)
|
||||
|
||||
|
||||
@router.post("/create", status_code=status.HTTP_201_CREATED)
|
||||
def create_meal_plan(
|
||||
background_tasks: BackgroundTasks,
|
||||
data: MealPlanIn,
|
||||
session: Session = Depends(generate_session),
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
""" Creates a meal plan database entry """
|
||||
set_mealplan_dates(data)
|
||||
background_tasks.add_task(
|
||||
create_group_event, "Meal Plan Created", f"Mealplan Created for '{current_user.group}'", session=session
|
||||
)
|
||||
return db.meals.create(session, data.dict())
|
||||
|
||||
|
||||
@router.put("/{plan_id}")
|
||||
def update_meal_plan(
|
||||
background_tasks: BackgroundTasks,
|
||||
plan_id: str,
|
||||
meal_plan: MealPlanIn,
|
||||
session: Session = Depends(generate_session),
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
""" Updates a meal plan based off ID """
|
||||
set_mealplan_dates(meal_plan)
|
||||
processed_plan = MealPlanOut(id=plan_id, **meal_plan.dict())
|
||||
try:
|
||||
db.meals.update(session, plan_id, processed_plan.dict())
|
||||
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: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
""" Removes a meal plan from the database """
|
||||
|
||||
try:
|
||||
db.meals.delete(session, plan_id)
|
||||
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)
|
||||
@@ -1,50 +0,0 @@
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.meal_plan import ListItem, MealPlanOut, ShoppingListIn, ShoppingListOut
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.schema.user import PrivateUser
|
||||
|
||||
logger = get_logger()
|
||||
|
||||
router = UserAPIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
|
||||
|
||||
|
||||
@router.get("/{id}/shopping-list")
|
||||
def get_shopping_list(
|
||||
id: str,
|
||||
session: Session = Depends(generate_session),
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
|
||||
mealplan: MealPlanOut = db.meals.get(session, id)
|
||||
|
||||
all_ingredients = []
|
||||
|
||||
for plan_day in mealplan.plan_days:
|
||||
for meal in plan_day.meals:
|
||||
if not meal.slug:
|
||||
continue
|
||||
|
||||
try:
|
||||
recipe: Recipe = db.recipes.get(session, meal.slug)
|
||||
all_ingredients += recipe.recipe_ingredient
|
||||
except Exception:
|
||||
logger.error("Recipe Not Found")
|
||||
|
||||
new_list = ShoppingListIn(
|
||||
name="MealPlan Shopping List", group=current_user.group, items=[ListItem(text=t.note) for t in all_ingredients]
|
||||
)
|
||||
|
||||
created_list: ShoppingListOut = db.shopping_lists.create(session, new_list)
|
||||
|
||||
mealplan.shopping_list = created_list.id
|
||||
|
||||
db.meals.update(session, mealplan.id, mealplan)
|
||||
|
||||
return created_list
|
||||
@@ -1,8 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from mealie.routes.mealplans import crud, helpers
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
router.include_router(crud.router)
|
||||
router.include_router(helpers.router)
|
||||
@@ -1,7 +1,7 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.schema.recipe import RecipeSummary
|
||||
|
||||
@@ -10,9 +10,11 @@ router = APIRouter()
|
||||
|
||||
@router.get("/summary/untagged", response_model=list[RecipeSummary])
|
||||
async def get_untagged_recipes(count: bool = False, session: Session = Depends(generate_session)):
|
||||
return db.recipes.count_untagged(session, count=count, override_schema=RecipeSummary)
|
||||
db = get_database(session)
|
||||
return db.recipes.count_untagged(count=count, override_schema=RecipeSummary)
|
||||
|
||||
|
||||
@router.get("/summary/uncategorized", response_model=list[RecipeSummary])
|
||||
async def get_uncategorized_recipes(count: bool = False, session: Session = Depends(generate_session)):
|
||||
return db.recipes.count_uncategorized(session, count=count, override_schema=RecipeSummary)
|
||||
db = get_database(session)
|
||||
return db.recipes.count_uncategorized(count=count, override_schema=RecipeSummary)
|
||||
|
||||
@@ -4,7 +4,7 @@ from fastapi import Depends, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import CommentOut, CreateComment, SaveComment
|
||||
@@ -21,9 +21,10 @@ async def create_comment(
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
""" Create comment in the Database """
|
||||
db = get_database(session)
|
||||
|
||||
new_comment = SaveComment(user=current_user.id, text=new_comment.text, recipe_slug=slug)
|
||||
return db.comments.create(session, new_comment)
|
||||
return db.comments.create(new_comment)
|
||||
|
||||
|
||||
@router.put("/{slug}/comments/{id}")
|
||||
@@ -34,12 +35,13 @@ async def update_comment(
|
||||
current_user: PrivateUser = Depends(get_current_user),
|
||||
):
|
||||
""" Update comment in the Database """
|
||||
old_comment: CommentOut = db.comments.get(session, id)
|
||||
db = get_database(session)
|
||||
old_comment: CommentOut = db.comments.get(id)
|
||||
|
||||
if current_user.id != old_comment.user.id:
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
return db.comments.update(session, id, new_comment)
|
||||
return db.comments.update(id, new_comment)
|
||||
|
||||
|
||||
@router.delete("/{slug}/comments/{id}")
|
||||
@@ -47,9 +49,10 @@ async def delete_comment(
|
||||
id: int, session: Session = Depends(generate_session), current_user: PrivateUser = Depends(get_current_user)
|
||||
):
|
||||
""" Delete comment from the Database """
|
||||
comment: CommentOut = db.comments.get(session, id)
|
||||
db = get_database(session)
|
||||
comment: CommentOut = db.comments.get(id)
|
||||
if current_user.id == comment.user.id or current_user.admin:
|
||||
db.comments.delete(session, id)
|
||||
db.comments.delete(id)
|
||||
return
|
||||
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@@ -5,7 +5,7 @@ from fastapi.datastructures import UploadFile
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeAsset
|
||||
@@ -32,8 +32,9 @@ def update_recipe_image(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Removes an existing image and replaces it with the incoming file. """
|
||||
db = get_database(session)
|
||||
write_image(slug, image, extension)
|
||||
new_version = db.recipes.update_image(session, slug, extension)
|
||||
new_version = db.recipes.update_image(slug, extension)
|
||||
|
||||
return {"image": new_version}
|
||||
|
||||
@@ -58,7 +59,9 @@ def upload_recipe_asset(
|
||||
if not dest.is_file():
|
||||
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
recipe: Recipe = db.recipes.get(session, slug)
|
||||
db = get_database(session)
|
||||
|
||||
recipe: Recipe = db.recipes.get(slug)
|
||||
recipe.assets.append(asset_in)
|
||||
db.recipes.update(session, slug, recipe.dict())
|
||||
db.recipes.update(slug, recipe.dict())
|
||||
return asset_in
|
||||
|
||||
@@ -10,7 +10,7 @@ from starlette.responses import FileResponse
|
||||
|
||||
from mealie.core.dependencies import temporary_zip_path
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeImageTypes
|
||||
@@ -71,7 +71,9 @@ async def create_recipe_from_zip(
|
||||
with myzip.open(file) as myfile:
|
||||
recipe_image = myfile.read()
|
||||
|
||||
recipe: Recipe = db.recipes.create(session, Recipe(**recipe_dict))
|
||||
db = get_database(session)
|
||||
|
||||
recipe: Recipe = db.recipes.create(Recipe(**recipe_dict))
|
||||
|
||||
write_image(recipe.slug, recipe_image, "webp")
|
||||
|
||||
@@ -89,7 +91,9 @@ async def get_recipe_as_zip(
|
||||
slug: str, session: Session = Depends(generate_session), temp_path=Depends(temporary_zip_path)
|
||||
):
|
||||
""" Get a Recipe and It's Original Image as a Zip File """
|
||||
recipe: Recipe = db.recipes.get(session, slug)
|
||||
db = get_database(session)
|
||||
|
||||
recipe: Recipe = db.recipes.get(slug)
|
||||
|
||||
image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
|
||||
|
||||
@@ -105,14 +109,12 @@ async def get_recipe_as_zip(
|
||||
@user_router.put("/{slug}")
|
||||
def update_recipe(data: Recipe, recipe_service: RecipeService = Depends(RecipeService.write_existing)):
|
||||
""" Updates a recipe by existing slug and data. """
|
||||
|
||||
return recipe_service.update_one(data)
|
||||
|
||||
|
||||
@user_router.patch("/{slug}")
|
||||
def patch_recipe(data: Recipe, recipe_service: RecipeService = Depends(RecipeService.write_existing)):
|
||||
""" Updates a recipe by existing slug and data. """
|
||||
|
||||
return recipe_service.patch_one(data)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from fastapi import Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut
|
||||
@@ -18,25 +18,28 @@ async def create_shopping_list(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Create Shopping List in the Database """
|
||||
|
||||
db = get_database(session)
|
||||
list_in.group = current_user.group
|
||||
|
||||
return db.shopping_lists.create(session, list_in)
|
||||
return db.shopping_lists.create(list_in)
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=ShoppingListOut)
|
||||
async def get_shopping_list(id: int, session: Session = Depends(generate_session)):
|
||||
""" Get Shopping List from the Database """
|
||||
return db.shopping_lists.get(session, id)
|
||||
db = get_database(session)
|
||||
return db.shopping_lists.get(id)
|
||||
|
||||
|
||||
@router.put("/{id}", response_model=ShoppingListOut)
|
||||
async def update_shopping_list(id: int, new_data: ShoppingListIn, session: Session = Depends(generate_session)):
|
||||
""" Update Shopping List in the Database """
|
||||
return db.shopping_lists.update(session, id, new_data)
|
||||
db = get_database(session)
|
||||
return db.shopping_lists.update(id, new_data)
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
async def delete_shopping_list(id: int, session: Session = Depends(generate_session)):
|
||||
""" Delete Shopping List from the Database """
|
||||
return db.shopping_lists.delete(session, id)
|
||||
db = get_database(session)
|
||||
return db.shopping_lists.delete(id)
|
||||
|
||||
@@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter
|
||||
from mealie.schema.admin import SiteSettings
|
||||
@@ -16,8 +16,9 @@ admin_router = AdminAPIRouter(prefix="/api/site-settings", tags=["Settings"])
|
||||
@public_router.get("")
|
||||
def get_main_settings(session: Session = Depends(generate_session)):
|
||||
""" Returns basic site settings """
|
||||
db = get_database(session)
|
||||
|
||||
return db.settings.get(session, 1)
|
||||
return db.settings.get(1)
|
||||
|
||||
|
||||
@admin_router.put("")
|
||||
@@ -26,7 +27,8 @@ def update_settings(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Returns Site Settings """
|
||||
db.settings.update(session, 1, data.dict())
|
||||
db = get_database(session)
|
||||
db.settings.update(1, data.dict())
|
||||
|
||||
|
||||
@admin_router.post("/webhooks/test")
|
||||
@@ -35,7 +37,8 @@ def test_webhooks(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Run the function to test your webhooks """
|
||||
group_entry: GroupInDB = db.groups.get(session, current_user.group, "name")
|
||||
db = get_database(session)
|
||||
group_entry: GroupInDB = db.groups.get(current_user.group, "name")
|
||||
|
||||
try:
|
||||
post_webhooks(group_entry.id, session)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm.session import Session
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from mealie.core.dependencies import is_logged_in
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||
from mealie.schema.recipe import RecipeTagResponse, TagIn
|
||||
@@ -15,13 +15,15 @@ admin_router = AdminAPIRouter()
|
||||
@public_router.get("")
|
||||
async def get_all_recipe_tags(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of available tags in the database """
|
||||
return db.tags.get_all_limit_columns(session, ["slug", "name"])
|
||||
db = get_database(session)
|
||||
return db.tags.get_all_limit_columns(["slug", "name"])
|
||||
|
||||
|
||||
@public_router.get("/empty")
|
||||
def get_empty_tags(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of tags that do not contain any recipes"""
|
||||
return db.tags.get_empty(session)
|
||||
db = get_database(session)
|
||||
return db.tags.get_empty()
|
||||
|
||||
|
||||
@public_router.get("/{tag}", response_model=RecipeTagResponse)
|
||||
@@ -29,7 +31,8 @@ def get_all_recipes_by_tag(
|
||||
tag: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
|
||||
):
|
||||
""" Returns a list of recipes associated with the provided tag. """
|
||||
tag_obj = db.tags.get(session, tag)
|
||||
db = get_database(session)
|
||||
tag_obj = db.tags.get(tag)
|
||||
tag_obj = RecipeTagResponse.from_orm(tag_obj)
|
||||
|
||||
if not is_user:
|
||||
@@ -41,15 +44,15 @@ def get_all_recipes_by_tag(
|
||||
@user_router.post("")
|
||||
async def create_recipe_tag(tag: TagIn, session: Session = Depends(generate_session)):
|
||||
""" Creates a Tag in the database """
|
||||
|
||||
return db.tags.create(session, tag.dict())
|
||||
db = get_database(session)
|
||||
return db.tags.create(tag.dict())
|
||||
|
||||
|
||||
@admin_router.put("/{tag}", response_model=RecipeTagResponse)
|
||||
async def update_recipe_tag(tag: str, new_tag: TagIn, session: Session = Depends(generate_session)):
|
||||
""" Updates an existing Tag in the database """
|
||||
|
||||
return db.tags.update(session, tag, new_tag.dict())
|
||||
db = get_database(session)
|
||||
return db.tags.update(tag, new_tag.dict())
|
||||
|
||||
|
||||
@admin_router.delete("/{tag}")
|
||||
@@ -59,6 +62,7 @@ async def delete_recipe_tag(tag: str, session: Session = Depends(generate_sessio
|
||||
from any recipes that contain it"""
|
||||
|
||||
try:
|
||||
db.tags.delete(session, tag)
|
||||
db = get_database(session)
|
||||
db.tags.delete(tag)
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from . import food_routes, unit_routes
|
||||
from mealie.services._base_http_service.router_factory import RouterFactory
|
||||
from mealie.services.recipe.recipe_food_service import RecipeFoodService
|
||||
from mealie.services.recipe.recipe_unit_service import RecipeUnitService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
router.include_router(food_routes.router, prefix="/foods", tags=["Recipes: Foods"])
|
||||
router.include_router(unit_routes.router, prefix="/units", tags=["Recipes: Units"])
|
||||
router.include_router(RouterFactory(RecipeFoodService, prefix="/foods", tags=["Recipes: Foods"]))
|
||||
router.include_router(RouterFactory(RecipeUnitService, prefix="/units", tags=["Recipes: Units"]))
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
from fastapi import Depends, status
|
||||
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import Session, generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import CreateIngredientFood, IngredientFood
|
||||
|
||||
router = UserAPIRouter()
|
||||
|
||||
|
||||
@router.get("", response_model=list[IngredientFood])
|
||||
async def get_all(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Get unit from the Database """
|
||||
# Get unit
|
||||
return db.ingredient_foods.get_all(session)
|
||||
|
||||
|
||||
@router.post("", response_model=IngredientFood, status_code=status.HTTP_201_CREATED)
|
||||
async def create_food(unit: CreateIngredientFood, session: Session = Depends(generate_session)):
|
||||
""" Create unit in the Database """
|
||||
|
||||
return db.ingredient_foods.create(session, unit)
|
||||
|
||||
|
||||
@router.get("/{id}")
|
||||
async def get_food(id: str, session: Session = Depends(generate_session)):
|
||||
""" Get unit from the Database """
|
||||
|
||||
return db.ingredient_foods.get(session, id)
|
||||
|
||||
|
||||
@router.put("/{id}")
|
||||
async def update_food(id: str, unit: CreateIngredientFood, session: Session = Depends(generate_session)):
|
||||
""" Update unit in the Database """
|
||||
|
||||
return db.ingredient_foods.update(session, id, unit)
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
async def delete_food(id: str, session: Session = Depends(generate_session)):
|
||||
""" Delete unit from the Database """
|
||||
return db.ingredient_foods.delete(session, id)
|
||||
@@ -1,44 +0,0 @@
|
||||
from fastapi import Depends, status
|
||||
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import Session, generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import CreateIngredientUnit, IngredientUnit
|
||||
|
||||
router = UserAPIRouter()
|
||||
|
||||
|
||||
@router.get("", response_model=list[IngredientUnit])
|
||||
async def get_all(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Get unit from the Database """
|
||||
# Get unit
|
||||
return db.ingredient_units.get_all(session)
|
||||
|
||||
|
||||
@router.post("", response_model=IngredientUnit, status_code=status.HTTP_201_CREATED)
|
||||
async def create_unit(unit: CreateIngredientUnit, session: Session = Depends(generate_session)):
|
||||
""" Create unit in the Database """
|
||||
|
||||
return db.ingredient_units.create(session, unit)
|
||||
|
||||
|
||||
@router.get("/{id}")
|
||||
async def get_unit(id: str, session: Session = Depends(generate_session)):
|
||||
""" Get unit from the Database """
|
||||
|
||||
return db.ingredient_units.get(session, id)
|
||||
|
||||
|
||||
@router.put("/{id}")
|
||||
async def update_unit(id: str, unit: CreateIngredientUnit, session: Session = Depends(generate_session)):
|
||||
""" Update unit in the Database """
|
||||
|
||||
return db.ingredient_units.update(session, id, unit)
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
async def delete_unit(id: str, session: Session = Depends(generate_session)):
|
||||
""" Delete unit from the Database """
|
||||
return db.ingredient_units.delete(session, id)
|
||||
@@ -6,7 +6,7 @@ from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.core.security import create_access_token
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, PrivateUser
|
||||
@@ -33,7 +33,9 @@ async def create_api_token(
|
||||
parent_id=current_user.id,
|
||||
)
|
||||
|
||||
new_token_in_db = db.api_tokens.create(session, token_model)
|
||||
db = get_database(session)
|
||||
|
||||
new_token_in_db = db.api_tokens.create(token_model)
|
||||
|
||||
if new_token_in_db:
|
||||
return {"token": token}
|
||||
@@ -46,13 +48,14 @@ async def delete_api_token(
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Delete api_token from the Database """
|
||||
token: LongLiveTokenInDB = db.api_tokens.get(session, token_id)
|
||||
db = get_database(session)
|
||||
token: LongLiveTokenInDB = db.api_tokens.get(token_id)
|
||||
|
||||
if not token:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Could not locate token with id '{token_id}' in database")
|
||||
|
||||
if token.user.email == current_user.email:
|
||||
deleted_token = db.api_tokens.delete(session, token_id)
|
||||
deleted_token = db.api_tokens.delete(token_id)
|
||||
return {"token_delete": deleted_token.name}
|
||||
else:
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@@ -4,7 +4,7 @@ from sqlalchemy.orm.session import Session
|
||||
from mealie.core import security
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.core.security import hash_password
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||
@@ -17,7 +17,8 @@ admin_router = AdminAPIRouter(prefix="")
|
||||
|
||||
@admin_router.get("", response_model=list[UserOut])
|
||||
async def get_all_users(session: Session = Depends(generate_session)):
|
||||
return db.users.get_all(session)
|
||||
db = get_database(session)
|
||||
return db.users.get_all()
|
||||
|
||||
|
||||
@admin_router.post("", response_model=UserOut, status_code=201)
|
||||
@@ -33,12 +34,14 @@ async def create_user(
|
||||
create_user_event, "User Created", f"Created by {current_user.full_name}", session=session
|
||||
)
|
||||
|
||||
return db.users.create(session, new_user.dict())
|
||||
db = get_database(session)
|
||||
return db.users.create(new_user.dict())
|
||||
|
||||
|
||||
@admin_router.get("/{id}", response_model=UserOut)
|
||||
async def get_user(id: int, session: Session = Depends(generate_session)):
|
||||
return db.users.get(session, id)
|
||||
db = get_database(session)
|
||||
return db.users.get(id)
|
||||
|
||||
|
||||
@admin_router.delete("/{id}")
|
||||
@@ -56,7 +59,8 @@ def delete_user(
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER")
|
||||
|
||||
try:
|
||||
db.users.delete(session, id)
|
||||
db = get_database(session)
|
||||
db.users.delete(id)
|
||||
background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session)
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
@@ -87,7 +91,9 @@ async def update_user(
|
||||
# prevent an admin from demoting themself
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
db.users.update(session, id, new_data.dict())
|
||||
db = get_database(session)
|
||||
db.users.update(id, new_data.dict())
|
||||
|
||||
if current_user.id == id:
|
||||
access_token = security.create_access_token(data=dict(sub=new_data.email))
|
||||
return {"access_token": access_token, "token_type": "bearer"}
|
||||
|
||||
@@ -2,7 +2,7 @@ from fastapi import Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||
@@ -14,8 +14,8 @@ user_router = UserAPIRouter()
|
||||
@user_router.get("/{id}/favorites", response_model=UserFavorites)
|
||||
async def get_favorites(id: str, session: Session = Depends(generate_session)):
|
||||
""" Get user's favorite recipes """
|
||||
|
||||
return db.users.get(session, id, override_schema=UserFavorites)
|
||||
db = get_database(session)
|
||||
return db.users.get(id, override_schema=UserFavorites)
|
||||
|
||||
|
||||
@user_router.post("/{id}/favorites/{slug}")
|
||||
@@ -29,7 +29,8 @@ def add_favorite(
|
||||
assert_user_change_allowed(id, current_user)
|
||||
current_user.favorite_recipes.append(slug)
|
||||
|
||||
db.users.update(session, current_user.id, current_user)
|
||||
db = get_database(session)
|
||||
db.users.update(current_user.id, current_user)
|
||||
|
||||
|
||||
@user_router.delete("/{id}/favorites/{slug}")
|
||||
@@ -43,6 +44,7 @@ def remove_favorite(
|
||||
assert_user_change_allowed(id, current_user)
|
||||
current_user.favorite_recipes = [x for x in current_user.favorite_recipes if x != slug]
|
||||
|
||||
db.users.update(session, current_user.id, current_user)
|
||||
db = get_database(session)
|
||||
db.users.update(current_user.id, current_user)
|
||||
|
||||
return
|
||||
|
||||
@@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.config import settings
|
||||
from mealie.core.security import hash_password
|
||||
from mealie.db.database import db
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import UserAPIRouter
|
||||
from mealie.schema.user import ChangePassword
|
||||
@@ -15,7 +15,9 @@ user_router = UserAPIRouter(prefix="")
|
||||
@user_router.put("/{id}/reset-password")
|
||||
async def reset_user_password(id: int, session: Session = Depends(generate_session)):
|
||||
new_password = hash_password(settings.DEFAULT_PASSWORD)
|
||||
db.users.update_password(session, id, new_password)
|
||||
|
||||
db = get_database(session)
|
||||
db.users.update_password(id, new_password)
|
||||
|
||||
|
||||
@user_router.put("/{id}/password")
|
||||
|
||||
Reference in New Issue
Block a user