📦 Proper Package + Black Config
5
.vscode/settings.json
vendored
|
@ -5,13 +5,14 @@
|
|||
"python.linting.enabled": true,
|
||||
"python.autoComplete.extraPaths": ["mealie", "mealie/mealie"],
|
||||
"python.analysis.extraPaths": ["mealie", "mealie/mealie"],
|
||||
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.nosetestsEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"python.testing.autoTestDiscoverOnSaveEnabled": false,
|
||||
"python.testing.pytestArgs": [
|
||||
"tests"
|
||||
],
|
||||
"cSpell.enableFiletypes": ["!javascript", "!python"],
|
||||
"python.testing.pytestArgs": ["mealie"],
|
||||
"i18n-ally.localesPaths": "frontend/src/locales",
|
||||
"i18n-ally.enabledFrameworks": ["vue"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
|
||||
|
||||

|
||||

|
||||
|
||||
# {{ recipe.name }}
|
||||
{{ recipe.description }}
|
||||
|
||||
## Ingredients
|
||||
{% for ingredient in recipe.recipeIngredient %}
|
||||
- [ ] {{ ingredient }}
|
||||
{% endfor %}
|
||||
{% for ingredient in recipe.recipeIngredient %}
|
||||
- [ ] {{ ingredient }} {% endfor %}
|
||||
|
||||
## Instructions
|
||||
{% for step in recipe.recipeInstructions %}
|
||||
- [ ] {{ step.text }}
|
||||
{% endfor %}
|
||||
{% for step in recipe.recipeInstructions %}
|
||||
- [ ] {{ step.text }} {% endfor %}
|
||||
|
||||
{% for note in recipe.notes %}
|
||||
**{{ note.title }}:** {{ note.text }}
|
||||
|
|
|
@ -3,25 +3,25 @@ from fastapi import FastAPI
|
|||
from fastapi.logger import logger
|
||||
|
||||
# import utils.startup as startup
|
||||
from core.config import APP_VERSION, PORT, docs_url, redoc_url
|
||||
from db.db_setup import sql_exists
|
||||
from db.init_db import init_db
|
||||
from routes import (
|
||||
from mealie.core.config import APP_VERSION, PORT, docs_url, redoc_url
|
||||
from mealie.db.db_setup import sql_exists
|
||||
from mealie.db.init_db import init_db
|
||||
from mealie.routes import (
|
||||
backup_routes,
|
||||
debug_routes,
|
||||
migration_routes,
|
||||
setting_routes,
|
||||
theme_routes,
|
||||
)
|
||||
from routes.groups import groups
|
||||
from routes.mealplans import mealplans
|
||||
from routes.recipe import (
|
||||
from mealie.routes.groups import groups
|
||||
from mealie.routes.mealplans import mealplans
|
||||
from mealie.routes.recipe import (
|
||||
all_recipe_routes,
|
||||
category_routes,
|
||||
recipe_crud_routes,
|
||||
tag_routes,
|
||||
)
|
||||
from routes.users import users
|
||||
from mealie.routes.users import users
|
||||
|
||||
app = FastAPI(
|
||||
title="Mealie",
|
||||
|
@ -37,7 +37,7 @@ def data_base_first_run():
|
|||
|
||||
|
||||
def start_scheduler():
|
||||
import services.scheduler.scheduled_jobs
|
||||
import mealie.services.scheduler.scheduled_jobs
|
||||
|
||||
|
||||
def api_routers():
|
||||
|
@ -68,8 +68,8 @@ if not sql_exists:
|
|||
api_routers()
|
||||
start_scheduler()
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("-----SYSTEM STARTUP-----")
|
||||
|
||||
def main():
|
||||
|
||||
uvicorn.run(
|
||||
"app:app",
|
||||
|
@ -81,3 +81,8 @@ if __name__ == "__main__":
|
|||
workers=1,
|
||||
forwarded_allow_ips="*",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("-----SYSTEM STARTUP-----")
|
||||
main()
|
||||
|
|
|
@ -78,9 +78,7 @@ if DATABASE_TYPE == "sqlite":
|
|||
SQLITE_FILE = SQLITE_DIR.joinpath(f"mealie_{DB_VERSION}.sqlite")
|
||||
|
||||
else:
|
||||
raise Exception(
|
||||
"Unable to determine database type. Acceptible options are 'sqlite' "
|
||||
)
|
||||
raise Exception("Unable to determine database type. Acceptible options are 'sqlite' ")
|
||||
|
||||
# Mongo Database
|
||||
MEALIE_DB_NAME = os.getenv("mealie_db_name", "mealie")
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
from schema.category import RecipeCategoryResponse, RecipeTagResponse
|
||||
from schema.meal import MealPlanInDB
|
||||
from schema.recipe import Recipe
|
||||
from schema.settings import SiteSettings as SiteSettingsSchema
|
||||
from schema.sign_up import SignUpOut
|
||||
from schema.theme import SiteTheme
|
||||
from schema.user import GroupInDB, UserInDB
|
||||
from mealie.schema.category import RecipeCategoryResponse, RecipeTagResponse
|
||||
from mealie.schema.meal import MealPlanInDB
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.schema.settings import SiteSettings as SiteSettingsSchema
|
||||
from mealie.schema.sign_up import SignUpOut
|
||||
from mealie.schema.theme import SiteTheme
|
||||
from mealie.schema.user import GroupInDB, UserInDB
|
||||
from sqlalchemy.orm import load_only
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from db.db_base import BaseDocument
|
||||
from db.models.group import Group
|
||||
from db.models.mealplan import MealPlanModel
|
||||
from db.models.recipe.recipe import Category, RecipeModel, Tag
|
||||
from db.models.settings import SiteSettings
|
||||
from db.models.sign_up import SignUp
|
||||
from db.models.theme import SiteThemeModel
|
||||
from db.models.users import User
|
||||
from mealie.db.db_base import BaseDocument
|
||||
from mealie.db.models.group import Group
|
||||
from mealie.db.models.mealplan import MealPlanModel
|
||||
from mealie.db.models.recipe.recipe import Category, RecipeModel, Tag
|
||||
from mealie.db.models.settings import SiteSettings
|
||||
from mealie.db.models.sign_up import SignUp
|
||||
from mealie.db.models.theme import SiteThemeModel
|
||||
from mealie.db.models.users import User
|
||||
|
||||
|
||||
class _Recipes(BaseDocument):
|
||||
|
@ -95,9 +95,7 @@ class _Groups(BaseDocument):
|
|||
self.orm_mode = True
|
||||
self.schema = GroupInDB
|
||||
|
||||
def get_meals(
|
||||
self, session: Session, match_value: str, match_key: str = "name"
|
||||
) -> list[MealPlanInDB]:
|
||||
def get_meals(self, session: Session, match_value: str, match_key: str = "name") -> list[MealPlanInDB]:
|
||||
"""A Helper function to get the group from the database and return a sorted list of
|
||||
|
||||
Args:
|
||||
|
@ -108,13 +106,11 @@ class _Groups(BaseDocument):
|
|||
Returns:
|
||||
list[MealPlanInDB]: [description]
|
||||
"""
|
||||
group: GroupInDB = (
|
||||
session.query(self.sql_model)
|
||||
.filter_by(**{match_key: match_value})
|
||||
.one_or_none()
|
||||
)
|
||||
group: GroupInDB = session.query(self.sql_model).filter_by(**{match_key: match_value}).one_or_none()
|
||||
|
||||
return sorted(group.mealplans, key=lambda mealplan: mealplan.startDate)
|
||||
# Potentially not needed? column is sorted by SqlAlchemy based on startDate
|
||||
# return sorted(group.mealplans, key=lambda mealplan: mealplan.startDate)
|
||||
return group.mealplans
|
||||
|
||||
|
||||
class _SignUps(BaseDocument):
|
||||
|
|
|
@ -4,7 +4,7 @@ from pydantic import BaseModel
|
|||
from sqlalchemy.orm import load_only
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class BaseDocument:
|
||||
|
@ -16,15 +16,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) -> List[dict]:
|
||||
|
||||
if self.orm_mode:
|
||||
return [
|
||||
self.schema.from_orm(x)
|
||||
for x in session.query(self.sql_model).limit(limit).all()
|
||||
]
|
||||
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()]
|
||||
|
||||
|
@ -33,9 +28,7 @@ class BaseDocument:
|
|||
|
||||
return list
|
||||
|
||||
def get_all_limit_columns(
|
||||
self, session: Session, fields: List[str], limit: int = None
|
||||
) -> List[SqlAlchemyBase]:
|
||||
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
|
||||
keys specified under "fields"
|
||||
|
||||
|
@ -47,9 +40,7 @@ class BaseDocument:
|
|||
Returns:
|
||||
list[SqlAlchemyBase]: Returns a list of ORM objects
|
||||
"""
|
||||
results = (
|
||||
session.query(self.sql_model).options(load_only(*fields)).limit(limit).all()
|
||||
)
|
||||
results = session.query(self.sql_model).options(load_only(*fields)).limit(limit).all()
|
||||
|
||||
return results
|
||||
|
||||
|
@ -63,15 +54,11 @@ class BaseDocument:
|
|||
Returns:
|
||||
list[str]:
|
||||
"""
|
||||
results = session.query(self.sql_model).options(
|
||||
load_only(str(self.primary_key))
|
||||
)
|
||||
results = session.query(self.sql_model).options(load_only(str(self.primary_key)))
|
||||
results_as_dict = [x.dict() for x in results]
|
||||
return [x.get(self.primary_key) for x in results_as_dict]
|
||||
|
||||
def _query_one(
|
||||
self, session: Session, match_value: str, match_key: str = None
|
||||
) -> SqlAlchemyBase:
|
||||
def _query_one(self, session: Session, match_value: str, match_key: str = None) -> SqlAlchemyBase:
|
||||
"""Query the sql database for one item an return the sql alchemy model
|
||||
object. If no match key is provided the primary_key attribute will be used.
|
||||
|
||||
|
@ -85,15 +72,11 @@ class BaseDocument:
|
|||
if match_key == None:
|
||||
match_key = self.primary_key
|
||||
|
||||
result = (
|
||||
session.query(self.sql_model).filter_by(**{match_key: match_value}).one()
|
||||
)
|
||||
result = session.query(self.sql_model).filter_by(**{match_key: match_value}).one()
|
||||
|
||||
return result
|
||||
|
||||
def get(
|
||||
self, session: Session, match_value: str, match_key: str = None, limit=1
|
||||
) -> dict or List[dict]:
|
||||
def get(self, session: Session, match_value: str, match_key: str = None, limit=1) -> dict or List[dict]:
|
||||
"""Retrieves an entry from the database by matching a key/value pair. If no
|
||||
key is provided the class objects primary key will be used to match against.
|
||||
|
||||
|
@ -109,12 +92,7 @@ class BaseDocument:
|
|||
if match_key == None:
|
||||
match_key = self.primary_key
|
||||
|
||||
result = (
|
||||
session.query(self.sql_model)
|
||||
.filter_by(**{match_key: match_value})
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
result = session.query(self.sql_model).filter_by(**{match_key: match_value}).limit(limit).all()
|
||||
|
||||
if limit == 1:
|
||||
try:
|
||||
|
@ -167,11 +145,7 @@ class BaseDocument:
|
|||
return return_data
|
||||
|
||||
def delete(self, session: Session, primary_key_value) -> dict:
|
||||
result = (
|
||||
session.query(self.sql_model)
|
||||
.filter_by(**{self.primary_key: primary_key_value})
|
||||
.one()
|
||||
)
|
||||
result = session.query(self.sql_model).filter_by(**{self.primary_key: primary_key_value}).one()
|
||||
|
||||
session.delete(result)
|
||||
session.commit()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from core.config import SQLITE_FILE, USE_SQL
|
||||
from mealie.core.config import SQLITE_FILE, USE_SQL
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from db.models.db_session import sql_global_init
|
||||
from mealie.db.models.db_session import sql_global_init
|
||||
|
||||
sql_exists = True
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from core.config import DEFAULT_GROUP
|
||||
from core.security import get_password_hash
|
||||
from mealie.core.config import DEFAULT_GROUP
|
||||
from mealie.core.security import get_password_hash
|
||||
from fastapi.logger import logger
|
||||
from schema.settings import SiteSettings
|
||||
from schema.theme import SiteTheme
|
||||
from mealie.schema.settings import SiteSettings
|
||||
from mealie.schema.theme import SiteTheme
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
|
||||
|
||||
def init_db(db: Session = None) -> None:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from db.models.mealplan import *
|
||||
from db.models.recipe.recipe import *
|
||||
from db.models.settings import *
|
||||
from db.models.theme import *
|
||||
from db.models.users import *
|
||||
from db.models.sign_up import *
|
||||
from db.models.group import *
|
||||
from mealie.db.models.mealplan import *
|
||||
from mealie.db.models.recipe.recipe import *
|
||||
from mealie.db.models.settings import *
|
||||
from mealie.db.models.theme import *
|
||||
from mealie.db.models.users import *
|
||||
from mealie.db.models.sign_up import *
|
||||
from mealie.db.models.group import *
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ def sql_global_init(db_file: Path, check_thread=False):
|
|||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
import db.models._all_models
|
||||
import mealie.db.models._all_models
|
||||
|
||||
SqlAlchemyBase.metadata.create_all(engine)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from core.config import DEFAULT_GROUP
|
||||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from db.models.recipe.category import Category, group2categories
|
||||
from mealie.core.config import DEFAULT_GROUP
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.recipe.category import Category, group2categories
|
||||
from fastapi.logger import logger
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
@ -20,18 +20,17 @@ class Group(SqlAlchemyBase, BaseMixins):
|
|||
name = sa.Column(sa.String, index=True, nullable=False, unique=True)
|
||||
users = orm.relationship("User", back_populates="group")
|
||||
mealplans = orm.relationship(
|
||||
"MealPlanModel", back_populates="group", single_parent=True
|
||||
)
|
||||
categories = orm.relationship(
|
||||
"Category", secondary=group2categories, single_parent=True
|
||||
"MealPlanModel",
|
||||
back_populates="group",
|
||||
single_parent=True,
|
||||
order_by="MealPlanModel.startDate",
|
||||
)
|
||||
categories = orm.relationship("Category", secondary=group2categories, single_parent=True)
|
||||
|
||||
# Webhook Settings
|
||||
webhook_enable = sa.Column(sa.Boolean, default=False)
|
||||
webhook_time = sa.Column(sa.String, default="00:00")
|
||||
webhook_urls = orm.relationship(
|
||||
"WebhookURLModel", uselist=True, cascade="all, delete"
|
||||
)
|
||||
webhook_urls = orm.relationship("WebhookURLModel", uselist=True, cascade="all, delete")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -46,10 +45,7 @@ class Group(SqlAlchemyBase, BaseMixins):
|
|||
webhook_urls=[],
|
||||
) -> None:
|
||||
self.name = name
|
||||
self.categories = [
|
||||
Category.get_ref(session=session, slug=cat.get("slug"))
|
||||
for cat in categories
|
||||
]
|
||||
self.categories = [Category.get_ref(session=session, slug=cat.get("slug")) for cat in categories]
|
||||
|
||||
self.webhook_enable = webhook_enable
|
||||
self.webhook_time = webhook_time
|
||||
|
|
|
@ -2,8 +2,8 @@ from typing import List
|
|||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.group import Group
|
||||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.group import Group
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
|
||||
|
||||
class Meal(SqlAlchemyBase):
|
||||
|
@ -33,9 +33,7 @@ class MealPlanModel(SqlAlchemyBase, BaseMixins):
|
|||
group_id = sa.Column(sa.String, sa.ForeignKey("groups.id"))
|
||||
group = orm.relationship("Group", back_populates="mealplans")
|
||||
|
||||
def __init__(
|
||||
self, startDate, endDate, meals, group: str, uid=None, session=None
|
||||
) -> None:
|
||||
def __init__(self, startDate, endDate, meals, group: str, uid=None, session=None) -> None:
|
||||
self.startDate = startDate
|
||||
self.endDate = endDate
|
||||
self.group = Group.get_ref(session, group)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date
|
||||
|
||||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class ApiExtras(SqlAlchemyBase):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
from fastapi.logger import logger
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm import validates
|
||||
|
@ -32,9 +32,7 @@ class Category(SqlAlchemyBase):
|
|||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
name = sa.Column(sa.String, index=True, nullable=False)
|
||||
slug = sa.Column(sa.String, index=True, unique=True, nullable=False)
|
||||
recipes = orm.relationship(
|
||||
"RecipeModel", secondary=recipes2categories, back_populates="recipeCategory"
|
||||
)
|
||||
recipes = orm.relationship("RecipeModel", secondary=recipes2categories, back_populates="recipeCategory")
|
||||
|
||||
@validates("name")
|
||||
def validate_name(self, key, name):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class RecipeIngredient(SqlAlchemyBase):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class RecipeInstruction(SqlAlchemyBase):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class Note(SqlAlchemyBase):
|
||||
|
@ -12,4 +12,3 @@ class Note(SqlAlchemyBase):
|
|||
def __init__(self, title, text) -> None:
|
||||
self.title = title
|
||||
self.text = text
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class Nutrition(SqlAlchemyBase):
|
||||
|
@ -28,4 +28,3 @@ class Nutrition(SqlAlchemyBase):
|
|||
self.proteinContent = proteinContent
|
||||
self.sodiumContent = sodiumContent
|
||||
self.sugarContent = sugarContent
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ from typing import List
|
|||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from db.models.recipe.api_extras import ApiExtras
|
||||
from db.models.recipe.category import Category, recipes2categories
|
||||
from db.models.recipe.ingredient import RecipeIngredient
|
||||
from db.models.recipe.instruction import RecipeInstruction
|
||||
from db.models.recipe.note import Note
|
||||
from db.models.recipe.nutrition import Nutrition
|
||||
from db.models.recipe.tag import Tag, recipes2tags
|
||||
from db.models.recipe.tool import Tool
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.recipe.api_extras import ApiExtras
|
||||
from mealie.db.models.recipe.category import Category, recipes2categories
|
||||
from mealie.db.models.recipe.ingredient import RecipeIngredient
|
||||
from mealie.db.models.recipe.instruction import RecipeInstruction
|
||||
from mealie.db.models.recipe.note import Note
|
||||
from mealie.db.models.recipe.nutrition import Nutrition
|
||||
from mealie.db.models.recipe.tag import Tag, recipes2tags
|
||||
from mealie.db.models.recipe.tool import Tool
|
||||
from sqlalchemy.ext.orderinglist import ordering_list
|
||||
from sqlalchemy.orm import validates
|
||||
|
||||
|
@ -33,12 +33,8 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
|||
recipeYield = sa.Column(sa.String)
|
||||
recipeCuisine = sa.Column(sa.String)
|
||||
tool: List[Tool] = orm.relationship("Tool", cascade="all, delete")
|
||||
nutrition: Nutrition = orm.relationship(
|
||||
"Nutrition", uselist=False, cascade="all, delete"
|
||||
)
|
||||
recipeCategory: List = orm.relationship(
|
||||
"Category", secondary=recipes2categories, back_populates="recipes"
|
||||
)
|
||||
nutrition: Nutrition = orm.relationship("Nutrition", uselist=False, cascade="all, delete")
|
||||
recipeCategory: List = orm.relationship("Category", secondary=recipes2categories, back_populates="recipes")
|
||||
|
||||
recipeIngredient: List[RecipeIngredient] = orm.relationship(
|
||||
"RecipeIngredient",
|
||||
|
@ -55,9 +51,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
|||
|
||||
# Mealie Specific
|
||||
slug = sa.Column(sa.String, index=True, unique=True)
|
||||
tags: List[Tag] = orm.relationship(
|
||||
"Tag", secondary=recipes2tags, back_populates="recipes"
|
||||
)
|
||||
tags: List[Tag] = orm.relationship("Tag", secondary=recipes2tags, back_populates="recipes")
|
||||
dateAdded = sa.Column(sa.Date, default=date.today)
|
||||
notes: List[Note] = orm.relationship("Note", cascade="all, delete")
|
||||
rating = sa.Column(sa.Integer)
|
||||
|
@ -106,9 +100,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
|||
self.tool = [Tool(tool=x) for x in tool] if tool else []
|
||||
|
||||
self.recipeYield = recipeYield
|
||||
self.recipeIngredient = [
|
||||
RecipeIngredient(ingredient=ingr) for ingr in recipeIngredient
|
||||
]
|
||||
self.recipeIngredient = [RecipeIngredient(ingredient=ingr) for ingr in recipeIngredient]
|
||||
self.recipeInstructions = [
|
||||
RecipeInstruction(text=instruc.get("text"), type=instruc.get("@type", None))
|
||||
for instruc in recipeInstructions
|
||||
|
@ -117,10 +109,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
|||
self.prepTime = prepTime
|
||||
self.performTime = performTime
|
||||
|
||||
self.recipeCategory = [
|
||||
Category.create_if_not_exist(session=session, name=cat)
|
||||
for cat in recipeCategory
|
||||
]
|
||||
self.recipeCategory = [Category.create_if_not_exist(session=session, name=cat) for cat in recipeCategory]
|
||||
|
||||
# Mealie Specific
|
||||
self.tags = [Tag.create_if_not_exist(session=session, name=tag) for tag in tags]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
from fastapi.logger import logger
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm import validates
|
||||
|
@ -18,9 +18,7 @@ class Tag(SqlAlchemyBase):
|
|||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
name = sa.Column(sa.String, index=True, nullable=False)
|
||||
slug = sa.Column(sa.String, index=True, unique=True, nullable=False)
|
||||
recipes = orm.relationship(
|
||||
"RecipeModel", secondary=recipes2tags, back_populates="tags"
|
||||
)
|
||||
recipes = orm.relationship("RecipeModel", secondary=recipes2tags, back_populates="tags")
|
||||
|
||||
@validates("name")
|
||||
def validate_name(self, key, name):
|
||||
|
@ -31,7 +29,6 @@ class Tag(SqlAlchemyBase):
|
|||
self.name = name.strip()
|
||||
self.slug = slugify(self.name)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def create_if_not_exist(session, name: str = None):
|
||||
test_slug = slugify(name)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sqlalchemy as sa
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class Tool(SqlAlchemyBase):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from db.models.recipe.category import Category, site_settings2categories
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.recipe.category import Category, site_settings2categories
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
|
@ -29,10 +29,7 @@ class SiteSettings(SqlAlchemyBase, BaseMixins):
|
|||
self.language = language
|
||||
self.cards_per_section = cards_per_section
|
||||
self.show_recent = show_recent
|
||||
self.categories = [
|
||||
Category.get_ref(session=session, name=cat.get("slug"))
|
||||
for cat in categories
|
||||
]
|
||||
self.categories = [Category.get_ref(session=session, name=cat.get("slug")) for cat in categories]
|
||||
|
||||
def update(self, *args, **kwarg):
|
||||
self.__init__(*args, **kwarg)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from sqlalchemy import Boolean, Column, Integer, String
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.models.model_base import SqlAlchemyBase
|
||||
from mealie.db.models.model_base import SqlAlchemyBase
|
||||
|
||||
|
||||
class SiteThemeModel(SqlAlchemyBase):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from core.config import DEFAULT_GROUP
|
||||
from db.models.group import Group
|
||||
from db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.core.config import DEFAULT_GROUP
|
||||
from mealie.db.models.group import Group
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, orm
|
||||
|
||||
# I'm not sure this is necessasry, browser based settings may be sufficient
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import operator
|
||||
import shutil
|
||||
|
||||
from core.config import BACKUP_DIR, TEMPLATE_DIR
|
||||
from db.db_setup import generate_session
|
||||
from mealie.core.config import BACKUP_DIR, TEMPLATE_DIR
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
|
||||
from schema.backup import BackupJob, ImportJob, Imports, LocalBackup
|
||||
from schema.snackbar import SnackResponse
|
||||
from services.backups.exports import backup_all
|
||||
from services.backups.imports import ImportDatabase
|
||||
from mealie.schema.backup import BackupJob, ImportJob, Imports, LocalBackup
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.services.backups.exports import backup_all
|
||||
from mealie.services.backups.imports import ImportDatabase
|
||||
from sqlalchemy.orm.session import Session
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
|
@ -71,17 +71,13 @@ async def upload_nextcloud_zipfile(file_name: str):
|
|||
file = BACKUP_DIR.joinpath(file_name)
|
||||
|
||||
if file.is_file:
|
||||
return FileResponse(
|
||||
file, media_type="application/octet-stream", filename=file_name
|
||||
)
|
||||
return FileResponse(file, media_type="application/octet-stream", filename=file_name)
|
||||
else:
|
||||
return SnackResponse.error("No File Found")
|
||||
|
||||
|
||||
@router.post("/{file_name}/import", status_code=200)
|
||||
def import_database(
|
||||
file_name: str, import_data: ImportJob, session: Session = Depends(generate_session)
|
||||
):
|
||||
def import_database(file_name: str, import_data: ImportJob, session: Session = Depends(generate_session)):
|
||||
""" Import a database backup file generated from Mealie. """
|
||||
|
||||
import_db = ImportDatabase(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
|
||||
from core.config import APP_VERSION, DEBUG_DIR, LOGGER_FILE
|
||||
from mealie.core.config import APP_VERSION, DEBUG_DIR, LOGGER_FILE
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter(prefix="/api/debug", tags=["Debug"])
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from core.config import SECRET
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.core.config import SECRET
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from fastapi_login import LoginManager
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from schema.user import UserInDB
|
||||
from mealie.schema.user import UserInDB
|
||||
|
||||
manager = LoginManager(SECRET, "/api/auth/token")
|
||||
|
||||
|
@ -21,4 +21,3 @@ def query_user(user_email: str, session: Session = None) -> UserInDB:
|
|||
user = db.users.get(session, user_email, "email")
|
||||
session.close()
|
||||
return user
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from routes.deps import manager
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import GroupBase, GroupInDB, UpdateGroup, UserInDB
|
||||
from mealie.routes.deps import manager
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import GroupBase, GroupInDB, UpdateGroup, UserInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/groups", tags=["Groups"])
|
||||
|
@ -59,9 +59,7 @@ async def update_group_data(
|
|||
|
||||
|
||||
@router.delete("/{id}")
|
||||
async def delete_user_group(
|
||||
id: int, current_user=Depends(manager), session: Session = Depends(generate_session)
|
||||
):
|
||||
async def delete_user_group(id: int, current_user=Depends(manager), session: Session = Depends(generate_session)):
|
||||
""" Removes a user group from the database """
|
||||
|
||||
if id == 1:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from fastapi import APIRouter
|
||||
from routes.groups import crud
|
||||
from mealie.routes.groups import crud
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
router.include_router(crud.router)
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import datetime
|
||||
|
||||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from routes.deps import manager
|
||||
from schema.meal import MealPlanIn, MealPlanInDB
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import GroupInDB, UserInDB
|
||||
from services.meal_services import get_todays_meal, process_meals
|
||||
from mealie.routes.deps import manager
|
||||
from mealie.schema.meal import MealPlanIn, MealPlanInDB
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import GroupInDB, UserInDB
|
||||
from mealie.services.meal_services import get_todays_meal, process_meals
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
|
||||
|
@ -37,9 +37,7 @@ def create_meal_plan(
|
|||
|
||||
|
||||
@router.put("/{plan_id}")
|
||||
def update_meal_plan(
|
||||
plan_id: str, meal_plan: MealPlanIn, session: Session = Depends(generate_session)
|
||||
):
|
||||
def update_meal_plan(plan_id: str, meal_plan: MealPlanIn, session: Session = Depends(generate_session)):
|
||||
""" Updates a meal plan based off ID """
|
||||
processed_plan = process_meals(session, meal_plan)
|
||||
processed_plan = MealPlanInDB(uid=plan_id, **processed_plan.dict())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from schema.meal import MealPlanInDB
|
||||
from schema.recipe import Recipe
|
||||
from mealie.schema.meal import MealPlanInDB
|
||||
from mealie.schema.recipe import Recipe
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
|
||||
|
@ -16,8 +16,6 @@ def get_shopping_list(id: str, session: Session = Depends(generate_session)):
|
|||
mealplan: MealPlanInDB
|
||||
slugs = [x.slug for x in mealplan.meals]
|
||||
recipes: list[Recipe] = [db.recipes.get(session, x) for x in slugs]
|
||||
ingredients = [
|
||||
{"name": x.name, "recipeIngredient": x.recipeIngredient} for x in recipes if x
|
||||
]
|
||||
ingredients = [{"name": x.name, "recipeIngredient": x.recipeIngredient} for x in recipes if x]
|
||||
|
||||
return ingredients
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from fastapi import APIRouter
|
||||
from routes.mealplans import crud, helpers
|
||||
from mealie.routes.mealplans import crud, helpers
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@ import operator
|
|||
import shutil
|
||||
from typing import List
|
||||
|
||||
from core.config import MIGRATION_DIR
|
||||
from db.db_setup import generate_session
|
||||
from mealie.core.config import MIGRATION_DIR
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
|
||||
from schema.migration import MigrationFile, Migrations
|
||||
from services.migrations.chowdown import chowdown_migrate as chowdow_migrate
|
||||
from services.migrations.nextcloud import migrate as nextcloud_migrate
|
||||
from mealie.schema.migration import MigrationFile, Migrations
|
||||
from mealie.services.migrations.chowdown import chowdown_migrate as chowdow_migrate
|
||||
from mealie.services.migrations.nextcloud import migrate as nextcloud_migrate
|
||||
from sqlalchemy.orm.session import Session
|
||||
from schema.snackbar import SnackResponse
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
|
||||
router = APIRouter(prefix="/api/migrations", tags=["Migration"])
|
||||
|
||||
|
@ -36,9 +36,7 @@ def get_avaiable_nextcloud_imports():
|
|||
|
||||
|
||||
@router.post("/{type}/{file_name}/import")
|
||||
def import_nextcloud_directory(
|
||||
type: str, file_name: str, session: Session = Depends(generate_session)
|
||||
):
|
||||
def import_nextcloud_directory(type: str, file_name: str, session: Session = Depends(generate_session)):
|
||||
""" Imports all the recipes in a given directory """
|
||||
file_path = MIGRATION_DIR.joinpath(type, file_name)
|
||||
if type == "nextcloud":
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from schema.recipe import AllRecipeRequest
|
||||
from mealie.schema.recipe import AllRecipeRequest
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
@ -44,9 +44,7 @@ def get_all_recipes(
|
|||
|
||||
|
||||
@router.post("/api/recipes")
|
||||
def get_all_recipes_post(
|
||||
body: AllRecipeRequest, session: Session = Depends(generate_session)
|
||||
):
|
||||
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
|
||||
|
@ -76,9 +74,7 @@ def get_all_recipes_post(
|
|||
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 """
|
||||
#! This should be refactored into a single database call, but I couldn't figure it out
|
||||
in_category = [
|
||||
db.categories.get(session, slugify(cat), limit=1) for cat in categories
|
||||
]
|
||||
in_category = [db.categories.get(session, slugify(cat), limit=1) for cat in categories]
|
||||
in_category = [cat.get("recipes") for cat in in_category if cat]
|
||||
in_category = [item for sublist in in_category for item in sublist]
|
||||
return in_category
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from schema.category import RecipeCategoryResponse
|
||||
from mealie.schema.category import RecipeCategoryResponse
|
||||
from sqlalchemy.orm.session import Session
|
||||
from schema.snackbar import SnackResponse
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
|
||||
from schema.snackbar import SnackResponse
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api/categories",
|
||||
|
@ -20,17 +20,13 @@ async def get_all_recipe_categories(session: Session = Depends(generate_session)
|
|||
|
||||
|
||||
@router.get("/{category}", response_model=RecipeCategoryResponse)
|
||||
def get_all_recipes_by_category(
|
||||
category: str, session: Session = Depends(generate_session)
|
||||
):
|
||||
def get_all_recipes_by_category(category: str, session: Session = Depends(generate_session)):
|
||||
""" Returns a list of recipes associated with the provided category. """
|
||||
return db.categories.get(session, category)
|
||||
|
||||
|
||||
@router.delete("/{category}")
|
||||
async def delete_recipe_category(
|
||||
category: str, session: Session = Depends(generate_session)
|
||||
):
|
||||
async def delete_recipe_category(category: str, session: Session = Depends(generate_session)):
|
||||
"""Removes a recipe category from the database. Deleting a
|
||||
category does not impact a recipe. The category will be removed
|
||||
from any recipes that contain it"""
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException
|
||||
from fastapi.logger import logger
|
||||
from fastapi.responses import FileResponse
|
||||
from schema.recipe import Recipe, RecipeURLIn
|
||||
from schema.snackbar import SnackResponse
|
||||
from services.image_services import read_image, write_image
|
||||
from services.scraper.scraper import create_from_url
|
||||
from mealie.schema.recipe import Recipe, RecipeURLIn
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.services.image_services import read_image, write_image
|
||||
from mealie.services.scraper.scraper import create_from_url
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(
|
||||
|
@ -41,9 +41,7 @@ def get_recipe(recipe_slug: str, session: Session = Depends(generate_session)):
|
|||
|
||||
|
||||
@router.put("/{recipe_slug}")
|
||||
def update_recipe(
|
||||
recipe_slug: str, data: Recipe, session: Session = Depends(generate_session)
|
||||
):
|
||||
def update_recipe(recipe_slug: str, data: Recipe, session: Session = Depends(generate_session)):
|
||||
""" Updates a recipe by existing slug and data. """
|
||||
|
||||
recipe: Recipe = db.recipes.update(session, recipe_slug, data.dict())
|
||||
|
@ -58,9 +56,7 @@ def delete_recipe(recipe_slug: str, session: Session = Depends(generate_session)
|
|||
try:
|
||||
db.recipes.delete(session, recipe_slug)
|
||||
except:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=SnackResponse.error("Unable to Delete Recipe")
|
||||
)
|
||||
raise HTTPException(status_code=404, detail=SnackResponse.error("Unable to Delete Recipe"))
|
||||
|
||||
return SnackResponse.error(f"Recipe {recipe_slug} Deleted")
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
from schema.snackbar import SnackResponse
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
|
||||
from schema.snackbar import SnackResponse
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
|
||||
router = APIRouter(tags=["Recipes"])
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from schema.settings import SiteSettings
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import GroupInDB, UserInDB
|
||||
from mealie.schema.settings import SiteSettings
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import GroupInDB, UserInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.post_webhooks import post_webhooks
|
||||
from mealie.utils.post_webhooks import post_webhooks
|
||||
|
||||
from routes.deps import manager
|
||||
from mealie.routes.deps import manager
|
||||
|
||||
router = APIRouter(prefix="/api/site-settings", tags=["Settings"])
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from db.db_setup import generate_session
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from schema.theme import SiteTheme
|
||||
from mealie.schema.theme import SiteTheme
|
||||
from sqlalchemy.orm.session import Session
|
||||
from schema.snackbar import SnackResponse
|
||||
from db.database import db
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.db.database import db
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["Themes"])
|
||||
|
||||
|
@ -30,9 +30,7 @@ def get_single_theme(theme_name: str, session: Session = Depends(generate_sessio
|
|||
|
||||
|
||||
@router.put("/themes/{theme_name}")
|
||||
def update_theme(
|
||||
theme_name: str, data: SiteTheme, session: Session = Depends(generate_session)
|
||||
):
|
||||
def update_theme(theme_name: str, data: SiteTheme, session: Session = Depends(generate_session)):
|
||||
""" Update a theme database entry """
|
||||
db.themes.update(session, theme_name, data.dict())
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from core.security import verify_password
|
||||
from db.db_setup import generate_session
|
||||
from mealie.core.security import verify_password
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from fastapi_login.exceptions import InvalidCredentialsException
|
||||
from routes.deps import manager, query_user
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import UserInDB
|
||||
from mealie.routes.deps import manager, query_user
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import UserInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/auth", tags=["Authentication"])
|
||||
|
@ -27,9 +27,7 @@ def get_token(
|
|||
elif not verify_password(password, user.password):
|
||||
raise InvalidCredentialsException
|
||||
|
||||
access_token = manager.create_access_token(
|
||||
data=dict(sub=email), expires=timedelta(hours=2)
|
||||
)
|
||||
access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(hours=2))
|
||||
return SnackResponse.success(
|
||||
"User Successfully Logged In",
|
||||
{"access_token": access_token, "token_type": "bearer"},
|
||||
|
@ -51,9 +49,7 @@ def get_long_token(
|
|||
elif not verify_password(password, user.password):
|
||||
raise InvalidCredentialsException
|
||||
|
||||
access_token = manager.create_access_token(
|
||||
data=dict(sub=email), expires=timedelta(days=1)
|
||||
)
|
||||
access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(days=1))
|
||||
return SnackResponse.success(
|
||||
"User Successfully Logged In",
|
||||
{"access_token": access_token, "token_type": "bearer"},
|
||||
|
@ -63,7 +59,5 @@ def get_long_token(
|
|||
@router.get("/refresh")
|
||||
async def refresh_token(current_user: UserInDB = Depends(manager)):
|
||||
""" Use a valid token to get another token"""
|
||||
access_token = manager.create_access_token(
|
||||
data=dict(sub=current_user.email), expires=timedelta(hours=1)
|
||||
)
|
||||
access_token = manager.create_access_token(data=dict(sub=current_user.email), expires=timedelta(hours=1))
|
||||
return {"access_token": access_token, "token_type": "bearer"}
|
||||
|
|
|
@ -2,15 +2,15 @@ import shutil
|
|||
from datetime import timedelta
|
||||
from os import access
|
||||
|
||||
from core.config import USER_DIR
|
||||
from core.security import get_password_hash, verify_password
|
||||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.core.config import USER_DIR
|
||||
from mealie.core.security import get_password_hash, verify_password
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, File, UploadFile
|
||||
from fastapi.responses import FileResponse
|
||||
from routes.deps import manager
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import ChangePassword, UserBase, UserIn, UserInDB, UserOut
|
||||
from mealie.routes.deps import manager
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import ChangePassword, UserBase, UserIn, UserInDB, UserOut
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/users", tags=["Users"])
|
||||
|
@ -71,9 +71,7 @@ async def update_user(
|
|||
updated_user: UserInDB = db.users.update(session, id, new_data.dict())
|
||||
email = updated_user.email
|
||||
if current_user.id == id:
|
||||
access_token = manager.create_access_token(
|
||||
data=dict(sub=email), expires=timedelta(hours=2)
|
||||
)
|
||||
access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(hours=2))
|
||||
access_token = {"access_token": access_token, "token_type": "bearer"}
|
||||
|
||||
return SnackResponse.success("User Updated", access_token)
|
||||
|
@ -126,9 +124,7 @@ async def update_password(
|
|||
):
|
||||
""" Resets the User Password"""
|
||||
|
||||
match_passwords = verify_password(
|
||||
password_change.current_password, current_user.password
|
||||
)
|
||||
match_passwords = verify_password(password_change.current_password, current_user.password)
|
||||
match_id = current_user.id == id
|
||||
|
||||
if match_passwords and match_id:
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import uuid
|
||||
|
||||
from core.security import get_password_hash
|
||||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from mealie.core.security import get_password_hash
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from routes.deps import manager
|
||||
from schema.sign_up import SignUpIn, SignUpOut, SignUpToken
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import UserIn, UserInDB
|
||||
from mealie.routes.deps import manager
|
||||
from mealie.schema.sign_up import SignUpIn, SignUpOut, SignUpToken
|
||||
from mealie.schema.snackbar import SnackResponse
|
||||
from mealie.schema.user import UserIn, UserInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(prefix="/api/users/sign-ups", tags=["User Signup"])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from fastapi import APIRouter
|
||||
from routes.users import auth, crud, sign_up
|
||||
from mealie.routes.users import auth, crud, sign_up
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
0
mealie/schema/__init__.py
Normal file
|
@ -8,6 +8,8 @@ class BackupOptions(BaseModel):
|
|||
recipes: bool = True
|
||||
settings: bool = True
|
||||
themes: bool = True
|
||||
groups: bool = True
|
||||
users: bool = True
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
|
@ -15,6 +17,8 @@ class BackupOptions(BaseModel):
|
|||
"recipes": True,
|
||||
"settings": True,
|
||||
"themes": True,
|
||||
"groups": True,
|
||||
"users": True,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from typing import List, Optional
|
|||
|
||||
from fastapi_camelcase import CamelModel
|
||||
|
||||
from schema.recipe import Recipe
|
||||
from mealie.schema.recipe import Recipe
|
||||
|
||||
|
||||
class CategoryBase(CamelModel):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date
|
||||
from typing import List, Optional
|
||||
|
||||
from db.models.mealplan import MealPlanModel
|
||||
from mealie.db.models.mealplan import MealPlanModel
|
||||
from pydantic import BaseModel, validator
|
||||
from pydantic.utils import GetterDict
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import datetime
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from db.models.recipe.recipe import RecipeModel
|
||||
from mealie.db.models.recipe.recipe import RecipeModel
|
||||
from pydantic import BaseModel, validator
|
||||
from pydantic.utils import GetterDict
|
||||
from slugify import slugify
|
||||
|
|
|
@ -9,12 +9,14 @@ class RecipeImport(BaseModel):
|
|||
status: bool
|
||||
exception: Optional[str]
|
||||
|
||||
|
||||
class ThemeImport(BaseModel):
|
||||
name: str
|
||||
status: bool
|
||||
exception: Optional[str]
|
||||
|
||||
|
||||
class SettingsImport(BaseModel):
|
||||
name: str
|
||||
status: bool
|
||||
exception: Optional[str]
|
||||
exception: Optional[str]
|
||||
|
|
|
@ -2,7 +2,7 @@ from typing import Optional
|
|||
|
||||
from fastapi_camelcase import CamelModel
|
||||
|
||||
from schema.category import CategoryBase
|
||||
from mealie.schema.category import CategoryBase
|
||||
|
||||
|
||||
class SiteSettings(CamelModel):
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from typing import Any, Optional
|
||||
|
||||
from core.config import DEFAULT_GROUP
|
||||
from db.models.group import Group
|
||||
from db.models.users import User
|
||||
from mealie.core.config import DEFAULT_GROUP
|
||||
from mealie.db.models.group import Group
|
||||
from mealie.db.models.users import User
|
||||
from fastapi_camelcase import CamelModel
|
||||
from pydantic.utils import GetterDict
|
||||
|
||||
from schema.category import CategoryBase
|
||||
from schema.meal import MealPlanInDB
|
||||
from mealie.schema.category import CategoryBase
|
||||
from mealie.schema.meal import MealPlanInDB
|
||||
|
||||
|
||||
class ChangePassword(CamelModel):
|
||||
|
|
0
mealie/services/__init__.py
Normal file
0
mealie/services/backups/__init__.py
Normal file
|
@ -4,13 +4,12 @@ from datetime import datetime
|
|||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
from core.config import BACKUP_DIR, IMG_DIR, TEMP_DIR, TEMPLATE_DIR
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.core.config import BACKUP_DIR, IMG_DIR, TEMP_DIR, TEMPLATE_DIR
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from fastapi.logger import logger
|
||||
from jinja2 import Template
|
||||
from pydantic.main import BaseModel
|
||||
from schema.recipe import Recipe
|
||||
|
||||
|
||||
class ExportDatabase:
|
||||
|
@ -75,14 +74,10 @@ class ExportDatabase:
|
|||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if export_list:
|
||||
ExportDatabase._write_json_file(
|
||||
items, out_dir.joinpath(f"{folder_name}.json")
|
||||
)
|
||||
ExportDatabase._write_json_file(items, out_dir.joinpath(f"{folder_name}.json"))
|
||||
else:
|
||||
for item in items:
|
||||
ExportDatabase._write_json_file(
|
||||
item, out_dir.joinpath(f"{item.get('name')}.json")
|
||||
)
|
||||
ExportDatabase._write_json_file(item, out_dir.joinpath(f"{item.get('name')}.json"))
|
||||
|
||||
@staticmethod
|
||||
def _write_json_file(data: Union[dict, list], out_file: Path):
|
||||
|
|
|
@ -4,13 +4,13 @@ import zipfile
|
|||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from core.config import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.core.config import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from fastapi.logger import logger
|
||||
from schema.recipe import Recipe
|
||||
from schema.restore import RecipeImport, SettingsImport, ThemeImport
|
||||
from schema.theme import SiteTheme
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.schema.restore import RecipeImport, SettingsImport, ThemeImport
|
||||
from mealie.schema.theme import SiteTheme
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
||||
|
@ -93,9 +93,7 @@ class ImportDatabase:
|
|||
|
||||
recipe_obj = Recipe(**recipe_dict)
|
||||
db.recipes.create(session, recipe_obj.dict())
|
||||
import_status = RecipeImport(
|
||||
name=recipe_obj.name, slug=recipe_obj.slug, status=True
|
||||
)
|
||||
import_status = RecipeImport(name=recipe_obj.name, slug=recipe_obj.slug, status=True)
|
||||
imports.append(import_status)
|
||||
successful_imports.append(recipe.stem)
|
||||
logger.info(f"Imported: {recipe.stem}")
|
||||
|
@ -125,17 +123,13 @@ class ImportDatabase:
|
|||
# Migration from list to Object Type Data
|
||||
try:
|
||||
if "" in recipe_dict["tags"]:
|
||||
recipe_dict["tags"] = [
|
||||
tag for tag in recipe_dict["tags"] if not tag == ""
|
||||
]
|
||||
recipe_dict["tags"] = [tag for tag in recipe_dict["tags"] if not tag == ""]
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if "" in recipe_dict["categories"]:
|
||||
recipe_dict["categories"] = [
|
||||
cat for cat in recipe_dict["categories"] if not cat == ""
|
||||
]
|
||||
recipe_dict["categories"] = [cat for cat in recipe_dict["categories"] if not cat == ""]
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -165,9 +159,7 @@ class ImportDatabase:
|
|||
theme_imports.append(ThemeImport(name=new_theme.name, status=True))
|
||||
except Exception as inst:
|
||||
logger.info(f"Unable Import Theme {new_theme.name}")
|
||||
theme_imports.append(
|
||||
ThemeImport(name=new_theme.name, status=False, exception=str(inst))
|
||||
)
|
||||
theme_imports.append(ThemeImport(name=new_theme.name, status=False, exception=str(inst)))
|
||||
|
||||
return theme_imports
|
||||
|
||||
|
@ -185,9 +177,7 @@ class ImportDatabase:
|
|||
import_status = SettingsImport(name=name, status=True)
|
||||
|
||||
except Exception as inst:
|
||||
import_status = SettingsImport(
|
||||
name=name, status=False, exception=str(inst)
|
||||
)
|
||||
import_status = SettingsImport(name=name, status=False, exception=str(inst))
|
||||
|
||||
settings_imports.append(import_status)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import shutil
|
|||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from core.config import IMG_DIR
|
||||
from mealie.core.config import IMG_DIR
|
||||
from fastapi.logger import logger
|
||||
|
||||
|
||||
|
|
|
@ -2,12 +2,18 @@ from datetime import date, timedelta, timezone
|
|||
from typing import Union
|
||||
|
||||
import pytz
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from pydantic.tools import T
|
||||
from schema.meal import MealIn, MealOut, MealPlanIn, MealPlanInDB, MealPlanProcessed
|
||||
from schema.recipe import Recipe
|
||||
from schema.user import GroupInDB
|
||||
from mealie.schema.meal import (
|
||||
MealIn,
|
||||
MealOut,
|
||||
MealPlanIn,
|
||||
MealPlanInDB,
|
||||
MealPlanProcessed,
|
||||
)
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.schema.user import GroupInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
||||
|
|
0
mealie/services/migrations/__init__.py
Normal file
|
@ -2,11 +2,11 @@ import shutil
|
|||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from core.config import IMG_DIR, TEMP_DIR
|
||||
from db.database import db
|
||||
from schema.recipe import Recipe
|
||||
from mealie.core.config import IMG_DIR, TEMP_DIR
|
||||
from mealie.db.database import db
|
||||
from mealie.schema.recipe import Recipe
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.unzip import unpack_zip
|
||||
from mealie.utils.unzip import unpack_zip
|
||||
|
||||
try:
|
||||
from yaml import CLoader as Loader
|
||||
|
|
|
@ -4,11 +4,11 @@ import shutil
|
|||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from core.config import IMG_DIR, MIGRATION_DIR, TEMP_DIR
|
||||
from schema.recipe import Recipe
|
||||
from services.scraper.cleaner import Cleaner
|
||||
from core.config import IMG_DIR, TEMP_DIR
|
||||
from db.database import db
|
||||
from mealie.core.config import IMG_DIR, MIGRATION_DIR, TEMP_DIR
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.services.scraper.cleaner import Cleaner
|
||||
from mealie.core.config import IMG_DIR, TEMP_DIR
|
||||
from mealie.db.database import db
|
||||
|
||||
|
||||
def process_selection(selection: Path) -> Path:
|
||||
|
@ -79,7 +79,7 @@ def migrate(session, selection: str):
|
|||
try:
|
||||
recipe = import_recipes(dir)
|
||||
db.recipes.create(session, recipe.dict())
|
||||
|
||||
|
||||
successful_imports.append(recipe.name)
|
||||
except:
|
||||
logging.error(f"Failed Nextcloud Import: {dir.name}")
|
||||
|
|
0
mealie/services/scheduler/__init__.py
Normal file
|
@ -1,3 +1,3 @@
|
|||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
|
||||
scheduler = BackgroundScheduler()
|
||||
scheduler = BackgroundScheduler()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from fastapi.logger import logger
|
||||
from schema.user import GroupInDB
|
||||
from services.backups.exports import auto_backup_job
|
||||
from services.scheduler.global_scheduler import scheduler
|
||||
from services.scheduler.scheduler_utils import Cron, cron_parser
|
||||
from utils.post_webhooks import post_webhooks
|
||||
from mealie.schema.user import GroupInDB
|
||||
from mealie.services.backups.exports import auto_backup_job
|
||||
from mealie.services.scheduler.global_scheduler import scheduler
|
||||
from mealie.services.scheduler.scheduler_utils import Cron, cron_parser
|
||||
from mealie.utils.post_webhooks import post_webhooks
|
||||
|
||||
|
||||
# TODO Fix Scheduler
|
||||
|
@ -83,9 +83,7 @@ def init_webhook_schedule(scheduler, job_store: dict):
|
|||
logger.info("----INIT SCHEDULE OBJECT-----")
|
||||
|
||||
JOB_STORE = {
|
||||
"backup_job": ScheduledFunction(
|
||||
scheduler, auto_backup_job, Cron(hours=00, minutes=00), "backups"
|
||||
),
|
||||
"backup_job": ScheduledFunction(scheduler, auto_backup_job, Cron(hours=00, minutes=00), "backups"),
|
||||
}
|
||||
|
||||
JOB_STORE = init_webhook_schedule(scheduler=scheduler, job_store=JOB_STORE)
|
||||
|
|
0
mealie/services/scraper/__init__.py
Normal file
|
@ -31,24 +31,15 @@ class Cleaner:
|
|||
recipe_data["prepTime"] = Cleaner.time(recipe_data.get("prepTime", None))
|
||||
recipe_data["performTime"] = Cleaner.time(recipe_data.get("performTime", None))
|
||||
recipe_data["totalTime"] = Cleaner.time(recipe_data.get("totalTime", None))
|
||||
recipe_data["recipeCategory"] = Cleaner.category(
|
||||
recipe_data.get("recipeCategory", [])
|
||||
)
|
||||
recipe_data["recipeCategory"] = Cleaner.category(recipe_data.get("recipeCategory", []))
|
||||
|
||||
recipe_data["recipeYield"] = Cleaner.yield_amount(
|
||||
recipe_data.get("recipeYield")
|
||||
)
|
||||
recipe_data["recipeIngredient"] = Cleaner.ingredient(
|
||||
recipe_data.get("recipeIngredient")
|
||||
)
|
||||
recipe_data["recipeInstructions"] = Cleaner.instructions(
|
||||
recipe_data["recipeInstructions"]
|
||||
)
|
||||
recipe_data["recipeYield"] = Cleaner.yield_amount(recipe_data.get("recipeYield"))
|
||||
recipe_data["recipeIngredient"] = Cleaner.ingredient(recipe_data.get("recipeIngredient"))
|
||||
recipe_data["recipeInstructions"] = Cleaner.instructions(recipe_data["recipeInstructions"])
|
||||
recipe_data["image"] = Cleaner.image(recipe_data.get("image"))
|
||||
recipe_data["slug"] = slugify(recipe_data.get("name"))
|
||||
recipe_data["orgURL"] = url
|
||||
|
||||
|
||||
return recipe_data
|
||||
|
||||
@staticmethod
|
||||
|
@ -84,11 +75,7 @@ class Cleaner:
|
|||
|
||||
# One long string split by (possibly multiple) new lines
|
||||
if isinstance(instructions, str):
|
||||
return [
|
||||
{"text": Cleaner._instruction(line)}
|
||||
for line in instructions.splitlines()
|
||||
if line
|
||||
]
|
||||
return [{"text": Cleaner._instruction(line)} for line in instructions.splitlines() if line]
|
||||
|
||||
# Plain strings in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == str:
|
||||
|
@ -97,13 +84,8 @@ class Cleaner:
|
|||
# Dictionaries (let's assume it's a HowToStep) in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == dict:
|
||||
# Try List of Dictionary without "@type" or "type"
|
||||
if not instructions[0].get("@type", False) and not instructions[0].get(
|
||||
"type", False
|
||||
):
|
||||
return [
|
||||
{"text": Cleaner._instruction(step["text"])}
|
||||
for step in instructions
|
||||
]
|
||||
if not instructions[0].get("@type", False) and not instructions[0].get("type", False):
|
||||
return [{"text": Cleaner._instruction(step["text"])} for step in instructions]
|
||||
|
||||
try:
|
||||
# If HowToStep is under HowToSection
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from typing import Tuple
|
||||
|
||||
import extruct
|
||||
from core.config import DEBUG_DIR
|
||||
from mealie.core.config import DEBUG_DIR
|
||||
from slugify import slugify
|
||||
from w3lib.html import get_base_url
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ from typing import List
|
|||
|
||||
import requests
|
||||
import scrape_schema_recipe
|
||||
from core.config import DEBUG_DIR
|
||||
from mealie.core.config import DEBUG_DIR
|
||||
from fastapi.logger import logger
|
||||
from services.image_services import scrape_image
|
||||
from schema.recipe import Recipe
|
||||
from services.scraper import open_graph
|
||||
from services.scraper.cleaner import Cleaner
|
||||
from mealie.services.image_services import scrape_image
|
||||
from mealie.schema.recipe import Recipe
|
||||
from mealie.services.scraper import open_graph
|
||||
from mealie.services.scraper.cleaner import Cleaner
|
||||
|
||||
LAST_JSON = DEBUG_DIR.joinpath("last_recipe.json")
|
||||
|
||||
|
@ -36,15 +36,11 @@ def create_from_url(url: str) -> Recipe:
|
|||
|
||||
def extract_recipe_from_html(html: str, url: str) -> dict:
|
||||
try:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(
|
||||
html, python_objects=True
|
||||
)
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(html, python_objects=True)
|
||||
dump_last_json(scraped_recipes)
|
||||
|
||||
if not scraped_recipes:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.scrape_url(
|
||||
url, python_objects=True
|
||||
)
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.scrape_url(url, python_objects=True)
|
||||
except Exception as e:
|
||||
# trying without python_objects
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(html)
|
||||
|
|
0
mealie/utils/__init__.py
Normal file
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
|
||||
from core.config import DATA_DIR
|
||||
from mealie.core.config import DATA_DIR
|
||||
|
||||
"""Script to export the ReDoc documentation page into a standalone HTML file."""
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import requests
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from schema.user import GroupInDB
|
||||
from services.meal_services import get_todays_meal
|
||||
from mealie.db.database import db
|
||||
from mealie.db.db_setup import create_session
|
||||
from mealie.schema.user import GroupInDB
|
||||
from mealie.services.meal_services import get_todays_meal
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ def post_webhooks(group: int, session: Session = None):
|
|||
group_settings: GroupInDB = db.groups.get(session, group)
|
||||
|
||||
if not group_settings.webhook_enable:
|
||||
return
|
||||
return
|
||||
|
||||
todays_recipe = get_todays_meal(session, group)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import tempfile
|
|||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from core.config import TEMP_DIR
|
||||
from mealie.core.config import TEMP_DIR
|
||||
|
||||
|
||||
def unpack_zip(selection: Path) -> tempfile.TemporaryDirectory:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[tool.poetry]
|
||||
name = "mealie"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
description = "A Recipe Manager"
|
||||
authors = ["Hayden <hay-kot@pm.me>"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
start = "app:app"
|
||||
start = "mealie.app:main"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
|
@ -39,4 +39,16 @@ mkdocs-material = "^7.0.2"
|
|||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
addopts = "-ra -q --cov=quick_zip"
|
||||
python_files = 'test_*'
|
||||
python_classes = '*Tests'
|
||||
python_functions = 'test_*'
|
||||
testpaths = [
|
||||
"tests",
|
||||
]
|
||||
|
|
0
tests/__init__.py
Normal file
|
@ -1,10 +1,10 @@
|
|||
import json
|
||||
|
||||
import requests
|
||||
from app import app
|
||||
from core.config import SQLITE_DIR
|
||||
from db.db_setup import generate_session, sql_global_init
|
||||
from db.init_db import init_db
|
||||
from mealie.app import app
|
||||
from mealie.core.config import SQLITE_DIR
|
||||
from mealie.db.db_setup import generate_session, sql_global_init
|
||||
from mealie.db.init_db import init_db
|
||||
from fastapi.testclient import TestClient
|
||||
from pytest import fixture
|
||||
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |