diff --git a/docs/docs/changelog/v0.4.1.md b/docs/docs/changelog/v0.4.1.md
index 2b2a6d7bc..5450bc4b8 100644
--- a/docs/docs/changelog/v0.4.1.md
+++ b/docs/docs/changelog/v0.4.1.md
@@ -13,4 +13,10 @@
- Random meal-planner will no longer duplicate recipes unless no other options
- New Quick Week button to generate next 5 day week of recipe slots.
- Minor UI tweaks
+- Recipe Cards now display 2 recipe tags
+- Recipe images are now minified. This comes with a serious performance improvement. On initial startup you may experience some delays. Images are migrated to the new structure on startup, depending on the size of your database this can take some time.
+ - Note that original images are still kept for large displays like on the individual recipe pages.
+ - A smaller image is used for recipe cards
+ - A 'tiny' image is used for search images.
+
diff --git a/docs/docs/overrides/api.html b/docs/docs/overrides/api.html
index 2219e40ad..7e2e2ebc5 100644
--- a/docs/docs/overrides/api.html
+++ b/docs/docs/overrides/api.html
@@ -14,7 +14,7 @@
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 080c3ca3d..7d675172a 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -74,6 +74,7 @@ nav:
- Guidelines: "contributors/developers-guide/general-guidelines.md"
- Development Road Map: "roadmap.md"
- Change Log:
+ - v0.4.1 Frontend/UI: "changelog/v0.4.1.md"
- v0.4.0 Authentication: "changelog/v0.4.0.md"
- v0.3.0 Improvements: "changelog/v0.3.0.md"
- v0.2.0 Now With Tests!: "changelog/v0.2.0.md"
diff --git a/frontend/src/api/meta.js b/frontend/src/api/meta.js
index e1aed1fe1..59183c0c5 100644
--- a/frontend/src/api/meta.js
+++ b/frontend/src/api/meta.js
@@ -5,6 +5,7 @@ const prefix = baseURL + "debug";
const debugURLs = {
version: `${prefix}/version`,
+ debug: `${prefix}`,
lastRecipe: `${prefix}/last-recipe-json`,
demo: `${prefix}/is-demo`,
};
@@ -14,6 +15,12 @@ export const metaAPI = {
let response = await apiReq.get(debugURLs.version);
return response.data;
},
+
+ async getDebugInfo() {
+ const response = await apiReq.get(debugURLs.debug);
+ return response.data;
+ },
+
async getLastJson() {
let response = await apiReq.get(debugURLs.lastRecipe);
return response.data;
diff --git a/frontend/src/api/recipe.js b/frontend/src/api/recipe.js
index 5eef791ac..50e45e593 100644
--- a/frontend/src/api/recipe.js
+++ b/frontend/src/api/recipe.js
@@ -8,6 +8,7 @@ const prefix = baseURL + "recipes/";
const recipeURLs = {
allRecipes: baseURL + "recipes",
+ summary: baseURL + "recipes" + "/summary",
allRecipesByCategory: prefix + "category",
create: prefix + "create",
createByURL: prefix + "create-url",
@@ -86,6 +87,11 @@ export const recipeAPI = {
return response.data;
},
+ async allSummary() {
+ const response = await apiReq.get(recipeURLs.summary);
+ return response.data;
+ },
+
recipeImage(recipeSlug) {
return `/api/recipes/${recipeSlug}/image?image_type=original`;
},
diff --git a/frontend/src/components/Admin/AdminSidebar.vue b/frontend/src/components/Admin/AdminSidebar.vue
index 35876ef41..f09070492 100644
--- a/frontend/src/components/Admin/AdminSidebar.vue
+++ b/frontend/src/components/Admin/AdminSidebar.vue
@@ -74,7 +74,7 @@
-
+
mdi-information
@@ -87,6 +87,7 @@
@@ -25,9 +26,9 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/pages/Recipes/TagPage.vue b/frontend/src/pages/Recipes/TagPage.vue
index e49fdb332..a6a0a991b 100644
--- a/frontend/src/pages/Recipes/TagPage.vue
+++ b/frontend/src/pages/Recipes/TagPage.vue
@@ -33,7 +33,7 @@ export default {
},
},
watch: {
- async currentCategory() {
+ async currentTag() {
this.getRecipes();
},
},
diff --git a/frontend/src/routes/admin.js b/frontend/src/routes/admin.js
index e7637007b..e52927db2 100644
--- a/frontend/src/routes/admin.js
+++ b/frontend/src/routes/admin.js
@@ -6,6 +6,7 @@ import Migration from "@/pages/Admin/Migration";
import Profile from "@/pages/Admin/Profile";
import ManageUsers from "@/pages/Admin/ManageUsers";
import Settings from "@/pages/Admin/Settings";
+import About from "@/pages/Admin/About";
import { store } from "../store";
export default {
@@ -50,5 +51,9 @@ export default {
path: "settings",
component: Settings,
},
+ {
+ path: "about",
+ component: About,
+ },
],
};
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
index 8b0b4cc51..f8f17282e 100644
--- a/frontend/src/store/index.js
+++ b/frontend/src/store/index.js
@@ -54,15 +54,15 @@ const store = new Vuex.Store({
actions: {
async requestRecentRecipes() {
- const keys = [
- "name",
- "slug",
- "image",
- "description",
- "dateAdded",
- "rating",
- ];
- const payload = await api.recipes.allByKeys(keys);
+ // const keys = [
+ // "name",
+ // "slug",
+ // "image",
+ // "description",
+ // "dateAdded",
+ // "rating",
+ // ];
+ const payload = await api.recipes.allSummary();
this.commit("setRecentRecipes", payload);
},
diff --git a/mealie/core/config.py b/mealie/core/config.py
index 5bcfe1982..363b32983 100644
--- a/mealie/core/config.py
+++ b/mealie/core/config.py
@@ -5,7 +5,7 @@ from typing import Optional, Union
from pydantic import BaseSettings, Field, validator
-APP_VERSION = "v0.4.0"
+APP_VERSION = "v0.4.1"
DB_VERSION = "v0.4.0"
CWD = Path(__file__).parent
diff --git a/mealie/db/db_base.py b/mealie/db/db_base.py
index 6aef2b24d..f9e9a03a9 100644
--- a/mealie/db/db_base.py
+++ b/mealie/db/db_base.py
@@ -15,17 +15,10 @@ class BaseDocument:
self.schema: BaseModel
# TODO: Improve Get All Query Functionality
- def get_all(self, session: Session, limit: int = None, order_by: str = None) -> List[dict]:
+ def get_all(self, session: Session, limit: int = None, order_by: str = None, override_schema=None) -> List[dict]:
+ eff_schema = override_schema or self.schema
- if self.orm_mode:
- return [self.schema.from_orm(x) for x in session.query(self.sql_model).limit(limit).all()]
-
- # list = [x.dict() for x in session.query(self.sql_model).limit(limit).all()]
-
- # if limit == 1:
- # return list[0]
-
- # return list
+ return [eff_schema.from_orm(x) for x in session.query(self.sql_model).limit(limit).all()]
def get_all_limit_columns(self, session: Session, fields: List[str], limit: int = None) -> List[SqlAlchemyBase]:
"""Queries the database for the selected model. Restricts return responses to the
diff --git a/mealie/routes/debug_routes.py b/mealie/routes/debug_routes.py
index 5b0392ccd..933e781c8 100644
--- a/mealie/routes/debug_routes.py
+++ b/mealie/routes/debug_routes.py
@@ -3,15 +3,35 @@ import json
from fastapi import APIRouter, Depends
from mealie.core.config import APP_VERSION, LOGGER_FILE, app_dirs, settings
from mealie.routes.deps import get_current_user
-from mealie.schema.debug import AppInfo
+from mealie.schema.debug import AppInfo, DebugInfo
router = APIRouter(prefix="/api/debug", tags=["Debug"])
+@router.get("")
+async def get_debug_info(current_user=Depends(get_current_user)):
+ """ Returns general information about the application for debugging """
+
+ return DebugInfo(
+ production=settings.PRODUCTION,
+ version=APP_VERSION,
+ demo_status=settings.IS_DEMO,
+ api_port=settings.API_PORT,
+ api_docs=settings.API_DOCS,
+ db_type=settings.DATABASE_TYPE,
+ sqlite_file=settings.SQLITE_FILE,
+ default_group=settings.DEFAULT_GROUP,
+ )
+
+
@router.get("/version")
async def get_mealie_version():
""" Returns the current version of mealie"""
- return AppInfo(version=APP_VERSION, demo_status=settings.IS_DEMO)
+ return AppInfo(
+ version=APP_VERSION,
+ demo_status=settings.IS_DEMO,
+ production=settings.PRODUCTION,
+ )
@router.get("/last-recipe-json")
diff --git a/mealie/routes/mealplans/crud.py b/mealie/routes/mealplans/crud.py
index c0498e6a1..f1dcc02bb 100644
--- a/mealie/routes/mealplans/crud.py
+++ b/mealie/routes/mealplans/crud.py
@@ -1,12 +1,14 @@
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, Depends, HTTPException
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.meal import MealPlanIn, MealPlanInDB
from mealie.schema.snackbar import SnackResponse
from mealie.schema.user import GroupInDB, UserInDB
+from mealie.services.image import image
from mealie.services.meal_services import get_todays_meal, process_meals
from sqlalchemy.orm.session import Session
+from starlette.responses import FileResponse
router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
@@ -74,3 +76,22 @@ def get_today(session: Session = Depends(generate_session), current_user: UserIn
recipe = get_todays_meal(session, group_in_db)
return recipe.slug
+
+
+@router.get("/today/image", tags=["Meal Plan"])
+def get_today(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)
+
+ if recipe:
+ recipe_image = image.read_image(recipe.slug, image_type=image.IMG_OPTIONS.ORIGINAL_IMAGE)
+ else:
+ raise HTTPException(404, "no meal for today")
+ if recipe_image:
+ return FileResponse(recipe_image)
+ else:
+ raise HTTPException(404, "file not found")
diff --git a/mealie/routes/recipe/all_recipe_routes.py b/mealie/routes/recipe/all_recipe_routes.py
index 659905483..42dd6940b 100644
--- a/mealie/routes/recipe/all_recipe_routes.py
+++ b/mealie/routes/recipe/all_recipe_routes.py
@@ -3,13 +3,24 @@ from typing import List, Optional
from fastapi import APIRouter, Depends, Query
from mealie.db.database import db
from mealie.db.db_setup import generate_session
-from mealie.schema.recipe import AllRecipeRequest
+from mealie.schema.recipe import AllRecipeRequest, RecipeSummary
from slugify import slugify
from sqlalchemy.orm.session import Session
router = APIRouter(tags=["Query All Recipes"])
+@router.get("/api/recipes/summary")
+async def get_recipe_summary(
+ skip=0,
+ end=9999,
+ session: Session = Depends(generate_session),
+):
+ """ Returns the summary data for recipes in the database """
+
+ return db.recipes.get_all(session, limit=end, override_schema=RecipeSummary)
+
+
@router.get("/api/recipes")
def get_all_recipes(
keys: Optional[List[str]] = Query(...),
diff --git a/mealie/routes/recipe/recipe_crud_routes.py b/mealie/routes/recipe/recipe_crud_routes.py
index b044a80a9..e696f87d9 100644
--- a/mealie/routes/recipe/recipe_crud_routes.py
+++ b/mealie/routes/recipe/recipe_crud_routes.py
@@ -98,7 +98,6 @@ async def get_recipe_img(recipe_slug: str, image_type: ImageType = ImageType.ori
which_image = IMG_OPTIONS.TINY_IMAGE
recipe_image = read_image(recipe_slug, image_type=which_image)
- print(recipe_image)
if recipe_image:
return FileResponse(recipe_image)
else:
diff --git a/mealie/schema/debug.py b/mealie/schema/debug.py
index e0b8fccb3..4cb94396d 100644
--- a/mealie/schema/debug.py
+++ b/mealie/schema/debug.py
@@ -1,6 +1,15 @@
+from pathlib import Path
from fastapi_camelcase import CamelModel
class AppInfo(CamelModel):
+ production: bool
version: str
demo_status: bool
+
+class DebugInfo(AppInfo):
+ api_port: int
+ api_docs: bool
+ db_type: str
+ sqlite_file: Path
+ default_group: str
\ No newline at end of file
diff --git a/mealie/schema/recipe.py b/mealie/schema/recipe.py
index be1df086e..3ea0b9aee 100644
--- a/mealie/schema/recipe.py
+++ b/mealie/schema/recipe.py
@@ -34,12 +34,30 @@ class Nutrition(BaseModel):
orm_mode = True
-class Recipe(BaseModel):
+class RecipeSummary(BaseModel):
name: str
- description: Optional[str]
+ slug: Optional[str] = ""
image: Optional[Any]
- recipeYield: Optional[str]
+
+ description: Optional[str]
recipeCategory: Optional[List[str]] = []
+ tags: Optional[List[str]] = []
+ rating: Optional[int]
+
+ class Config:
+ orm_mode = True
+
+ @classmethod
+ def getter_dict(_cls, name_orm: RecipeModel):
+ return {
+ **GetterDict(name_orm),
+ "recipeCategory": [x.name for x in name_orm.recipeCategory],
+ "tags": [x.name for x in name_orm.tags],
+ }
+
+
+class Recipe(RecipeSummary):
+ recipeYield: Optional[str]
recipeIngredient: Optional[list[str]]
recipeInstructions: Optional[list[RecipeStep]]
nutrition: Optional[Nutrition]
@@ -50,11 +68,8 @@ class Recipe(BaseModel):
performTime: Optional[str] = None
# Mealie Specific
- slug: Optional[str] = ""
- tags: Optional[List[str]] = []
dateAdded: Optional[datetime.date]
notes: Optional[List[RecipeNote]] = []
- rating: Optional[int]
orgURL: Optional[str]
extras: Optional[dict] = {}
diff --git a/poetry.lock b/poetry.lock
index 6b7165056..20b2ae91c 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -50,7 +50,7 @@ zookeeper = ["kazoo"]
[[package]]
name = "astroid"
-version = "2.5.1"
+version = "2.5.2"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false
@@ -191,11 +191,11 @@ toml = ["toml"]
[[package]]
name = "decorator"
-version = "4.4.2"
+version = "5.0.4"
description = "Decorators for Humans"
category = "main"
optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*"
+python-versions = ">=3.5"
[[package]]
name = "ecdsa"
@@ -412,11 +412,11 @@ python-versions = "*"
[[package]]
name = "lazy-object-proxy"
-version = "1.5.2"
+version = "1.6.0"
description = "A fast and thorough lazy object proxy."
category = "dev"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[[package]]
name = "livereload"
@@ -610,7 +610,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
name = "pillow"
version = "8.2.0"
description = "Python Imaging Library (Fork)"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
@@ -698,14 +698,14 @@ python-versions = "*"
[[package]]
name = "pylint"
-version = "2.7.2"
+version = "2.7.4"
description = "python code static checker"
category = "dev"
optional = false
python-versions = "~=3.6"
[package.dependencies]
-astroid = ">=2.5.1,<2.6"
+astroid = ">=2.5.2,<2.7"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
isort = ">=4.2.5,<6"
mccabe = ">=0.6,<0.7"
@@ -951,7 +951,7 @@ python-versions = ">=3.6"
[[package]]
name = "sqlalchemy"
-version = "1.4.2"
+version = "1.4.5"
description = "Database Abstraction Library"
category = "main"
optional = false
@@ -962,6 +962,7 @@ greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\""}
[package.extras]
aiomysql = ["greenlet (!=0.4.17)", "aiomysql"]
+aiosqlite = ["greenlet (!=0.4.17)", "aiosqlite"]
asyncio = ["greenlet (!=0.4.17)"]
mariadb_connector = ["mariadb (>=1.0.1)"]
mssql = ["pyodbc"]
@@ -977,6 +978,7 @@ postgresql_pg8000 = ["pg8000 (>=1.16.6)"]
postgresql_psycopg2binary = ["psycopg2-binary"]
postgresql_psycopg2cffi = ["psycopg2cffi"]
pymysql = ["pymysql (<1)", "pymysql"]
+sqlcipher = ["sqlcipher3-binary"]
[[package]]
name = "starlette"
@@ -1162,7 +1164,7 @@ python-versions = "*"
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
-content-hash = "32bff6a472fd8564106e2cfa20161a47d271d89ed44a5f2f2483f419fe259c92"
+content-hash = "a81463b941cfdbc0e32e215644b172ec1111d5ada27864292d299d7d64fae4cf"
[metadata.files]
aiofiles = [
@@ -1182,8 +1184,8 @@ apscheduler = [
{file = "APScheduler-3.7.0.tar.gz", hash = "sha256:1cab7f2521e107d07127b042155b632b7a1cd5e02c34be5a28ff62f77c900c6a"},
]
astroid = [
- {file = "astroid-2.5.1-py3-none-any.whl", hash = "sha256:21d735aab248253531bb0f1e1e6d068f0ee23533e18ae8a6171ff892b98297cf"},
- {file = "astroid-2.5.1.tar.gz", hash = "sha256:cfc35498ee64017be059ceffab0a25bedf7548ab76f2bea691c5565896e7128d"},
+ {file = "astroid-2.5.2-py3-none-any.whl", hash = "sha256:cd80bf957c49765dce6d92c43163ff9d2abc43132ce64d4b1b47717c6d2522df"},
+ {file = "astroid-2.5.2.tar.gz", hash = "sha256:6b0ed1af831570e500e2437625979eaa3b36011f66ddfc4ce930128610258ca9"},
]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
@@ -1320,8 +1322,8 @@ coverage = [
{file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
]
decorator = [
- {file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"},
- {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"},
+ {file = "decorator-5.0.4-py3-none-any.whl", hash = "sha256:7280eff5351d7004144b1f302347328c3d06e84271dbe690a5dc4b17eb586994"},
+ {file = "decorator-5.0.4.tar.gz", hash = "sha256:cdd9d86d8aca11e4496f3cd26d48020db5a2fac247af0e918b3e0bbdb6e4a174"},
]
ecdsa = [
{file = "ecdsa-0.14.1-py2.py3-none-any.whl", hash = "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe"},
@@ -1444,30 +1446,28 @@ jstyleson = [
{file = "jstyleson-0.0.2.tar.gz", hash = "sha256:680003f3b15a2959e4e6a351f3b858e3c07dd3e073a0d54954e34d8ea5e1308e"},
]
lazy-object-proxy = [
- {file = "lazy-object-proxy-1.5.2.tar.gz", hash = "sha256:5944a9b95e97de1980c65f03b79b356f30a43de48682b8bdd90aa5089f0ec1f4"},
- {file = "lazy_object_proxy-1.5.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e960e8be509e8d6d618300a6c189555c24efde63e85acaf0b14b2cd1ac743315"},
- {file = "lazy_object_proxy-1.5.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:522b7c94b524389f4a4094c4bf04c2b02228454ddd17c1a9b2801fac1d754871"},
- {file = "lazy_object_proxy-1.5.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:3782931963dc89e0e9a0ae4348b44762e868ea280e4f8c233b537852a8996ab9"},
- {file = "lazy_object_proxy-1.5.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:429c4d1862f3fc37cd56304d880f2eae5bd0da83bdef889f3bd66458aac49128"},
- {file = "lazy_object_proxy-1.5.2-cp35-cp35m-win32.whl", hash = "sha256:cd1bdace1a8762534e9a36c073cd54e97d517a17d69a17985961265be6d22847"},
- {file = "lazy_object_proxy-1.5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:ddbdcd10eb999d7ab292677f588b658372aadb9a52790f82484a37127a390108"},
- {file = "lazy_object_proxy-1.5.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ecb5dd5990cec6e7f5c9c1124a37cb2c710c6d69b0c1a5c4aa4b35eba0ada068"},
- {file = "lazy_object_proxy-1.5.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b6577f15d5516d7d209c1a8cde23062c0f10625f19e8dc9fb59268859778d7d7"},
- {file = "lazy_object_proxy-1.5.2-cp36-cp36m-win32.whl", hash = "sha256:c8fe2d6ff0ff583784039d0255ea7da076efd08507f2be6f68583b0da32e3afb"},
- {file = "lazy_object_proxy-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:fa5b2dee0e231fa4ad117be114251bdfe6afe39213bd629d43deb117b6a6c40a"},
- {file = "lazy_object_proxy-1.5.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1d33d6f789697f401b75ce08e73b1de567b947740f768376631079290118ad39"},
- {file = "lazy_object_proxy-1.5.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:57fb5c5504ddd45ed420b5b6461a78f58cbb0c1b0cbd9cd5a43ad30a4a3ee4d0"},
- {file = "lazy_object_proxy-1.5.2-cp37-cp37m-win32.whl", hash = "sha256:e7273c64bccfd9310e9601b8f4511d84730239516bada26a0c9846c9697617ef"},
- {file = "lazy_object_proxy-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f4e5e68b7af950ed7fdb594b3f19a0014a3ace0fedb86acb896e140ffb24302"},
- {file = "lazy_object_proxy-1.5.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cadfa2c2cf54d35d13dc8d231253b7985b97d629ab9ca6e7d672c35539d38163"},
- {file = "lazy_object_proxy-1.5.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e7428977763150b4cf83255625a80a23dfdc94d43be7791ce90799d446b4e26f"},
- {file = "lazy_object_proxy-1.5.2-cp38-cp38-win32.whl", hash = "sha256:2f2de8f8ac0be3e40d17730e0600619d35c78c13a099ea91ef7fb4ad944ce694"},
- {file = "lazy_object_proxy-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:38c3865bd220bd983fcaa9aa11462619e84a71233bafd9c880f7b1cb753ca7fa"},
- {file = "lazy_object_proxy-1.5.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:8a44e9901c0555f95ac401377032f6e6af66d8fc1fbfad77a7a8b1a826e0b93c"},
- {file = "lazy_object_proxy-1.5.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fa7fb7973c622b9e725bee1db569d2c2ee64d2f9a089201c5e8185d482c7352d"},
- {file = "lazy_object_proxy-1.5.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:71a1ef23f22fa8437974b2d60fedb947c99a957ad625f83f43fd3de70f77f458"},
- {file = "lazy_object_proxy-1.5.2-cp39-cp39-win32.whl", hash = "sha256:ef3f5e288aa57b73b034ce9c1f1ac753d968f9069cd0742d1d69c698a0167166"},
- {file = "lazy_object_proxy-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:37d9c34b96cca6787fe014aeb651217944a967a5b165e2cacb6b858d2997ab84"},
+ {file = "lazy-object-proxy-1.6.0.tar.gz", hash = "sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726"},
+ {file = "lazy_object_proxy-1.6.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b"},
+ {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win32.whl", hash = "sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e"},
+ {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93"},
+ {file = "lazy_object_proxy-1.6.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741"},
+ {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587"},
+ {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4"},
+ {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win32.whl", hash = "sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f"},
+ {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3"},
+ {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981"},
+ {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2"},
+ {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win32.whl", hash = "sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd"},
+ {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837"},
+ {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653"},
+ {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3"},
+ {file = "lazy_object_proxy-1.6.0-cp38-cp38-win32.whl", hash = "sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8"},
+ {file = "lazy_object_proxy-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf"},
+ {file = "lazy_object_proxy-1.6.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad"},
+ {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43"},
+ {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a"},
+ {file = "lazy_object_proxy-1.6.0-cp39-cp39-win32.whl", hash = "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61"},
+ {file = "lazy_object_proxy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b"},
]
livereload = [
{file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"},
@@ -1714,8 +1714,8 @@ pyhumps = [
{file = "pyhumps-1.6.1.tar.gz", hash = "sha256:01612603c5ad73a407299d806d30708a3935052276fdd93776953bccc0724e0a"},
]
pylint = [
- {file = "pylint-2.7.2-py3-none-any.whl", hash = "sha256:d09b0b07ba06bcdff463958f53f23df25e740ecd81895f7d2699ec04bbd8dc3b"},
- {file = "pylint-2.7.2.tar.gz", hash = "sha256:0e21d3b80b96740909d77206d741aa3ce0b06b41be375d92e1f3244a274c1f8a"},
+ {file = "pylint-2.7.4-py3-none-any.whl", hash = "sha256:209d712ec870a0182df034ae19f347e725c1e615b2269519ab58a35b3fcbbe7a"},
+ {file = "pylint-2.7.4.tar.gz", hash = "sha256:bd38914c7731cdc518634a8d3c5585951302b6e2b6de60fbb3f7a0220e21eeee"},
]
pymdown-extensions = [
{file = "pymdown-extensions-8.1.1.tar.gz", hash = "sha256:632371fa3bf1b21a0e3f4063010da59b41db049f261f4c0b0872069a9b6d1735"},
@@ -1849,40 +1849,40 @@ soupsieve = [
{file = "soupsieve-2.2.1.tar.gz", hash = "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc"},
]
sqlalchemy = [
- {file = "SQLAlchemy-1.4.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:aed22be55a608787bb6875dbcf3561349a0e88fe33fd88c318c1e5b4eeb2306a"},
- {file = "SQLAlchemy-1.4.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:7e1b0ed6d720750f02333d2f52502dfc2a23185aacc2cc6ce6ec29d28c21397c"},
- {file = "SQLAlchemy-1.4.2-cp27-cp27m-win32.whl", hash = "sha256:9406b96a979ab8d6de5d89f58b1f103c9aeef6fb5367448537a8228619f11258"},
- {file = "SQLAlchemy-1.4.2-cp27-cp27m-win_amd64.whl", hash = "sha256:59ec279f1bd55e1d703e3d4b651600cc463cc3eafa8d8e5a70ab844f736348d4"},
- {file = "SQLAlchemy-1.4.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8cfcfcf2582b19c874fa20d0b75100abe17be80a4c637c0683b4eb919946dfee"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a6b4b7688fe7d251bbae3f9da4a487568bd584d13201bc7591c8639ad01fecdc"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0abab6d1044198993256f073340b14c459736777c550a7e914cd00444dcf9c30"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:5fb8f6a391992dd6aafe4fdf1dffbf7934fba1f5938593f20b152aa7f9619f82"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:97e333260a99d989f2a131aa8aa74140636dfbd030987150cb3748da607ea7db"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3fa75c854dba3f9b9c28bc5d88d246f6bc6f20b7480367c65339bcb2864d4707"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-win32.whl", hash = "sha256:1b9f3c7b281aa1c3d0c74ef12c4633e5f8358bb94f01be7b964887183fd53e5e"},
- {file = "SQLAlchemy-1.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:da72e3499bde4548e8b7d7f2ab23ceed09a5bac307bf51057e066c406a0ba2e1"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:8383292298bb85d7ad79a13c6571aff213b96c49737f3c3af129de63bbfb42c9"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4d1447183356c9679853926e81c7ebce3fbca9b1c607ea439975298c72137a36"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ff76d7dbf33f62e30e5a1d1b095d46afcdc49e42cbe33ce12014110147466700"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:1ba6922331b3f38e116c9266206b044baf64576e5cebd87917b5ad872d7a025f"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:d3b2819f4d7ae56191efc6fc456eb1805ada2bd5ba93d918893bc24fa7a1e30c"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:3b290ff34de625143a05d2d172a88a064bb04a7938265b09d4e4bf45f21948f6"},
- {file = "SQLAlchemy-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5289cafee71037f15feeeaf736f01910b9e3572525b73b201bdd21816db010ed"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:0bb04fd7414718fb1f4dfa17efcb0be787363451cf99a5e992728925d298d9ae"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:4e88549a5e58ba8c80c5ea071ac3b4e590236672a882bb80f56da4afcee45d96"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:edec945ed57d11a1123657e4066f0bf747aaa93c8a65ec1c2c98172d1f2a9b7d"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:06125670280111e39014af87f14d74599fd4b39a512c74f1a10e21e5626eb158"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:e1692bdf1b95c97caab1201773a4576f59627997f598d30bdadc50dd9f897fec"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-win32.whl", hash = "sha256:65c4df9517da9cce2c1255282d3e39f2afbc3a02deba60d99b0a3283ae80ec0b"},
- {file = "SQLAlchemy-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:c6197c88ad53c31f58de5a8180936b8ef027356e788cd5f6514b3439d3d897ac"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:6d6115edf1297bfa58994986ffe0dff21af18f0cba51dfa6d1769aa8a277be32"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:facacaea95e0822f7bbeaa6909b30b2836b14cff8790209d52a0c866e240b673"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6e517126d3bc13d455826befdc35a89f82f01d163848f68db02caa80d25433fc"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:09b08eb1bea621e47c2b0fcb0334fcbb00e1da2a3c2d45a98e56cd072b840719"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:7eba42098a13a3bcd509080b5e44d73783d9129ba0383793979bf518d01e8bb3"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-win32.whl", hash = "sha256:920db115eb06fc507fe2c774fb5c82a898b05dffbdadc7fafad51ce2cfd8c549"},
- {file = "SQLAlchemy-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:dcde5067a7dab1ff2eaea2f3622b2055c5225ce2aaf589c5a4c703d43519c4ba"},
- {file = "SQLAlchemy-1.4.2.tar.gz", hash = "sha256:6a8e4c2e65028933a6dc8643c8f5a4f295a367131195b3c708634925cb3e8ec1"},
+ {file = "SQLAlchemy-1.4.5-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c3810ebcf1d42c532c8f5c3f442c705d94442a27a32f2df5344f0857306ab321"},
+ {file = "SQLAlchemy-1.4.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:7481f9c2c832a3bf37c80bee44d91ac9938b815cc06f7e795b976e300914aab9"},
+ {file = "SQLAlchemy-1.4.5-cp27-cp27m-win32.whl", hash = "sha256:94040a92b6676f9ffdab6c6b479b3554b927a635c90698c761960b266b04fc88"},
+ {file = "SQLAlchemy-1.4.5-cp27-cp27m-win_amd64.whl", hash = "sha256:02b039e0e7e6de2f15ea2d2de3995e31a170e700ec0b37b4eded662171711d19"},
+ {file = "SQLAlchemy-1.4.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f16801795f1ffe9472360589a04301018c79e4582a85e68067275bb4f765e4e2"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:82f11b679df91275788be6734dd4a9dfa29bac67b85326992609f62b05bdab37"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:a08027ae84efc563f0f2f341dda572eadebeca38c0ae028a009988f27e9e6230"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:70a1387396ea5b3022539b560c287daf79403d8b4b365f89b56d660e625a4457"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:4f7ce3bfdab6520554af4a5b1df4513d45388624d015ba4d921daf48ce1d6503"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:08943201a1e3c6238e48f4d5d56c27ea1e1b39d3d9f36a9d81fc3cfb0e1b83bd"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-win32.whl", hash = "sha256:fbb0fda1c574975807aceb0e2332e0ecfe9e5656c191ed482c1a5eafe7a33823"},
+ {file = "SQLAlchemy-1.4.5-cp36-cp36m-win_amd64.whl", hash = "sha256:8d6a9feb5efd2fdab25c6d5a0a5589fed9d789f5ec57ec12263fd0e60ce1dea6"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:c22bfac8d3b955cdb13f0fcd6343156bf56d925196cf7d9ab9ce9f61d3f1e11c"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7c0c7bb49167ac738ca6ee6e7f94a9988a7e4e261d8da335341e8c8c8f3b2e9b"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:344b58b4b4193b72e8b768a51ef6eb5a4c948ce313a0f23e2ea081e71ce8ac0e"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:48540072f43b3c080159ec1f24a4b014c0ee83d3b73795399974aa358a8cf71b"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:81badd7d3e0e6aba70a5d1b50fabe8112e9835a6fdb0684054c3fe5378ce0d01"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:a103294583383660d9e06dbd82037dc8e94c184bdcb27b2be44ae4457dafc6b4"},
+ {file = "SQLAlchemy-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5361e25181b9872d6906c8c9be7dc05cb0a0951d71ee59ee5a71c1deb301b8a8"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:7f5087104c3c5af11ea59e49ae66c33ca98b14a47d3796ae97498fca53f84aef"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:11e7a86209f69273e75d2dd64b06c0c2660e39cd942fce2170515c404ed7358a"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:8301ecf3e819eb5dbc171e84654ff60872807775301a55fe35b0ab2ba3742031"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:44e11a06168782b6d485daef197783366ce7ab0d5eea0066c899ae06cef47bbc"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:6f8fdad2f335d2f3ca2f3ee3b01404f7abcf519b03de2c510f1f42d16e39ffb4"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-win32.whl", hash = "sha256:f62c57ceadedeb8e7b98b48ac4d684bf2b0f73b9d882fed3ca260d9aedf6403f"},
+ {file = "SQLAlchemy-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:301d0cd6ef1dc73b607748183da857e712d6f743de8d92b1e1f8facfb0ba2aa2"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:915d4fa08776c0252dc5a34fa15c6490f66f411ea1ac9492022f98875d6baf20"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7de84feb31af3d8fdf819cac2042928d0b60d3cb16f49c4b2f48d88db46e79f6"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:45b091ccbf94374ed14abde17e9a04522b0493a17282eaaf4383efdd413f5243"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:4df07161897191ed8d4a0cfc92425c81296160e5c5f76c9256716d3085172883"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ee4ddc904fb6414b5118af5b8d45e428aac2ccda01326b2ba2fe4354b0d8d1ae"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-win32.whl", hash = "sha256:2f11b5783933bff55291ca06496124347627d211ff2e509e846af1c35de0a3fb"},
+ {file = "SQLAlchemy-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:0ee0054d4a598d2920cae14bcbd33e200e02c5e3b47b902627f8cf5d4c9a2a4b"},
+ {file = "SQLAlchemy-1.4.5.tar.gz", hash = "sha256:1294f05916c044631fd626a4866326bbfbd17f62bd37510d000afaef4b35bd74"},
]
starlette = [
{file = "starlette-0.13.6-py3-none-any.whl", hash = "sha256:bd2ffe5e37fb75d014728511f8e68ebf2c80b0fa3d04ca1479f4dc752ae31ac9"},
diff --git a/pyproject.toml b/pyproject.toml
index 68dd7b38c..5af7567e6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -30,6 +30,8 @@ bcrypt = "^3.2.0"
python-jose = "^3.2.0"
passlib = "^1.7.4"
lxml = "4.6.2"
+Pillow = "^8.2.0"
+
[tool.poetry.dev-dependencies]
pylint = "^2.6.0"
@@ -39,7 +41,6 @@ pytest-cov = "^2.11.0"
mkdocs-material = "^7.0.2"
flake8 = "^3.9.0"
coverage = "^5.5"
-Pillow = "^8.2.0"
[build-system]
requires = ["poetry-core>=1.0.0"]