diff --git a/mealie/routes/backup_routes.py b/mealie/routes/backup_routes.py index abeaed57c..823543192 100644 --- a/mealie/routes/backup_routes.py +++ b/mealie/routes/backup_routes.py @@ -1,28 +1,33 @@ +import operator + +from app_config import BACKUP_DIR, TEMPLATE_DIR from fastapi import APIRouter, HTTPException -from models.backup_models import BackupJob, Imports +from models.backup_models import BackupJob, ImportJob, Imports, LocalBackup from services.backups.exports import backup_all from services.backups.imports import ImportDatabase -from settings import BACKUP_DIR, TEMPLATE_DIR from utils.snackbar import SnackResponse -router = APIRouter() +router = APIRouter(tags=["Import / Export"]) -@router.get("/api/backups/available/", tags=["Import / Export"], response_model=Imports) +@router.get("/api/backups/available/", response_model=Imports) def available_imports(): """Returns a list of avaiable .zip files for import into Mealie.""" imports = [] templates = [] for archive in BACKUP_DIR.glob("*.zip"): - imports.append(archive.name) + backup = LocalBackup(name=archive.name, date=archive.stat().st_ctime) + imports.append(backup) for template in TEMPLATE_DIR.glob("*.md"): templates.append(template.name) + imports.sort(key=operator.attrgetter("date"), reverse=True) + return Imports(imports=imports, templates=templates) -@router.post("/api/backups/export/database/", tags=["Import / Export"], status_code=201) +@router.post("/api/backups/export/database/", status_code=201) def export_database(data: BackupJob): """Generates a backup of the recipe database in json format.""" export_path = backup_all(data.tag, data.template) @@ -35,17 +40,17 @@ def export_database(data: BackupJob): ) -@router.post( - "/api/backups/{file_name}/import/", tags=["Import / Export"], status_code=200 -) -def import_database(file_name: str): +@router.post("/api/backups/{file_name}/import/", status_code=200) +def import_database(file_name: str, import_data: ImportJob): """ Import a database backup file generated from Mealie. """ import_db = ImportDatabase( - zip_archive=file_name, - import_recipes=True, - import_settings=False, - import_themes=False, + zip_archive=import_data.name, + import_recipes=import_data.recipes, + force_import=import_data.force, + rebase=import_data.rebase, + import_settings=import_data.settings, + import_themes=import_data.themes, ) imported = import_db.run() diff --git a/mealie/routes/meal_routes.py b/mealie/routes/meal_routes.py index efd4ebe82..8e9663043 100644 --- a/mealie/routes/meal_routes.py +++ b/mealie/routes/meal_routes.py @@ -1,21 +1,20 @@ from typing import List from fastapi import APIRouter, HTTPException -from models.recipe_models import SlugResponse from services.meal_services import MealPlan from utils.snackbar import SnackResponse -router = APIRouter() +router = APIRouter(tags=["Meal Plan"]) -@router.get("/api/meal-plan/all/", tags=["Meal Plan"], response_model=List[MealPlan]) +@router.get("/api/meal-plan/all/", response_model=List[MealPlan]) def get_all_meals(): """ Returns a list of all available Meal Plan """ return MealPlan.get_all() -@router.post("/api/meal-plan/create/", tags=["Meal Plan"]) +@router.post("/api/meal-plan/create/") def set_meal_plan(data: MealPlan): """ Creates a meal plan database entry """ data.process_meals() @@ -29,7 +28,7 @@ def set_meal_plan(data: MealPlan): return SnackResponse.success("Mealplan Created") -@router.post("/api/meal-plan/{plan_id}/update/", tags=["Meal Plan"]) +@router.post("/api/meal-plan/{plan_id}/update/") def update_meal_plan(plan_id: str, meal_plan: MealPlan): """ Updates a meal plan based off ID """ meal_plan.process_meals() @@ -46,7 +45,7 @@ def update_meal_plan(plan_id: str, meal_plan: MealPlan): return SnackResponse.success("Mealplan Updated") -@router.delete("/api/meal-plan/{plan_id}/delete/", tags=["Meal Plan"]) +@router.delete("/api/meal-plan/{plan_id}/delete/") def delete_meal_plan(plan_id): """ Removes a meal plan from the database """ @@ -68,7 +67,7 @@ def get_today(): return MealPlan.today() -@router.get("/api/meal-plan/this-week/", tags=["Meal Plan"], response_model=MealPlan) +@router.get("/api/meal-plan/this-week/", response_model=MealPlan) def get_this_week(): """ Returns the meal plan data for this week """ diff --git a/mealie/routes/migration_routes.py b/mealie/routes/migration_routes.py index 76e48002d..49eccc2c8 100644 --- a/mealie/routes/migration_routes.py +++ b/mealie/routes/migration_routes.py @@ -4,14 +4,14 @@ from fastapi import APIRouter, File, HTTPException, UploadFile from models.migration_models import ChowdownURL from services.migrations.chowdown import chowdown_migrate as chowdow_migrate from services.migrations.nextcloud import migrate as nextcloud_migrate -from settings import MIGRATION_DIR +from app_config import MIGRATION_DIR from utils.snackbar import SnackResponse -router = APIRouter() +router = APIRouter(tags=["Migration"]) # Chowdown -@router.post("/api/migration/chowdown/repo/", tags=["Migration"]) +@router.post("/api/migration/chowdown/repo/") def import_chowdown_recipes(repo: ChowdownURL): """ Import Chowsdown Recipes from Repo URL """ try: @@ -30,7 +30,7 @@ def import_chowdown_recipes(repo: ChowdownURL): # Nextcloud -@router.get("/api/migration/nextcloud/available/", tags=["Migration"]) +@router.get("/api/migration/nextcloud/available/") def get_avaiable_nextcloud_imports(): """ Returns a list of avaiable directories that can be imported into Mealie """ available = [] @@ -43,14 +43,14 @@ def get_avaiable_nextcloud_imports(): return available -@router.post("/api/migration/nextcloud/{selection}/import/", tags=["Migration"]) +@router.post("/api/migration/nextcloud/{selection}/import/") def import_nextcloud_directory(selection: str): """ Imports all the recipes in a given directory """ return nextcloud_migrate(selection) -@router.delete("/api/migration/{file_folder_name}/delete/", tags=["Migration"]) +@router.delete("/api/migration/{file_folder_name}/delete/") def delete_migration_data(file_folder_name: str): """ Removes migration data from the file system """ @@ -66,7 +66,7 @@ def delete_migration_data(file_folder_name: str): return SnackResponse.info(f"Migration Data Remove: {remove_path.absolute()}") -@router.post("/api/migration/upload/", tags=["Migration"]) +@router.post("/api/migration/upload/") def upload_nextcloud_zipfile(archive: UploadFile = File(...)): """ Upload a .zip File to later be imported into Mealie """ dest = MIGRATION_DIR.joinpath(archive.filename) diff --git a/mealie/routes/recipe_routes.py b/mealie/routes/recipe_routes.py index 520e495c5..eadf7046f 100644 --- a/mealie/routes/recipe_routes.py +++ b/mealie/routes/recipe_routes.py @@ -8,10 +8,10 @@ from services.recipe_services import Recipe, read_requested_values from services.scrape_services import create_from_url from utils.snackbar import SnackResponse -router = APIRouter() +router = APIRouter(tags=["Recipes"]) -@router.get("/api/all-recipes/", tags=["Recipes"], response_model=List[dict]) +@router.get("/api/all-recipes/", response_model=List[dict]) def get_all_recipes(keys: Optional[List[str]] = Query(...), num: Optional[int] = 100): """ Returns key data for all recipes based off the query paramters provided. @@ -28,7 +28,7 @@ def get_all_recipes(keys: Optional[List[str]] = Query(...), num: Optional[int] = return all_recipes -@router.post("/api/all-recipes/", tags=["Recipes"], response_model=List[dict]) +@router.post("/api/all-recipes/", response_model=List[dict]) def get_all_recipes_post(body: AllRecipeRequest): """ Returns key data for all recipes based off the body data provided. @@ -44,7 +44,7 @@ def get_all_recipes_post(body: AllRecipeRequest): return all_recipes -@router.get("/api/recipe/{recipe_slug}/", tags=["Recipes"], response_model=Recipe) +@router.get("/api/recipe/{recipe_slug}/", response_model=Recipe) def get_recipe(recipe_slug: str): """ Takes in a recipe slug, returns all data for a recipe """ recipe = Recipe.get_by_slug(recipe_slug) @@ -52,7 +52,7 @@ def get_recipe(recipe_slug: str): return recipe -@router.get("/api/recipe/image/{recipe_slug}/", tags=["Recipes"]) +@router.get("/api/recipe/image/{recipe_slug}/") def get_recipe_img(recipe_slug: str): """ Takes in a recipe slug, returns the static image """ recipe_image = read_image(recipe_slug) @@ -75,7 +75,7 @@ def parse_recipe_url(url: RecipeURLIn): return slug -@router.post("/api/recipe/create/", tags=["Recipes"]) +@router.post("/api/recipe/create/") def create_from_json(data: Recipe) -> str: """ Takes in a JSON string and loads data into the database as a new entry""" created_recipe = data.save_to_db() @@ -83,7 +83,7 @@ def create_from_json(data: Recipe) -> str: return created_recipe -@router.post("/api/recipe/{recipe_slug}/update/image/", tags=["Recipes"]) +@router.post("/api/recipe/{recipe_slug}/update/image/") def update_recipe_image( recipe_slug: str, image: bytes = File(...), extension: str = Form(...) ): @@ -94,7 +94,7 @@ def update_recipe_image( return response -@router.post("/api/recipe/{recipe_slug}/update/", tags=["Recipes"]) +@router.post("/api/recipe/{recipe_slug}/update/") def update_recipe(recipe_slug: str, data: Recipe): """ Updates a recipe by existing slug and data. """ @@ -103,7 +103,7 @@ def update_recipe(recipe_slug: str, data: Recipe): return new_slug -@router.delete("/api/recipe/{recipe_slug}/delete/", tags=["Recipes"]) +@router.delete("/api/recipe/{recipe_slug}/delete/") def delete_recipe(recipe_slug: str): """ Deletes a recipe by slug """ diff --git a/mealie/routes/setting_routes.py b/mealie/routes/setting_routes.py index db7c6fb73..a30875c50 100644 --- a/mealie/routes/setting_routes.py +++ b/mealie/routes/setting_routes.py @@ -4,24 +4,24 @@ from services.settings_services import SiteSettings, SiteTheme from utils.global_scheduler import scheduler from utils.snackbar import SnackResponse -router = APIRouter() +router = APIRouter(tags=["Settings"]) -@router.get("/api/site-settings/", tags=["Settings"]) +@router.get("/api/site-settings/") def get_main_settings(): """ Returns basic site settings """ return SiteSettings.get_site_settings() -@router.post("/api/site-settings/webhooks/test/", tags=["Settings"]) +@router.post("/api/site-settings/webhooks/test/") def test_webhooks(): """ Run the function to test your webhooks """ return post_webhooks() -@router.post("/api/site-settings/update/", tags=["Settings"]) +@router.post("/api/site-settings/update/") def update_settings(data: SiteSettings): """ Returns Site Settings """ data.update() diff --git a/mealie/routes/static_routes.py b/mealie/routes/static_routes.py index 01efe5227..6744b6972 100644 --- a/mealie/routes/static_routes.py +++ b/mealie/routes/static_routes.py @@ -6,19 +6,19 @@ from fastapi.responses import FileResponse CWD = Path(__file__).parent WEB_PATH = CWD.parent.joinpath("dist") BASE_HTML = WEB_PATH.joinpath("index.html") -router = APIRouter() +router = APIRouter(include_in_schema=False) -@router.get("/favicon.ico", include_in_schema=False) +@router.get("/favicon.ico") def facivon(): return responses.RedirectResponse(url="/mealie/favicon.ico") -@router.get("/", include_in_schema=False) +@router.get("/") def root(): return FileResponse(BASE_HTML) -@router.get("/{full_path:path}", include_in_schema=False) +@router.get("/{full_path:path}") def root_plus(full_path): return FileResponse(BASE_HTML)