diff --git a/.flake8 b/.flake8
index b90fca4d20a6..b764320ebfd3 100644
--- a/.flake8
+++ b/.flake8
@@ -1,6 +1,6 @@
[flake8]
ignore = [
E501 # Line Length - See Black Config in pyproject.toml
- E722 # Bare Exception | Temporary
+ E402 # Import Not at Top of File
]
exclude = _all_models.py
diff --git a/.gitignore b/.gitignore
index e356f2f9db67..0f4444b6ed6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,13 +3,11 @@
*__pycache__/
*.py[cod]
*$py.class
+
# frontend/.env.development
docs/site/
-mealie/temp/*
-mealie/temp/api.html
-.temp/
+*temp*
.secret
-!*/components/Recipe/Parts
dev/data/backups/*
dev/data/debug/*
@@ -17,14 +15,6 @@ dev/data/img/*
dev/data/migration/*
dev/data/users/*
-#Exception to keep folders
-!mealie/dist/.gitkeep
-!dev/data/backups/.gitkeep
-!dev/data/backups/dev_sample_data*
-!dev/data/debug/.gitkeep
-!dev/data/migration/.gitkeep
-!dev/data/img/.gitkeep
-
.DS_Store
node_modules
@@ -148,16 +138,11 @@ ENV/
# mypy
.mypy_cache/
-# IDE settings
-# .vscode/
-
# Node Modules
node_modules/
-mealie/data/debug/last_recipe.json
+*.db
*.sqlite
-dev/data/db/test.db
scratch.py
dev/data/backups/dev_sample_data*.zip
-dev/data/backups/dev_sample_data*.zip
!dev/data/backups/test*.zip
-dev/data/recipes/*
+dev/data/recipes/*
\ No newline at end of file
diff --git a/frontend/src/components/Recipe/Parts/Helpers/SettingsMenu.vue b/frontend/src/components/Recipe/Parts/Helpers/SettingsMenu.vue
new file mode 100644
index 000000000000..75445f160a90
--- /dev/null
+++ b/frontend/src/components/Recipe/Parts/Helpers/SettingsMenu.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+ mdi-cog
+
+ {{ $t("general.settings") }}
+
+
+
+
+
+ Recipe Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/Recipe/RecipeEditor/index.vue b/frontend/src/components/Recipe/RecipeEditor/index.vue
index cd675c5db65d..16225a952111 100644
--- a/frontend/src/components/Recipe/RecipeEditor/index.vue
+++ b/frontend/src/components/Recipe/RecipeEditor/index.vue
@@ -8,6 +8,11 @@
:slug="value.slug"
@refresh="$emit('upload')"
/>
+
@@ -122,6 +127,7 @@ import Instructions from "@/components/Recipe/Parts/Instructions";
import Ingredients from "@/components/Recipe/Parts/Ingredients";
import Assets from "@/components/Recipe/Parts/Assets.vue";
import Notes from "@/components/Recipe/Parts/Notes.vue";
+import SettingsMenu from "@/components/Recipe/Parts/Helpers/SettingsMenu.vue";
export default {
components: {
BulkAdd,
@@ -133,6 +139,7 @@ export default {
Ingredients,
Assets,
Notes,
+ SettingsMenu,
},
props: {
value: Object,
diff --git a/mealie/app.py b/mealie/app.py
index 75b2bb7a6d78..403998cd010c 100644
--- a/mealie/app.py
+++ b/mealie/app.py
@@ -3,13 +3,10 @@ from fastapi import FastAPI
from mealie.core import root_logger
from mealie.core.config import APP_VERSION, settings
-from mealie.routes import (backup_routes, debug_routes, migration_routes,
- theme_routes, utility_routes)
+from mealie.routes import backup_routes, debug_routes, migration_routes, theme_routes, utility_routes
from mealie.routes.groups import groups
from mealie.routes.mealplans import mealplans
-from mealie.routes.recipe import (all_recipe_routes, category_routes,
- recipe_assets, recipe_crud_routes,
- tag_routes)
+from mealie.routes.recipe import router as recipe_router
from mealie.routes.site_settings import all_settings
from mealie.routes.users import users
@@ -30,15 +27,10 @@ def start_scheduler():
def api_routers():
# Authentication
- app.include_router(utility_routes.router)
app.include_router(users.router)
app.include_router(groups.router)
# Recipes
- app.include_router(all_recipe_routes.router)
- app.include_router(category_routes.router)
- app.include_router(tag_routes.router)
- app.include_router(recipe_crud_routes.router)
- app.include_router(recipe_assets.router)
+ app.include_router(recipe_router)
# Meal Routes
app.include_router(mealplans.router)
# Settings Routes
@@ -49,6 +41,7 @@ def api_routers():
# Migration Routes
app.include_router(migration_routes.router)
app.include_router(debug_routes.router)
+ app.include_router(utility_routes.router)
api_routers()
diff --git a/mealie/core/config.py b/mealie/core/config.py
index be080dfb64a5..bdae8d3924d2 100644
--- a/mealie/core/config.py
+++ b/mealie/core/config.py
@@ -120,7 +120,7 @@ class AppSettings(BaseSettings):
DEFAULT_EMAIL: str = "changeme@email.com"
DEFAULT_PASSWORD: str = "MyPassword"
- TOKEN_TIME: int = 2 # Time in Hours
+ TOKEN_TIME: int = 2 # Time in Hours
# Not Used!
SFTP_USERNAME: Optional[str]
diff --git a/mealie/core/security.py b/mealie/core/security.py
index 4f9848cab17d..12cbe2257b6a 100644
--- a/mealie/core/security.py
+++ b/mealie/core/security.py
@@ -14,7 +14,7 @@ ALGORITHM = "HS256"
def create_access_token(data: dict(), expires_delta: timedelta = None) -> str:
to_encode = data.copy()
expires_delta = expires_delta or timedelta(hours=settings.TOKEN_TIME)
-
+
expire = datetime.utcnow() + expires_delta
to_encode.update({"exp": expire})
diff --git a/mealie/db/db_base.py b/mealie/db/db_base.py
index ede800379122..3b0c571681cd 100644
--- a/mealie/db/db_base.py
+++ b/mealie/db/db_base.py
@@ -137,4 +137,3 @@ class BaseDocument:
session.delete(result)
session.commit()
-
diff --git a/mealie/routes/backup_routes.py b/mealie/routes/backup_routes.py
index bfb304441da6..864a1380ac6f 100644
--- a/mealie/routes/backup_routes.py
+++ b/mealie/routes/backup_routes.py
@@ -1,17 +1,15 @@
import operator
import shutil
-from typing import Optional
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from mealie.core.config import app_dirs
from mealie.core.security import create_file_token
from mealie.db.db_setup import generate_session
-from mealie.routes.deps import get_current_user, validate_file_token
+from mealie.routes.deps import get_current_user
from mealie.schema.backup import BackupJob, ImportJob, Imports, LocalBackup
from mealie.services.backups import imports
from mealie.services.backups.exports import backup_all
from sqlalchemy.orm.session import Session
-from starlette.responses import FileResponse
router = APIRouter(prefix="/api/backups", tags=["Backups"], dependencies=[Depends(get_current_user)])
@@ -46,8 +44,8 @@ def export_database(data: BackupJob, session: Session = Depends(generate_session
export_groups=data.options.groups,
)
return {"export_path": export_path}
- except:
- raise HTTPException( status.HTTP_500_INTERNAL_SERVER_ERROR )
+ except Exception:
+ raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
@router.post("/upload", status_code=status.HTTP_200_OK)
@@ -59,8 +57,7 @@ def upload_backup_file(archive: UploadFile = File(...)):
shutil.copyfileobj(archive.file, buffer)
if not dest.is_file:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
-
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.get("/{file_name}/download")
@@ -95,8 +92,8 @@ def delete_backup(file_name: str):
file_path = app_dirs.BACKUP_DIR.joinpath(file_name)
if not file_path.is_file():
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
try:
file_path.unlink()
- except:
- raise HTTPException( status.HTTP_500_INTERNAL_SERVER_ERROR )
+ except Exception:
+ raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
diff --git a/mealie/routes/debug_routes.py b/mealie/routes/debug_routes.py
index 8dc919683809..500ee742e8f2 100644
--- a/mealie/routes/debug_routes.py
+++ b/mealie/routes/debug_routes.py
@@ -1,5 +1,3 @@
-import json
-
from fastapi import APIRouter, Depends
from mealie.core.config import APP_VERSION, app_dirs, settings
from mealie.core.root_logger import LOGGER_FILE
diff --git a/mealie/routes/groups/crud.py b/mealie/routes/groups/crud.py
index 933076b43785..81262697da6f 100644
--- a/mealie/routes/groups/crud.py
+++ b/mealie/routes/groups/crud.py
@@ -39,8 +39,8 @@ async def create_group(
try:
db.groups.create(session, group_data.dict())
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.put("/{id}")
@@ -61,23 +61,14 @@ async def delete_user_group(
""" Removes a user group from the database """
if id == 1:
- raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST,
- detail='DEFAULT_GROUP'
- )
+ raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="DEFAULT_GROUP")
group: GroupInDB = db.groups.get(session, id)
if not group:
- raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST,
- detail='GROUP_NOT_FOUND'
- )
+ raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="GROUP_NOT_FOUND")
if not group.users == []:
- raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST,
- detail='GROUP_WITH_USERS'
- )
+ raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="GROUP_WITH_USERS")
db.groups.delete(session, id)
diff --git a/mealie/routes/mealplans/crud.py b/mealie/routes/mealplans/crud.py
index 54d8bf116ae3..7b58853d7533 100644
--- a/mealie/routes/mealplans/crud.py
+++ b/mealie/routes/mealplans/crud.py
@@ -43,8 +43,8 @@ def update_meal_plan(
processed_plan = MealPlanInDB(uid=plan_id, **processed_plan.dict())
try:
db.meals.update(session, plan_id, processed_plan.dict())
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.delete("/{plan_id}")
@@ -53,8 +53,8 @@ def delete_meal_plan(plan_id, session: Session = Depends(generate_session), curr
try:
db.meals.delete(session, plan_id)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.get("/this-week", response_model=MealPlanInDB)
@@ -90,8 +90,8 @@ def get_todays_image(session: Session = Depends(generate_session), group_name: s
if recipe:
recipe_image = image.read_image(recipe.slug, image_type=image.IMG_OPTIONS.ORIGINAL_IMAGE)
else:
- raise HTTPException( status.HTTP_404_NOT_FOUND )
+ raise HTTPException(status.HTTP_404_NOT_FOUND)
if recipe_image:
return FileResponse(recipe_image)
else:
- raise HTTPException( status.HTTP_404_NOT_FOUND )
+ raise HTTPException(status.HTTP_404_NOT_FOUND)
diff --git a/mealie/routes/migration_routes.py b/mealie/routes/migration_routes.py
index fc870b32e7e2..8fcfd78000cd 100644
--- a/mealie/routes/migration_routes.py
+++ b/mealie/routes/migration_routes.py
@@ -9,6 +9,7 @@ from mealie.routes.deps import get_current_user
from mealie.schema.migration import MigrationFile, Migrations
from mealie.services.migrations import migration
from sqlalchemy.orm.session import Session
+from fastapi import HTTPException
router = APIRouter(prefix="/api/migrations", tags=["Migration"], dependencies=[Depends(get_current_user)])
@@ -52,8 +53,7 @@ def delete_migration_data(import_type: migration.Migration, file_name: str):
elif remove_path.is_dir():
shutil.rmtree(remove_path)
else:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
-
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.post("/{import_type}/upload", status_code=status.HTTP_200_OK)
@@ -67,4 +67,4 @@ def upload_nextcloud_zipfile(import_type: migration.Migration, archive: UploadFi
shutil.copyfileobj(archive.file, buffer)
if not dest.is_file:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
\ No newline at end of file
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/mealie/routes/recipe/__init__.py b/mealie/routes/recipe/__init__.py
index e69de29bb2d1..8af92586aae6 100644
--- a/mealie/routes/recipe/__init__.py
+++ b/mealie/routes/recipe/__init__.py
@@ -0,0 +1,10 @@
+from fastapi import APIRouter
+from mealie.routes.recipe import all_recipe_routes, category_routes, recipe_assets, recipe_crud_routes, tag_routes
+
+router = APIRouter()
+
+router.include_router(all_recipe_routes.router)
+router.include_router(recipe_crud_routes.router)
+router.include_router(recipe_assets.router)
+router.include_router(category_routes.router)
+router.include_router(tag_routes.router)
diff --git a/mealie/routes/recipe/all_recipe_routes.py b/mealie/routes/recipe/all_recipe_routes.py
index 0a8556afc263..014815774ada 100644
--- a/mealie/routes/recipe/all_recipe_routes.py
+++ b/mealie/routes/recipe/all_recipe_routes.py
@@ -1,9 +1,7 @@
-from typing import List, Optional
-
-from fastapi import APIRouter, Depends, Query
+from fastapi import APIRouter, Depends
from mealie.db.database import db
from mealie.db.db_setup import generate_session
-from mealie.schema.recipe import AllRecipeRequest, RecipeSummary
+from mealie.schema.recipe import RecipeSummary
from slugify import slugify
from sqlalchemy.orm.session import Session
@@ -31,66 +29,6 @@ async def get_recipe_summary(
return db.recipes.get_all(session, limit=limit, start=start, override_schema=RecipeSummary)
-@router.get("/api/recipes", deprecated=True)
-def get_all_recipes(
- keys: Optional[List[str]] = Query(...),
- num: Optional[int] = 100,
- session: Session = Depends(generate_session),
-):
- """
- Returns key data for all recipes based off the query paramters provided.
- For example, if slug, image, and name are provided you will recieve a list of
- recipes containing the slug, image, and name property. By default, responses
- are limited to 100.
-
- At this time you can only query top level values:
-
- - slug
- - name
- - description
- - image
- - recipeYield
- - total_time
- - prep_time
- - perform_time
- - rating
- - org_url
-
- **Note:** You may experience problems with with query parameters. As an alternative
- you may also use the post method and provide a body.
- See the *Post* method for more details.
- """
-
- return db.recipes.get_all_limit_columns(session, keys, limit=num)
-
-
-@router.post("/api/recipes", deprecated=True)
-def get_all_recipes_post(body: AllRecipeRequest, session: Session = Depends(generate_session)):
- """
- Returns key data for all recipes based off the body data provided.
- For example, if slug, image, and name are provided you will recieve a list of
- recipes containing the slug, image, and name property.
-
- At this time you can only query top level values:
-
- - slug
- - name
- - description
- - image
- - recipeYield
- - total_time
- - prep_time
- - perform_time
- - rating
- - org_url
-
- Refer to the body example for data formats.
-
- """
-
- return db.recipes.get_all_limit_columns(session, body.properties, body.limit)
-
-
@router.post("/api/recipes/category")
def filter_by_category(categories: list, session: Session = Depends(generate_session)):
""" pass a list of categories and get a list of recipes associated with those categories """
diff --git a/mealie/routes/recipe/category_routes.py b/mealie/routes/recipe/category_routes.py
index 2722bc8dd042..c358a69afb2d 100644
--- a/mealie/routes/recipe/category_routes.py
+++ b/mealie/routes/recipe/category_routes.py
@@ -37,8 +37,8 @@ async def create_recipe_category(
try:
return db.categories.create(session, category.dict())
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.put("/{category}", response_model=RecipeCategoryResponse)
@@ -52,8 +52,8 @@ async def update_recipe_category(
try:
return db.categories.update(session, category, new_category.dict())
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.delete("/{category}")
@@ -66,5 +66,5 @@ async def delete_recipe_category(
try:
db.categories.delete(session, category)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/mealie/routes/recipe/recipe_assets.py b/mealie/routes/recipe/recipe_assets.py
index 95d4e07b027a..ebab8d246c27 100644
--- a/mealie/routes/recipe/recipe_assets.py
+++ b/mealie/routes/recipe/recipe_assets.py
@@ -1,6 +1,7 @@
import shutil
+from enum import Enum
-from fastapi import APIRouter, Depends, File, Form, status, HTTPException
+from fastapi import APIRouter, Depends, File, Form, HTTPException, status
from fastapi.datastructures import UploadFile
from mealie.core.config import app_dirs
from mealie.db.database import db
@@ -11,7 +12,24 @@ from slugify import slugify
from sqlalchemy.orm.session import Session
from starlette.responses import FileResponse
-router = APIRouter(prefix="/api/recipes", tags=["Recipe Assets"])
+router = APIRouter(prefix="/api/recipes", tags=["Recipe Media"])
+
+
+class ImageType(str, Enum):
+ original = "original.webp"
+ small = "min-original.webp"
+ tiny = "tiny-original.webp"
+
+
+@router.get("/image/{recipe_slug}/{file_name}")
+async def get_recipe_img(recipe_slug: str, file_name: ImageType = ImageType.original):
+ """Takes in a recipe slug, returns the static image. This route is proxied in the docker image
+ and should not hit the API in production"""
+ recipe_image = app_dirs.IMG_DIR.joinpath(recipe_slug, file_name.value)
+ if recipe_image:
+ return FileResponse(recipe_image)
+ else:
+ raise HTTPException(status.HTTP_404_NOT_FOUND)
@router.get("/{recipe_slug}/asset")
@@ -41,9 +59,9 @@ def upload_recipe_asset(
shutil.copyfileobj(file.file, buffer)
if not dest.is_file():
- raise HTTPException( status.HTTP_500_INTERNAL_SERVER_ERROR )
+ raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
recipe: Recipe = db.recipes.get(session, recipe_slug)
recipe.assets.append(asset_in)
db.recipes.update(session, recipe_slug, recipe.dict())
- return asset_in
\ No newline at end of file
+ return asset_in
diff --git a/mealie/routes/recipe/recipe_crud_routes.py b/mealie/routes/recipe/recipe_crud_routes.py
index cdeaf3f71c9f..2794370e8cf6 100644
--- a/mealie/routes/recipe/recipe_crud_routes.py
+++ b/mealie/routes/recipe/recipe_crud_routes.py
@@ -1,14 +1,10 @@
-from enum import Enum
-
from fastapi import APIRouter, Depends, File, Form, HTTPException, status
-from fastapi.responses import FileResponse
-from mealie.core.config import app_dirs
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.deps import get_current_user
from mealie.schema.recipe import Recipe, RecipeURLIn
-from mealie.services.image.image import IMG_OPTIONS, delete_image, read_image, rename_image, scrape_image, write_image
+from mealie.services.image.image import delete_image, rename_image, scrape_image, write_image
from mealie.services.scraper.scraper import create_from_url
from sqlalchemy.orm.session import Session
@@ -101,25 +97,8 @@ def delete_recipe(
try:
db.recipes.delete(session, recipe_slug)
delete_image(recipe_slug)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
-
-
-
-class ImageType(str, Enum):
- original = "original.webp"
- small = "min-original.webp"
- tiny = "tiny-original.webp"
-
-
-@router.get("/image/{recipe_slug}/{file_name}")
-async def get_recipe_img(recipe_slug: str, file_name: ImageType = ImageType.original):
- """ Takes in a recipe slug, returns the static image """
- recipe_image = app_dirs.IMG_DIR.joinpath(recipe_slug, file_name.value)
- if recipe_image:
- return FileResponse(recipe_image)
- else:
- raise HTTPException( status.HTTP_404_NOT_FOUND )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
@router.put("/{recipe_slug}/image")
diff --git a/mealie/routes/recipe/tag_routes.py b/mealie/routes/recipe/tag_routes.py
index 5d62715bbed7..57f6ba4b7efe 100644
--- a/mealie/routes/recipe/tag_routes.py
+++ b/mealie/routes/recipe/tag_routes.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, 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
@@ -7,10 +7,7 @@ from sqlalchemy.orm.session import Session
router = APIRouter(tags=["Recipes"])
-router = APIRouter(
- prefix="/api/tags",
- tags=["Recipe Tags"],
-)
+router = APIRouter(prefix="/api/tags", tags=["Recipe Tags"])
@router.get("")
@@ -59,5 +56,5 @@ async def delete_recipe_tag(
try:
db.tags.delete(session, tag)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/mealie/routes/theme_routes.py b/mealie/routes/theme_routes.py
index f1f3dbd43566..9f25c8eaecff 100644
--- a/mealie/routes/theme_routes.py
+++ b/mealie/routes/theme_routes.py
@@ -21,7 +21,6 @@ def create_theme(data: SiteTheme, session: Session = Depends(generate_session),
db.themes.create(session, data.dict())
-
@router.get("/themes/{theme_name}")
def get_single_theme(theme_name: str, session: Session = Depends(generate_session)):
""" Returns a named theme """
@@ -44,5 +43,5 @@ def delete_theme(theme_name: str, session: Session = Depends(generate_session),
""" Deletes theme from the database """
try:
db.themes.delete(session, theme_name)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/mealie/routes/users/auth.py b/mealie/routes/users/auth.py
index 48a0679ec1c5..555abf3bea91 100644
--- a/mealie/routes/users/auth.py
+++ b/mealie/routes/users/auth.py
@@ -1,5 +1,3 @@
-from datetime import timedelta
-
from fastapi import APIRouter, Depends, status
from fastapi.exceptions import HTTPException
from fastapi.security import OAuth2PasswordRequestForm
diff --git a/mealie/routes/users/crud.py b/mealie/routes/users/crud.py
index d11d6a852188..bd8101de59e7 100644
--- a/mealie/routes/users/crud.py
+++ b/mealie/routes/users/crud.py
@@ -1,5 +1,4 @@
import shutil
-from datetime import timedelta
from fastapi import APIRouter, Depends, File, UploadFile, status, HTTPException
from fastapi.responses import FileResponse
@@ -34,8 +33,8 @@ async def get_all_users(
):
if not current_user.admin:
- raise HTTPException( status.HTTP_403_FORBIDDEN )
-
+ raise HTTPException(status.HTTP_403_FORBIDDEN)
+
return db.users.get_all(session)
@@ -67,7 +66,6 @@ async def reset_user_password(
db.users.update_password(session, id, new_password)
-
@router.put("/{id}")
async def update_user(
id: int,
@@ -109,7 +107,7 @@ async def update_user_image(
try:
[x.unlink() for x in app_dirs.USER_DIR.join(id).glob("profile_image.*")]
- except:
+ except Exception:
pass
dest = app_dirs.USER_DIR.joinpath(id, f"profile_image.{extension}")
@@ -118,7 +116,7 @@ async def update_user_image(
shutil.copyfileobj(profile_image.file, buffer)
if not dest.is_file:
- raise HTTPException( status.HTTP_500_INTERNAL_SERVER_ERROR )
+ raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
@router.put("/{id}/password")
@@ -133,12 +131,11 @@ async def update_password(
match_passwords = verify_password(password_change.current_password, current_user.password)
match_id = current_user.id == id
- if not ( match_passwords and match_id ):
- raise HTTPException( status.HTTP_401_UNAUTHORIZED )
+ if not (match_passwords and match_id):
+ raise HTTPException(status.HTTP_401_UNAUTHORIZED)
new_password = get_password_hash(password_change.new_password)
db.users.update_password(session, id, new_password)
-
@router.delete("/{id}")
@@ -150,13 +147,10 @@ async def delete_user(
""" Removes a user from the database. Must be the current user or a super user"""
if id == 1:
- raise HTTPException(
- status_code=status.HTTP_403_FORBIDDEN,
- detail='SUPER_USER'
- )
+ raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER")
if current_user.id == id or current_user.admin:
try:
db.users.delete(session, id)
- except:
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
\ No newline at end of file
+ except Exception:
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/mealie/routes/users/sign_up.py b/mealie/routes/users/sign_up.py
index cd0bf8982c1e..c62d4f20414e 100644
--- a/mealie/routes/users/sign_up.py
+++ b/mealie/routes/users/sign_up.py
@@ -8,6 +8,7 @@ from mealie.routes.deps import get_current_user
from mealie.schema.sign_up import SignUpIn, SignUpOut, SignUpToken
from mealie.schema.user import UserIn, UserInDB
from sqlalchemy.orm.session import Session
+from fastapi import HTTPException, status
router = APIRouter(prefix="/api/users/sign-ups", tags=["User Signup"])
@@ -33,7 +34,7 @@ async def create_user_sign_up_key(
""" Generates a Random Token that a new user can sign up with """
if not current_user.admin:
- raise HTTPException( status.HTTP_403_FORBIDDEN )
+ raise HTTPException(status.HTTP_403_FORBIDDEN)
sign_up = {
"token": str(uuid.uuid1().hex),
@@ -43,7 +44,6 @@ async def create_user_sign_up_key(
return db.sign_ups.create(session, sign_up)
-
@router.post("/{token}")
async def create_user_with_token(
token: str,
@@ -55,12 +55,12 @@ async def create_user_with_token(
# Validate Token
db_entry: SignUpOut = db.sign_ups.get(session, token, limit=1)
if not db_entry:
- raise HTTPException( status.HTTP_401_UNAUTHORIZED )
+ raise HTTPException(status.HTTP_401_UNAUTHORIZED)
# Create User
new_user.admin = db_entry.admin
new_user.password = get_password_hash(new_user.password)
- data = db.users.create(session, new_user.dict())
+ db.users.create(session, new_user.dict())
# DeleteToken
db.sign_ups.delete(session, token)
@@ -74,6 +74,6 @@ async def delete_token(
):
""" Removed a token from the database """
if not current_user.admin:
- raise HTTPException( status.HTTP_403_FORBIDDEN )
-
+ raise HTTPException(status.HTTP_403_FORBIDDEN)
+
db.sign_ups.delete(session, token)
diff --git a/mealie/routes/utility_routes.py b/mealie/routes/utility_routes.py
index e52f4bdd8057..6f30128ab75e 100644
--- a/mealie/routes/utility_routes.py
+++ b/mealie/routes/utility_routes.py
@@ -4,16 +4,17 @@ from typing import Optional
from fastapi import APIRouter, Depends
from mealie.routes.deps import validate_file_token
from starlette.responses import FileResponse
+from fastapi import HTTPException, status
router = APIRouter(prefix="/api/utils", tags=["Utils"], include_in_schema=True)
@router.get("/download")
async def download_file(file_path: Optional[Path] = Depends(validate_file_token)):
- """ Uses a file token obtained by an active user to retrieve a file from the operating
- system. """
+ """Uses a file token obtained by an active user to retrieve a file from the operating
+ system."""
print("File Name:", file_path)
if not file_path.is_file():
- raise HTTPException( status.HTTP_400_BAD_REQUEST )
+ raise HTTPException(status.HTTP_400_BAD_REQUEST)
return FileResponse(file_path, media_type="application/octet-stream", filename=file_path.name)
diff --git a/mealie/services/backups/exports.py b/mealie/services/backups/exports.py
index cbbc0a853797..afd9a735eb84 100644
--- a/mealie/services/backups/exports.py
+++ b/mealie/services/backups/exports.py
@@ -37,7 +37,7 @@ class ExportDatabase:
try:
self.templates = [app_dirs.TEMPLATE_DIR.joinpath(x) for x in templates]
- except:
+ except Exception:
self.templates = False
logger.info("No Jinja2 Templates Registered for Export")
diff --git a/mealie/services/backups/imports.py b/mealie/services/backups/imports.py
index 3d35a843a11d..b561752bd6d8 100644
--- a/mealie/services/backups/imports.py
+++ b/mealie/services/backups/imports.py
@@ -84,20 +84,20 @@ class ImportDatabase:
try:
del recipe_dict["_id"]
del recipe_dict["date_added"]
- except:
+ except Exception:
pass
# Migration from list to Object Type Data
try:
if "" in recipe_dict["tags"]:
recipe_dict["tags"] = [tag for tag in recipe_dict["tags"] if tag != ""]
- except:
+ except Exception:
pass
try:
if "" in recipe_dict["categories"]:
recipe_dict["categories"] = [cat for cat in recipe_dict["categories"] if cat != ""]
- except:
+ except Exception:
pass
if type(recipe_dict["extras"]) == list:
diff --git a/mealie/services/image/image.py b/mealie/services/image/image.py
index 1353ac8a7686..ed5f90ab0cb0 100644
--- a/mealie/services/image/image.py
+++ b/mealie/services/image/image.py
@@ -54,7 +54,7 @@ def rename_image(original_slug, new_slug) -> Path:
def write_image(recipe_slug: str, file_data: bytes, extension: str) -> Path:
try:
delete_image(recipe_slug)
- except:
+ except Exception:
pass
image_dir = Path(app_dirs.IMG_DIR.joinpath(f"{recipe_slug}"))
@@ -100,7 +100,7 @@ def scrape_image(image_url: str, slug: str) -> Path:
try:
r = requests.get(image_url, stream=True)
- except:
+ except Exception:
logger.exception("Fatal Image Request Exception")
return None
diff --git a/mealie/services/image/minify.py b/mealie/services/image/minify.py
index 52344628427c..e33bbb38e106 100644
--- a/mealie/services/image/minify.py
+++ b/mealie/services/image/minify.py
@@ -35,14 +35,15 @@ def minify_image(image_file: Path) -> ImageSizes:
min_dest (Path): FULL Destination File Path
tiny_dest (Path): FULL Destination File Path
"""
+
def cleanup(dir: Path) -> None:
for file in dir.glob("*.*"):
if file.suffix != ".webp":
file.unlink()
- org_dest = image_file.parent.joinpath(f"original.webp")
- min_dest = image_file.parent.joinpath(f"min-original.webp")
- tiny_dest = image_file.parent.joinpath(f"tiny-original.webp")
+ org_dest = image_file.parent.joinpath("original.webp")
+ min_dest = image_file.parent.joinpath("min-original.webp")
+ tiny_dest = image_file.parent.joinpath("tiny-original.webp")
if min_dest.exists() and tiny_dest.exists() and org_dest.exists():
return
diff --git a/mealie/services/meal_services.py b/mealie/services/meal_services.py
index 7f5aaefa5c2c..9d657760810d 100644
--- a/mealie/services/meal_services.py
+++ b/mealie/services/meal_services.py
@@ -24,7 +24,7 @@ def process_meals(session: Session, meal_plan_base: MealPlanIn) -> MealPlanProce
description=recipe.description,
)
- except:
+ except Exception:
meal_data = MealOut(
date=meal_plan_base.startDate + timedelta(days=x),
diff --git a/mealie/services/migrations/_migration_base.py b/mealie/services/migrations/_migration_base.py
index 15434d5b22f5..6eb35895f7ef 100644
--- a/mealie/services/migrations/_migration_base.py
+++ b/mealie/services/migrations/_migration_base.py
@@ -8,7 +8,7 @@ from mealie.core import root_logger
from mealie.db.database import db
from mealie.schema.migration import MigrationImport
from mealie.schema.recipe import Recipe
-from mealie.services.image import image, minify
+from mealie.services.image import image
from mealie.services.scraper.cleaner import Cleaner
from mealie.utils.unzip import unpack_zip
from pydantic import BaseModel
diff --git a/mealie/services/scraper/cleaner.py b/mealie/services/scraper/cleaner.py
index 0129f68f8bd5..a24586bf4d74 100644
--- a/mealie/services/scraper/cleaner.py
+++ b/mealie/services/scraper/cleaner.py
@@ -115,7 +115,7 @@ class Cleaner:
for step in instructions
if step["type"].find("HowToStep") > -1
]
- except:
+ except Exception:
pass
else:
diff --git a/mealie/services/scraper/open_graph.py b/mealie/services/scraper/open_graph.py
index 7cd22e6c4852..ed41f7598c05 100644
--- a/mealie/services/scraper/open_graph.py
+++ b/mealie/services/scraper/open_graph.py
@@ -21,7 +21,7 @@ def basic_recipe_from_opengraph(html: str, url: str) -> dict:
data = extruct.extract(html, base_url=base_url)
try:
properties = data["opengraph"][0]["properties"]
- except:
+ except Exception:
return
return {
diff --git a/mealie/services/scraper/scraper.py b/mealie/services/scraper/scraper.py
index 6dfb39653f61..bee5cc178d3a 100644
--- a/mealie/services/scraper/scraper.py
+++ b/mealie/services/scraper/scraper.py
@@ -67,7 +67,7 @@ def download_image_for_recipe(recipe: dict) -> dict:
try:
img_path = scrape_image(recipe.get("image"), recipe.get("slug"))
recipe["image"] = img_path.name
- except:
+ except Exception:
recipe["image"] = "no image"
return recipe
diff --git a/tests/conftest.py b/tests/conftest.py
index 74b34c497f4b..f12b327f674f 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,6 +1,6 @@
from mealie.core.config import app_dirs, settings
-#! I don't like it either!
+# ! I don't like it either!
SQLITE_FILE = app_dirs.SQLITE_DIR.joinpath("test.db")
SQLITE_FILE.unlink(missing_ok=True)
diff --git a/tests/data/migrations/chowdown/chowdown-gh-pages.zip b/tests/data/migrations/chowdown/chowdown-gh-pages.zip
new file mode 100644
index 000000000000..bd90e08d4e8d
Binary files /dev/null and b/tests/data/migrations/chowdown/chowdown-gh-pages.zip differ
diff --git a/tests/data/migrations/nextcloud/new_nextcloud.zip b/tests/data/migrations/nextcloud/new_nextcloud.zip
new file mode 100644
index 000000000000..a420370fffa2
Binary files /dev/null and b/tests/data/migrations/nextcloud/new_nextcloud.zip differ
diff --git a/tests/integration_tests/test_group_routes.py b/tests/integration_tests/test_group_routes.py
index d06f200270a9..d13fed128b00 100644
--- a/tests/integration_tests/test_group_routes.py
+++ b/tests/integration_tests/test_group_routes.py
@@ -37,7 +37,7 @@ def test_update_group(api_client: TestClient, api_routes: AppRoutes, token):
# Test Update
response = api_client.put(api_routes.groups_id(2), json=new_data, headers=token)
assert response.status_code == 200
-
+
# Validate Changes
response = api_client.get(api_routes.groups, headers=token)
all_groups = json.loads(response.text)
diff --git a/tests/integration_tests/test_recipe_routes.py b/tests/integration_tests/test_recipe_routes.py
index b94d6d5f3e57..02803c05fd9c 100644
--- a/tests/integration_tests/test_recipe_routes.py
+++ b/tests/integration_tests/test_recipe_routes.py
@@ -34,11 +34,6 @@ def test_create_no_image(api_client: TestClient, api_routes: AppRoutes, token, r
assert json.loads(response.text) == "banana-bread-no-image"
-def test_read_all_post(api_client: TestClient, api_routes: AppRoutes):
- response = api_client.post(api_routes.recipes, json={"properties": ["slug", "description", "rating"]})
- assert response.status_code == 200
-
-
@pytest.mark.parametrize("recipe_data", recipe_test_data)
def test_read_update(api_client: TestClient, api_routes: AppRoutes, recipe_data, token):
recipe_url = api_routes.recipes_recipe_slug(recipe_data.expected_slug)