mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-27 20:55:12 -05:00
feat(backend): ✨ add rename tag, tool, category support (#875)
This commit is contained in:
@@ -28,10 +28,9 @@ from mealie.schema.group.group_preferences import ReadGroupPreferences
|
||||
from mealie.schema.group.invite_token import ReadInviteToken
|
||||
from mealie.schema.group.webhook import ReadWebhook
|
||||
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
|
||||
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse
|
||||
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse, RecipeTool
|
||||
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
|
||||
from mealie.schema.recipe.recipe_share_token import RecipeShareToken
|
||||
from mealie.schema.recipe.recipe_tool import RecipeTool
|
||||
from mealie.schema.reports.reports import ReportEntryOut, ReportOut
|
||||
from mealie.schema.server import ServerTask
|
||||
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from slugify import slugify
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, orm
|
||||
|
||||
from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase
|
||||
@@ -14,10 +15,10 @@ recipes_to_tools = Table(
|
||||
class Tool(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "tools"
|
||||
name = Column(String, index=True, unique=True, nullable=False)
|
||||
slug = Column(String, index=True, unique=True, nullable=False)
|
||||
on_hand = Column(Boolean, default=False)
|
||||
recipes = orm.relationship("RecipeModel", secondary=recipes_to_tools, back_populates="tools")
|
||||
|
||||
@auto_init()
|
||||
def __init__(self, name, on_hand, **_) -> None:
|
||||
self.on_hand = on_hand
|
||||
self.name = name
|
||||
def __init__(self, name, **_) -> None:
|
||||
self.slug = slugify(name)
|
||||
|
||||
@@ -2,6 +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.core.root_logger import get_logger
|
||||
from mealie.db.database import get_database
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||
@@ -10,6 +11,7 @@ from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
|
||||
public_router = APIRouter()
|
||||
user_router = UserAPIRouter()
|
||||
admin_router = AdminAPIRouter()
|
||||
logger = get_logger()
|
||||
|
||||
|
||||
@public_router.get("")
|
||||
@@ -61,6 +63,7 @@ async def update_recipe_category(category: str, new_category: CategoryIn, sessio
|
||||
try:
|
||||
return db.categories.update(category, new_category.dict())
|
||||
except Exception:
|
||||
logger.exception("Failed to update category")
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import APIRouter, Depends
|
||||
|
||||
from mealie.schema.recipe.recipe_tool import RecipeToolResponse
|
||||
from mealie.services._base_http_service.router_factory import RouterFactory
|
||||
from mealie.services.recipe.recipe_tool_service import RecipeToolService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
router.include_router(RouterFactory(RecipeToolService, prefix="/tools", tags=["Recipes: Tools"]))
|
||||
tools_router = RouterFactory(RecipeToolService, prefix="/tools", tags=["Recipes: Tools"])
|
||||
|
||||
|
||||
@tools_router.get("/slug/{slug}")
|
||||
async def Func(slug: str, tools_service: RecipeToolService = Depends(RecipeToolService.private)):
|
||||
"""Returns a recipe by slug."""
|
||||
return tools_service.db.tools.get_one(slug, "slug", override_schema=RecipeToolResponse)
|
||||
|
||||
|
||||
router.include_router(tools_router)
|
||||
|
||||
@@ -3,4 +3,5 @@ from .recipe_category import *
|
||||
from .recipe_comments import *
|
||||
from .recipe_image_types import *
|
||||
from .recipe_ingredient import *
|
||||
from .recipe_tool import *
|
||||
from .request_helpers import *
|
||||
|
||||
@@ -18,7 +18,6 @@ from .recipe_notes import RecipeNote
|
||||
from .recipe_nutrition import Nutrition
|
||||
from .recipe_settings import RecipeSettings
|
||||
from .recipe_step import RecipeStep
|
||||
from .recipe_tool import RecipeTool
|
||||
|
||||
app_dirs = get_app_dirs()
|
||||
|
||||
@@ -35,6 +34,11 @@ class RecipeCategory(RecipeTag):
|
||||
pass
|
||||
|
||||
|
||||
class RecipeTool(RecipeTag):
|
||||
id: int = 0
|
||||
on_hand: bool = False
|
||||
|
||||
|
||||
class CreateRecipeByUrl(BaseModel):
|
||||
url: str
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class RecipeTagResponse(RecipeCategoryResponse):
|
||||
pass
|
||||
|
||||
|
||||
from .recipe import Recipe
|
||||
from . import Recipe
|
||||
|
||||
RecipeCategoryResponse.update_forward_refs()
|
||||
RecipeTagResponse.update_forward_refs()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from typing import List
|
||||
|
||||
from fastapi_camelcase import CamelModel
|
||||
|
||||
|
||||
@@ -8,6 +10,19 @@ class RecipeToolCreate(CamelModel):
|
||||
|
||||
class RecipeTool(RecipeToolCreate):
|
||||
id: int
|
||||
slug: str
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class RecipeToolResponse(RecipeTool):
|
||||
recipes: List["Recipe"] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
from .recipe import Recipe
|
||||
|
||||
RecipeToolResponse.update_forward_refs()
|
||||
|
||||
@@ -63,7 +63,7 @@ class MealieAlphaMigrator(BaseMigrator):
|
||||
recipe_lookup: dict[str, Path] = {}
|
||||
recipes_as_dicts = []
|
||||
|
||||
for x in temp_path.rglob("**/[!.]*.json"):
|
||||
for x in temp_path.rglob("**/recipes/**/[!.]*.json"):
|
||||
if (y := MigrationReaders.json(x)) is not None:
|
||||
recipes_as_dicts.append(y)
|
||||
slug = y["slug"]
|
||||
@@ -76,12 +76,16 @@ class MealieAlphaMigrator(BaseMigrator):
|
||||
recipe_model_lookup = {x.slug: x for x in recipes}
|
||||
|
||||
for slug, status in results:
|
||||
if status:
|
||||
model = recipe_model_lookup.get(slug)
|
||||
dest_dir = model.directory
|
||||
source_dir = recipe_lookup.get(slug)
|
||||
if not status:
|
||||
continue
|
||||
|
||||
if dest_dir.exists():
|
||||
shutil.rmtree(dest_dir)
|
||||
model = recipe_model_lookup.get(slug)
|
||||
dest_dir = model.directory
|
||||
source_dir = recipe_lookup.get(slug)
|
||||
|
||||
shutil.copytree(source_dir, dest_dir)
|
||||
if dest_dir.exists():
|
||||
shutil.rmtree(dest_dir)
|
||||
|
||||
for dir in source_dir.iterdir():
|
||||
if dir.is_dir():
|
||||
shutil.copytree(dir, dest_dir / dir.name)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
import re
|
||||
import tempfile
|
||||
import zipfile
|
||||
from gzip import GzipFile
|
||||
from pathlib import Path
|
||||
|
||||
import regex as re
|
||||
from slugify import slugify
|
||||
|
||||
from mealie.schema.recipe import RecipeNote
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from functools import cached_property
|
||||
|
||||
from mealie.schema.recipe.recipe_tool import RecipeTool, RecipeToolCreate
|
||||
from mealie.schema.recipe import RecipeTool, RecipeToolCreate
|
||||
from mealie.services._base_http_service.crud_http_mixins import CrudHttpMixins
|
||||
from mealie.services._base_http_service.http_services import UserHttpService
|
||||
from mealie.services.events import create_recipe_event
|
||||
|
||||
Reference in New Issue
Block a user