Refactor/define repository layer (#883)

* move data access layer

* rename dal -> repo
This commit is contained in:
Hayden 2021-12-18 20:52:36 -09:00 committed by GitHub
parent ea7c4771ee
commit 74e13682cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 371 additions and 369 deletions

View File

@ -10,8 +10,8 @@ from jose import JWTError, jwt
from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs, get_app_settings
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user import LongLiveTokenInDB, PrivateUser, TokenData
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/token")
@ -74,7 +74,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme), session=Depends(
except JWTError:
raise credentials_exception
db = get_database(session)
db = get_repositories(session)
user = db.users.get(token_data.username, "email", any_case=True)
if user is None:
@ -89,7 +89,7 @@ async def get_admin_user(current_user=Depends(get_current_user)) -> PrivateUser:
def validate_long_live_token(session: Session, client_token: str, id: int) -> PrivateUser:
db = get_database(session)
db = get_repositories(session)
tokens: list[LongLiveTokenInDB] = db.api_tokens.get(id, "user_id", limit=9999)

View File

@ -8,8 +8,8 @@ from jose import jwt
from passlib.context import CryptContext
from mealie.core.config import get_app_settings
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.user import PrivateUser
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@ -38,7 +38,7 @@ def create_recipe_slug_token(file_path: str) -> str:
return create_access_token(token_data, expires_delta=timedelta(minutes=30))
def user_from_ldap(db: Database, session, username: str, password: str) -> PrivateUser:
def user_from_ldap(db: AllRepositories, session, username: str, password: str) -> PrivateUser:
"""Given a username and password, tries to authenticate by BINDing to an
LDAP server
@ -81,7 +81,7 @@ def user_from_ldap(db: Database, session, username: str, password: str) -> Priva
def authenticate_user(session, email: str, password: str) -> PrivateUser | bool:
settings = get_app_settings()
db = get_database(session)
db = get_repositories(session)
user: PrivateUser = db.users.get(email, "email", any_case=True)
if not user:

View File

@ -1 +0,0 @@
from .access_model_factory import Database

View File

@ -1,178 +0,0 @@
from functools import cached_property
from sqlalchemy.orm import Session
from mealie.db.models.event import Event, EventNotification
from mealie.db.models.group import Group, GroupMealPlan, ReportEntryModel, ReportModel
from mealie.db.models.group.cookbook import CookBook
from mealie.db.models.group.exports import GroupDataExportsModel
from mealie.db.models.group.invite_tokens import GroupInviteToken
from mealie.db.models.group.preferences import GroupPreferencesModel
from mealie.db.models.group.webhooks import GroupWebhooksModel
from mealie.db.models.recipe.category import Category
from mealie.db.models.recipe.comment import RecipeComment
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.shared import RecipeShareTokenModel
from mealie.db.models.recipe.tag import Tag
from mealie.db.models.recipe.tool import Tool
from mealie.db.models.server.task import ServerTaskModel
from mealie.db.models.sign_up import SignUp
from mealie.db.models.users import LongLiveToken, User
from mealie.db.models.users.password_reset import PasswordResetModel
from mealie.schema.cookbook.cookbook import ReadCookBook
from mealie.schema.events import Event as EventSchema
from mealie.schema.events import EventNotificationIn
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.group.group_preferences import ReadGroupPreferences
from mealie.schema.group.invite_token import ReadInviteToken
from mealie.schema.group.webhook import ReadWebhook
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse, RecipeTool
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
from mealie.schema.recipe.recipe_share_token import RecipeShareToken
from mealie.schema.reports.reports import ReportEntryOut, ReportOut
from mealie.schema.server import ServerTask
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
from mealie.schema.user.user_passwords import PrivatePasswordResetToken
from ._access_model import AccessModel
from .group_access_model import GroupDataAccessModel
from .meal_access_model import MealDataAccessModel
from .recipe_access_model import RecipeDataAccessModel
from .user_access_model import UserDataAccessModel
pk_id = "id"
pk_slug = "slug"
pk_token = "token"
pk_group_id = "group_id"
class CategoryDataAccessModel(AccessModel):
def get_empty(self):
return self.session.query(Category).filter(~Category.recipes.any()).all()
class TagsDataAccessModel(AccessModel):
def get_empty(self):
return self.session.query(Tag).filter(~Tag.recipes.any()).all()
class Database:
def __init__(self, session: Session) -> None:
"""
`DatabaseAccessLayer` class is the data access layer for all database actions within
Mealie. Database uses composition from classes derived from AccessModel. These
can be substantiated from the AccessModel class or through inheritance when
additional methods are required.
"""
self.session = session
# ================================================================
# Recipe Items
@cached_property
def recipes(self) -> RecipeDataAccessModel:
return RecipeDataAccessModel(self.session, pk_slug, RecipeModel, Recipe)
@cached_property
def ingredient_foods(self) -> AccessModel[IngredientFood, IngredientFoodModel]:
return AccessModel(self.session, pk_id, IngredientFoodModel, IngredientFood)
@cached_property
def ingredient_units(self) -> AccessModel[IngredientUnit, IngredientUnitModel]:
return AccessModel(self.session, pk_id, IngredientUnitModel, IngredientUnit)
@cached_property
def tools(self) -> AccessModel[RecipeTool, Tool]:
return AccessModel(self.session, pk_id, Tool, RecipeTool)
@cached_property
def comments(self) -> AccessModel[RecipeCommentOut, RecipeComment]:
return AccessModel(self.session, pk_id, RecipeComment, RecipeCommentOut)
@cached_property
def categories(self) -> CategoryDataAccessModel:
return CategoryDataAccessModel(self.session, pk_slug, Category, RecipeCategoryResponse)
@cached_property
def tags(self) -> TagsDataAccessModel:
return TagsDataAccessModel(self.session, pk_slug, Tag, RecipeTagResponse)
@cached_property
def recipe_share_tokens(self) -> AccessModel[RecipeShareToken, RecipeShareTokenModel]:
return AccessModel(self.session, pk_id, RecipeShareTokenModel, RecipeShareToken)
# ================================================================
# Site Items
@cached_property
def sign_up(self) -> AccessModel[SignUpOut, SignUp]:
return AccessModel(self.session, pk_id, SignUp, SignUpOut)
@cached_property
def event_notifications(self) -> AccessModel[EventNotificationIn, EventNotification]:
return AccessModel(self.session, pk_id, EventNotification, EventNotificationIn)
@cached_property
def events(self) -> AccessModel[EventSchema, Event]:
return AccessModel(self.session, pk_id, Event, EventSchema)
# ================================================================
# User Items
@cached_property
def users(self) -> UserDataAccessModel:
return UserDataAccessModel(self.session, pk_id, User, PrivateUser)
@cached_property
def api_tokens(self) -> AccessModel[LongLiveTokenInDB, LongLiveToken]:
return AccessModel(self.session, pk_id, LongLiveToken, LongLiveTokenInDB)
@cached_property
def tokens_pw_reset(self) -> AccessModel[PrivatePasswordResetToken, PasswordResetModel]:
return AccessModel(self.session, pk_token, PasswordResetModel, PrivatePasswordResetToken)
# ================================================================
# Group Items
@cached_property
def server_tasks(self) -> AccessModel[ServerTask, ServerTaskModel]:
return AccessModel(self.session, pk_id, ServerTaskModel, ServerTask)
@cached_property
def groups(self) -> GroupDataAccessModel:
return GroupDataAccessModel(self.session, pk_id, Group, GroupInDB)
@cached_property
def group_invite_tokens(self) -> AccessModel[ReadInviteToken, GroupInviteToken]:
return AccessModel(self.session, pk_token, GroupInviteToken, ReadInviteToken)
@cached_property
def group_preferences(self) -> AccessModel[ReadGroupPreferences, GroupPreferencesModel]:
return AccessModel(self.session, pk_group_id, GroupPreferencesModel, ReadGroupPreferences)
@cached_property
def group_exports(self) -> AccessModel[GroupDataExport, GroupDataExportsModel]:
return AccessModel(self.session, pk_id, GroupDataExportsModel, GroupDataExport)
@cached_property
def meals(self) -> MealDataAccessModel:
return MealDataAccessModel(self.session, pk_id, GroupMealPlan, ReadPlanEntry)
@cached_property
def cookbooks(self) -> AccessModel[ReadCookBook, CookBook]:
return AccessModel(self.session, pk_id, CookBook, ReadCookBook)
@cached_property
def webhooks(self) -> AccessModel[ReadWebhook, GroupWebhooksModel]:
return AccessModel(self.session, pk_id, GroupWebhooksModel, ReadWebhook)
@cached_property
def group_reports(self) -> AccessModel[ReportOut, ReportModel]:
return AccessModel(self.session, pk_id, ReportModel, ReportOut)
@cached_property
def group_report_entries(self) -> AccessModel[ReportEntryOut, ReportEntryModel]:
return AccessModel(self.session, pk_id, ReportEntryModel, ReportEntryOut)

View File

@ -1,7 +0,0 @@
from sqlalchemy.orm import Session
from .data_access_layer.access_model_factory import Database
def get_database(session: Session):
return Database(session)

View File

@ -1,11 +1,11 @@
from mealie.core import root_logger
from mealie.core.config import get_app_settings
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.db.data_initialization.init_units_foods import default_recipe_unit_init
from mealie.db.data_initialization.init_users import default_user_init
from mealie.db.database import get_database
from mealie.db.db_setup import create_session, engine
from mealie.db.models._model_base import SqlAlchemyBase
from mealie.repos.all_repositories import get_repositories
from mealie.repos.repository_factory import AllRepositories
from mealie.repos.seed.init_units_foods import default_recipe_unit_init
from mealie.repos.seed.init_users import default_user_init
from mealie.schema.user.user import GroupBase
from mealie.services.events import create_general_event
from mealie.services.group_services.group_utils import create_new_group
@ -21,13 +21,13 @@ def create_all_models():
SqlAlchemyBase.metadata.create_all(engine)
def init_db(db: Database) -> None:
def init_db(db: AllRepositories) -> None:
default_group_init(db)
default_user_init(db)
default_recipe_unit_init(db)
def default_group_init(db: Database):
def default_group_init(db: AllRepositories):
logger.info("Generating Default Group")
create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP))
@ -36,7 +36,7 @@ def main():
create_all_models()
session = create_session()
db = get_database(session)
db = get_repositories(session)
try:
init_user = db.users.get_all()

1
mealie/repos/__init__.py Normal file
View File

@ -0,0 +1 @@
from .repository_factory import AllRepositories

View File

@ -0,0 +1,7 @@
from sqlalchemy.orm import Session
from .repository_factory import AllRepositories
def get_repositories(session: Session):
return AllRepositories(session)

View File

@ -0,0 +1,178 @@
from functools import cached_property
from sqlalchemy.orm import Session
from mealie.db.models.event import Event, EventNotification
from mealie.db.models.group import Group, GroupMealPlan, ReportEntryModel, ReportModel
from mealie.db.models.group.cookbook import CookBook
from mealie.db.models.group.exports import GroupDataExportsModel
from mealie.db.models.group.invite_tokens import GroupInviteToken
from mealie.db.models.group.preferences import GroupPreferencesModel
from mealie.db.models.group.webhooks import GroupWebhooksModel
from mealie.db.models.recipe.category import Category
from mealie.db.models.recipe.comment import RecipeComment
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.shared import RecipeShareTokenModel
from mealie.db.models.recipe.tag import Tag
from mealie.db.models.recipe.tool import Tool
from mealie.db.models.server.task import ServerTaskModel
from mealie.db.models.sign_up import SignUp
from mealie.db.models.users import LongLiveToken, User
from mealie.db.models.users.password_reset import PasswordResetModel
from mealie.schema.cookbook.cookbook import ReadCookBook
from mealie.schema.events import Event as EventSchema
from mealie.schema.events import EventNotificationIn
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.group.group_preferences import ReadGroupPreferences
from mealie.schema.group.invite_token import ReadInviteToken
from mealie.schema.group.webhook import ReadWebhook
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse, RecipeTool
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
from mealie.schema.recipe.recipe_share_token import RecipeShareToken
from mealie.schema.reports.reports import ReportEntryOut, ReportOut
from mealie.schema.server import ServerTask
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
from mealie.schema.user.user_passwords import PrivatePasswordResetToken
from .repository_generic import RepositoryGeneric
from .repository_group import RepositoryGroup
from .repository_meals import RepositoryMeals
from .repository_recipes import RepositoryRecipes
from .repository_users import RepositoryUsers
pk_id = "id"
pk_slug = "slug"
pk_token = "token"
pk_group_id = "group_id"
class RepositoryCategories(RepositoryGeneric):
def get_empty(self):
return self.session.query(Category).filter(~Category.recipes.any()).all()
class RepositoryTags(RepositoryGeneric):
def get_empty(self):
return self.session.query(Tag).filter(~Tag.recipes.any()).all()
class AllRepositories:
def __init__(self, session: Session) -> None:
"""
`AllRepositories` class is the data access layer for all database actions within
Mealie. Database uses composition from classes derived from AccessModel. These
can be substantiated from the AccessModel class or through inheritance when
additional methods are required.
"""
self.session = session
# ================================================================
# Recipe Items
@cached_property
def recipes(self) -> RepositoryRecipes:
return RepositoryRecipes(self.session, pk_slug, RecipeModel, Recipe)
@cached_property
def ingredient_foods(self) -> RepositoryGeneric[IngredientFood, IngredientFoodModel]:
return RepositoryGeneric(self.session, pk_id, IngredientFoodModel, IngredientFood)
@cached_property
def ingredient_units(self) -> RepositoryGeneric[IngredientUnit, IngredientUnitModel]:
return RepositoryGeneric(self.session, pk_id, IngredientUnitModel, IngredientUnit)
@cached_property
def tools(self) -> RepositoryGeneric[RecipeTool, Tool]:
return RepositoryGeneric(self.session, pk_id, Tool, RecipeTool)
@cached_property
def comments(self) -> RepositoryGeneric[RecipeCommentOut, RecipeComment]:
return RepositoryGeneric(self.session, pk_id, RecipeComment, RecipeCommentOut)
@cached_property
def categories(self) -> RepositoryCategories:
return RepositoryCategories(self.session, pk_slug, Category, RecipeCategoryResponse)
@cached_property
def tags(self) -> RepositoryTags:
return RepositoryTags(self.session, pk_slug, Tag, RecipeTagResponse)
@cached_property
def recipe_share_tokens(self) -> RepositoryGeneric[RecipeShareToken, RecipeShareTokenModel]:
return RepositoryGeneric(self.session, pk_id, RecipeShareTokenModel, RecipeShareToken)
# ================================================================
# Site Items
@cached_property
def sign_up(self) -> RepositoryGeneric[SignUpOut, SignUp]:
return RepositoryGeneric(self.session, pk_id, SignUp, SignUpOut)
@cached_property
def event_notifications(self) -> RepositoryGeneric[EventNotificationIn, EventNotification]:
return RepositoryGeneric(self.session, pk_id, EventNotification, EventNotificationIn)
@cached_property
def events(self) -> RepositoryGeneric[EventSchema, Event]:
return RepositoryGeneric(self.session, pk_id, Event, EventSchema)
# ================================================================
# User Items
@cached_property
def users(self) -> RepositoryUsers:
return RepositoryUsers(self.session, pk_id, User, PrivateUser)
@cached_property
def api_tokens(self) -> RepositoryGeneric[LongLiveTokenInDB, LongLiveToken]:
return RepositoryGeneric(self.session, pk_id, LongLiveToken, LongLiveTokenInDB)
@cached_property
def tokens_pw_reset(self) -> RepositoryGeneric[PrivatePasswordResetToken, PasswordResetModel]:
return RepositoryGeneric(self.session, pk_token, PasswordResetModel, PrivatePasswordResetToken)
# ================================================================
# Group Items
@cached_property
def server_tasks(self) -> RepositoryGeneric[ServerTask, ServerTaskModel]:
return RepositoryGeneric(self.session, pk_id, ServerTaskModel, ServerTask)
@cached_property
def groups(self) -> RepositoryGroup:
return RepositoryGroup(self.session, pk_id, Group, GroupInDB)
@cached_property
def group_invite_tokens(self) -> RepositoryGeneric[ReadInviteToken, GroupInviteToken]:
return RepositoryGeneric(self.session, pk_token, GroupInviteToken, ReadInviteToken)
@cached_property
def group_preferences(self) -> RepositoryGeneric[ReadGroupPreferences, GroupPreferencesModel]:
return RepositoryGeneric(self.session, pk_group_id, GroupPreferencesModel, ReadGroupPreferences)
@cached_property
def group_exports(self) -> RepositoryGeneric[GroupDataExport, GroupDataExportsModel]:
return RepositoryGeneric(self.session, pk_id, GroupDataExportsModel, GroupDataExport)
@cached_property
def meals(self) -> RepositoryMeals:
return RepositoryMeals(self.session, pk_id, GroupMealPlan, ReadPlanEntry)
@cached_property
def cookbooks(self) -> RepositoryGeneric[ReadCookBook, CookBook]:
return RepositoryGeneric(self.session, pk_id, CookBook, ReadCookBook)
@cached_property
def webhooks(self) -> RepositoryGeneric[ReadWebhook, GroupWebhooksModel]:
return RepositoryGeneric(self.session, pk_id, GroupWebhooksModel, ReadWebhook)
@cached_property
def group_reports(self) -> RepositoryGeneric[ReportOut, ReportModel]:
return RepositoryGeneric(self.session, pk_id, ReportModel, ReportOut)
@cached_property
def group_report_entries(self) -> RepositoryGeneric[ReportEntryOut, ReportEntryModel]:
return RepositoryGeneric(self.session, pk_id, ReportEntryModel, ReportEntryOut)

View File

@ -16,7 +16,7 @@ T = TypeVar("T")
D = TypeVar("D")
class AccessModel(Generic[T, D]):
class RepositoryGeneric(Generic[T, D]):
"""A Generic BaseAccess Model method to perform common operations on the database
Args:
@ -40,12 +40,12 @@ class AccessModel(Generic[T, D]):
def subscribe(self, func: Callable) -> None:
self.observers.append(func)
def by_user(self, user_id: UUID4) -> AccessModel:
def by_user(self, user_id: UUID4) -> RepositoryGeneric:
self.limit_by_user = True
self.user_id = user_id
return self
def by_group(self, group_id: UUID) -> AccessModel:
def by_group(self, group_id: UUID) -> RepositoryGeneric:
self.limit_by_group = True
self.group_id = group_id
return self

View File

@ -4,10 +4,10 @@ from mealie.db.models.group import Group
from mealie.schema.meal_plan.meal import MealPlanOut
from mealie.schema.user.user import GroupInDB
from ._access_model import AccessModel
from .repository_generic import RepositoryGeneric
class GroupDataAccessModel(AccessModel[GroupInDB, Group]):
class RepositoryGroup(RepositoryGeneric[GroupInDB, Group]):
def get_meals(self, session: Session, match_value: str, match_key: str = "name") -> list[MealPlanOut]:
"""A Helper function to get the group from the database and return a sorted list of

View File

@ -4,10 +4,10 @@ from uuid import UUID
from mealie.db.models.group import GroupMealPlan
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from ._access_model import AccessModel
from .repository_generic import RepositoryGeneric
class MealDataAccessModel(AccessModel[ReadPlanEntry, GroupMealPlan]):
class RepositoryMeals(RepositoryGeneric[ReadPlanEntry, GroupMealPlan]):
def get_slice(self, start: date, end: date, group_id: UUID) -> list[ReadPlanEntry]:
start = start.strftime("%Y-%m-%d")
end = end.strftime("%Y-%m-%d")

View File

@ -8,10 +8,10 @@ from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.settings import RecipeSettings
from mealie.schema.recipe import Recipe
from ._access_model import AccessModel
from .repository_generic import RepositoryGeneric
class RecipeDataAccessModel(AccessModel[Recipe, RecipeModel]):
class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
def get_all_public(self, limit: int = None, order_by: str = None, start=0, override_schema=None):
eff_schema = override_schema or self.schema

View File

@ -4,10 +4,10 @@ import shutil
from mealie.assets import users as users_assets
from mealie.schema.user.user import PrivateUser, User
from ._access_model import AccessModel
from .repository_generic import RepositoryGeneric
class UserDataAccessModel(AccessModel[PrivateUser, User]):
class RepositoryUsers(RepositoryGeneric[PrivateUser, User]):
def update_password(self, id, password: str):
entry = self._query_one(match_value=id)
entry.update_password(password)

View File

@ -2,7 +2,7 @@ import json
from pathlib import Path
from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.recipe import CreateIngredientFood, CreateIngredientUnit
CWD = Path(__file__).parent
@ -21,7 +21,7 @@ def get_default_units() -> dict[str, str]:
return units
def default_recipe_unit_init(db: Database) -> None:
def default_recipe_unit_init(db: AllRepositories) -> None:
for unit in get_default_units().values():
try:
db.ingredient_units.create(

View File

@ -1,7 +1,7 @@
from mealie.core import root_logger
from mealie.core.config import get_app_settings
from mealie.core.security import hash_password
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.repos.repository_factory import AllRepositories
logger = root_logger.get_logger("init_users")
settings = get_app_settings()
@ -44,7 +44,7 @@ def dev_users() -> list[dict]:
]
def default_user_init(db: Database):
def default_user_init(db: AllRepositories):
default_user = {
"full_name": "Change Me",
"username": "admin",

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter
from mealie.schema.events import EventsOut
@ -15,7 +15,7 @@ logger = get_logger()
@router.get("", response_model=EventsOut)
async def get_events(session: Session = Depends(generate_session)):
"""Get event from the Database"""
db = get_database(session)
db = get_repositories(session)
return EventsOut(total=db.events.count_all(), events=db.events.get_all(order_by="time_stamp"))
@ -23,7 +23,7 @@ async def get_events(session: Session = Depends(generate_session)):
@router.delete("")
async def delete_events(session: Session = Depends(generate_session)):
"""Get event from the Database"""
db = get_database(session)
db = get_repositories(session)
db.events.delete_all()
return {"message": "All events deleted"}
@ -31,5 +31,5 @@ async def delete_events(session: Session = Depends(generate_session)):
@router.delete("/{id}")
async def delete_event(id: int, session: Session = Depends(generate_session)):
"""Delete event from the Database"""
db = get_database(session)
db = get_repositories(session)
return db.events.delete(id)

View File

@ -4,8 +4,8 @@ from fastapi import Depends, status
from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter
from mealie.schema.events import EventNotificationIn, EventNotificationOut, TestEvent
from mealie.services.events import test_notification
@ -21,7 +21,7 @@ async def create_event_notification(
session: Session = Depends(generate_session),
):
"""Create event_notification in the Database"""
db = get_database(session)
db = get_repositories(session)
return db.event_notifications.create(event_data)
@ -32,7 +32,7 @@ async def test_notification_route(
session: Session = Depends(generate_session),
):
"""Create event_notification in the Database"""
db = get_database(session)
db = get_repositories(session)
if test_data.id:
event_obj: EventNotificationIn = db.event_notifications.get(test_data.id)
@ -48,7 +48,7 @@ async def test_notification_route(
@router.get("/notifications", response_model=list[EventNotificationOut])
async def get_all_event_notification(session: Session = Depends(generate_session)):
"""Get all event_notification from the Database"""
db = get_database(session)
db = get_repositories(session)
return db.event_notifications.get_all(override_schema=EventNotificationOut)
@ -63,5 +63,5 @@ async def update_event_notification(id: int, session: Session = Depends(generate
async def delete_event_notification(id: int, session: Session = Depends(generate_session)):
"""Delete event_notification from the Database"""
# Delete Item
db = get_database(session)
db = get_repositories(session)
return db.event_notifications.delete(id)

View File

@ -4,8 +4,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_settings
from mealie.core.release_checker import get_latest_version
from mealie.core.settings.static import APP_VERSION
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.admin.about import AdminAboutInfo, AppStatistics, CheckAppConfig
router = APIRouter(prefix="/about")
@ -31,7 +31,7 @@ async def get_app_info():
@router.get("/statistics", response_model=AppStatistics)
async def get_app_statistics(session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
return AppStatistics(
total_recipes=db.recipes.count_all(),
uncategorized_recipes=db.recipes.count_uncategorized(),

View File

@ -3,8 +3,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import is_logged_in
from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
@ -17,14 +17,14 @@ logger = get_logger()
@public_router.get("")
async def get_all_recipe_categories(session: Session = Depends(generate_session)):
"""Returns a list of available categories in the database"""
db = get_database(session)
db = get_repositories(session)
return db.categories.get_all_limit_columns(fields=["slug", "name"])
@public_router.get("/empty")
def get_empty_categories(session: Session = Depends(generate_session)):
"""Returns a list of categories that do not contain any recipes"""
db = get_database(session)
db = get_repositories(session)
return db.categories.get_empty()
@ -33,7 +33,7 @@ def get_all_recipes_by_category(
category: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
):
"""Returns a list of recipes associated with the provided category."""
db = get_database(session)
db = get_repositories(session)
category_obj = db.categories.get(category)
category_obj = RecipeCategoryResponse.from_orm(category_obj)
@ -47,7 +47,7 @@ def get_all_recipes_by_category(
@user_router.post("")
async def create_recipe_category(category: CategoryIn, session: Session = Depends(generate_session)):
"""Creates a Category in the database"""
db = get_database(session)
db = get_repositories(session)
try:
return db.categories.create(category.dict())
@ -58,7 +58,7 @@ async def create_recipe_category(category: CategoryIn, session: Session = Depend
@admin_router.put("/{category}", response_model=RecipeCategoryResponse)
async def update_recipe_category(category: str, new_category: CategoryIn, session: Session = Depends(generate_session)):
"""Updates an existing Tag in the database"""
db = get_database(session)
db = get_repositories(session)
try:
return db.categories.update(category, new_category.dict())
@ -74,7 +74,7 @@ async def delete_recipe_category(category: str, session: Session = Depends(gener
category does not impact a recipe. The category will be removed
from any recipes that contain it
"""
db = get_database(session)
db = get_repositories(session)
try:
db.categories.delete(category)

View File

@ -1,8 +1,8 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.recipe import RecipeSummary
router = APIRouter()
@ -10,11 +10,11 @@ router = APIRouter()
@router.get("/summary/untagged", response_model=list[RecipeSummary])
async def get_untagged_recipes(count: bool = False, session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
return db.recipes.count_untagged(count=count, override_schema=RecipeSummary)
@router.get("/summary/uncategorized", response_model=list[RecipeSummary])
async def get_uncategorized_recipes(count: bool = False, session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
return db.recipes.count_uncategorized(count=count, override_schema=RecipeSummary)

View File

@ -1,8 +1,8 @@
from fastapi import Depends
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe.recipe_comments import RecipeCommentOut
@ -15,6 +15,6 @@ async def get_recipe_comments(
session: Session = Depends(generate_session),
):
"""Get all comments for a recipe"""
db = get_database(session)
db = get_repositories(session)
recipe = db.recipes.get_one(slug)
return db.comments.multi_query({"recipe_id": recipe.id})

View File

@ -5,8 +5,8 @@ from fastapi.datastructures import UploadFile
from slugify import slugify
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import CreateRecipeByUrl, Recipe, RecipeAsset
from mealie.services.image.image import scrape_image, write_image
@ -29,7 +29,7 @@ def update_recipe_image(
session: Session = Depends(generate_session),
):
"""Removes an existing image and replaces it with the incoming file."""
db = get_database(session)
db = get_repositories(session)
write_image(slug, image, extension)
new_version = db.recipes.update_image(slug, extension)
@ -56,7 +56,7 @@ def upload_recipe_asset(
if not dest.is_file():
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
db = get_database(session)
db = get_repositories(session)
recipe: Recipe = db.recipes.get(slug)
recipe.assets.append(asset_in)

View File

@ -6,7 +6,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import temporary_zip_path
from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import CreateRecipeByUrl, Recipe
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeSummary
@ -53,7 +53,7 @@ def parse_recipe_url_bulk(
"""Takes in a URL and attempts to scrape data and load it into the database"""
def bulk_import_func(task_id: int, session: Session) -> None:
database = get_database(session)
database = get_repositories(session)
task = database.server_tasks.get_one(task_id)
task.append_log("test task has started")

View File

@ -9,8 +9,8 @@ from mealie.core.dependencies import temporary_zip_path
from mealie.core.dependencies.dependencies import temporary_dir, validate_recipe_token
from mealie.core.root_logger import get_logger
from mealie.core.security import create_recipe_slug_token
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import Recipe, RecipeImageTypes
from mealie.services.recipe.recipe_service import RecipeService
@ -68,7 +68,7 @@ async def get_recipe_as_zip(
if slug != slug:
raise HTTPException(status_code=400, detail="Invalid Slug")
db = get_database(session)
db = get_repositories(session)
recipe: Recipe = db.recipes.get(slug)
image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
with ZipFile(temp_path, "w") as myzip:

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends
from pydantic import UUID4
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.recipe import Recipe
router = APIRouter()
@ -11,7 +11,7 @@ router = APIRouter()
@router.get("/shared/{token_id}", response_model=Recipe)
def get_shared_recipe(token_id: UUID4, session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
token_summary = db.recipe_share_tokens.get_one(token_id)

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut
from mealie.schema.user import PrivateUser
@ -18,7 +18,7 @@ async def create_shopping_list(
session: Session = Depends(generate_session),
):
"""Create Shopping List in the Database"""
db = get_database(session)
db = get_repositories(session)
list_in.group = current_user.group
return db.shopping_lists.create(list_in)
@ -27,19 +27,19 @@ async def create_shopping_list(
@router.get("/{id}", response_model=ShoppingListOut)
async def get_shopping_list(id: int, session: Session = Depends(generate_session)):
"""Get Shopping List from the Database"""
db = get_database(session)
db = get_repositories(session)
return db.shopping_lists.get(id)
@router.put("/{id}", response_model=ShoppingListOut)
async def update_shopping_list(id: int, new_data: ShoppingListIn, session: Session = Depends(generate_session)):
"""Update Shopping List in the Database"""
db = get_database(session)
db = get_repositories(session)
return db.shopping_lists.update(id, new_data)
@router.delete("/{id}")
async def delete_shopping_list(id: int, session: Session = Depends(generate_session)):
"""Delete Shopping List from the Database"""
db = get_database(session)
db = get_repositories(session)
return db.shopping_lists.delete(id)

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter
from mealie.schema.user import GroupInDB, PrivateUser
from mealie.utils.post_webhooks import post_webhooks
@ -15,7 +15,7 @@ admin_router = AdminAPIRouter(prefix="/api/site-settings", tags=["Settings"])
@public_router.get("")
def get_main_settings(session: Session = Depends(generate_session)):
"""Returns basic site settings"""
db = get_database(session)
db = get_repositories(session)
return db.settings.get(1)
@ -26,7 +26,7 @@ def test_webhooks(
session: Session = Depends(generate_session),
):
"""Run the function to test your webhooks"""
db = get_database(session)
db = get_repositories(session)
group_entry: GroupInDB = db.groups.get(current_user.group, "name")
try:

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from mealie.core.dependencies import is_logged_in
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.schema.recipe import RecipeTagResponse, TagIn
@ -15,14 +15,14 @@ admin_router = AdminAPIRouter()
@public_router.get("")
async def get_all_recipe_tags(session: Session = Depends(generate_session)):
"""Returns a list of available tags in the database"""
db = get_database(session)
db = get_repositories(session)
return db.tags.get_all_limit_columns(["slug", "name"])
@public_router.get("/empty")
def get_empty_tags(session: Session = Depends(generate_session)):
"""Returns a list of tags that do not contain any recipes"""
db = get_database(session)
db = get_repositories(session)
return db.tags.get_empty()
@ -31,7 +31,7 @@ def get_all_recipes_by_tag(
tag: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
):
"""Returns a list of recipes associated with the provided tag."""
db = get_database(session)
db = get_repositories(session)
tag_obj = db.tags.get(tag)
tag_obj = RecipeTagResponse.from_orm(tag_obj)
@ -44,14 +44,14 @@ def get_all_recipes_by_tag(
@user_router.post("")
async def create_recipe_tag(tag: TagIn, session: Session = Depends(generate_session)):
"""Creates a Tag in the database"""
db = get_database(session)
db = get_repositories(session)
return db.tags.create(tag.dict())
@admin_router.put("/{tag}", response_model=RecipeTagResponse)
async def update_recipe_tag(tag: str, new_tag: TagIn, session: Session = Depends(generate_session)):
"""Updates an existing Tag in the database"""
db = get_database(session)
db = get_repositories(session)
return db.tags.update(tag, new_tag.dict())
@ -62,7 +62,7 @@ async def delete_recipe_tag(tag: str, session: Session = Depends(generate_sessio
from any recipes that contain it"""
try:
db = get_database(session)
db = get_repositories(session)
db.tags.delete(tag)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)

View File

@ -6,8 +6,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.core.security import create_access_token
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, PrivateUser
@ -33,7 +33,7 @@ async def create_api_token(
user_id=current_user.id,
)
db = get_database(session)
db = get_repositories(session)
new_token_in_db = db.api_tokens.create(token_model)
@ -48,7 +48,7 @@ async def delete_api_token(
session: Session = Depends(generate_session),
):
"""Delete api_token from the Database"""
db = get_database(session)
db = get_repositories(session)
token: LongLiveTokenInDB = db.api_tokens.get(token_id)
if not token:

View File

@ -5,8 +5,8 @@ from sqlalchemy.orm.session import Session
from mealie.core import security
from mealie.core.dependencies import get_current_user
from mealie.core.security import hash_password
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser, UserBase, UserIn, UserOut
@ -18,7 +18,7 @@ admin_router = AdminAPIRouter(prefix="")
@admin_router.get("", response_model=list[UserOut])
async def get_all_users(session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
return db.users.get_all()
@ -35,13 +35,13 @@ async def create_user(
create_user_event, "User Created", f"Created by {current_user.full_name}", session=session
)
db = get_database(session)
db = get_repositories(session)
return db.users.create(new_user.dict())
@admin_router.get("/{id}", response_model=UserOut)
async def get_user(id: UUID4, session: Session = Depends(generate_session)):
db = get_database(session)
db = get_repositories(session)
return db.users.get(id)
@ -60,7 +60,7 @@ def delete_user(
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER")
try:
db = get_database(session)
db = get_repositories(session)
db.users.delete(id)
background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session)
except Exception:
@ -92,7 +92,7 @@ async def update_user(
# prevent an admin from demoting themself
raise HTTPException(status.HTTP_403_FORBIDDEN)
db = get_database(session)
db = get_repositories(session)
db.users.update(id, new_data.dict())
if current_user.id == id:

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser, UserFavorites
@ -14,7 +14,7 @@ user_router = UserAPIRouter()
@user_router.get("/{id}/favorites", response_model=UserFavorites)
async def get_favorites(id: str, session: Session = Depends(generate_session)):
"""Get user's favorite recipes"""
db = get_database(session)
db = get_repositories(session)
return db.users.get(id, override_schema=UserFavorites)
@ -27,7 +27,7 @@ def add_favorite(
"""Adds a Recipe to the users favorites"""
current_user.favorite_recipes.append(slug)
db = get_database(session)
db = get_repositories(session)
db.users.update(current_user.id, current_user)
@ -42,7 +42,7 @@ def remove_favorite(
assert_user_change_allowed(id, current_user)
current_user.favorite_recipes = [x for x in current_user.favorite_recipes if x != slug]
db = get_database(session)
db = get_repositories(session)
db.users.update(current_user.id, current_user)
return

View File

@ -9,8 +9,8 @@ from sqlalchemy.orm.session import Session
from mealie import utils
from mealie.core.dependencies import get_current_user
from mealie.core.dependencies.dependencies import temporary_dir
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser
@ -41,7 +41,7 @@ def update_user_image(
shutil.copyfile(image, dest)
db = get_database(session)
db = get_repositories(session)
db.users.patch(id, {"cache_key": utils.new_cache_key()})

View File

@ -3,8 +3,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_settings
from mealie.core.security import hash_password
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import ChangePassword
from mealie.schema.user.user_passwords import ForgotPassword, ResetPassword
@ -20,7 +20,7 @@ settings = get_app_settings()
async def reset_user_password(id: int, session: Session = Depends(generate_session)):
new_password = hash_password(settings.DEFAULT_PASSWORD)
db = get_database(session)
db = get_repositories(session)
db.users.update_password(id, new_password)

View File

@ -7,9 +7,9 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs, get_app_settings
from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import SessionLocal
from mealie.lang import get_locale_provider
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user.user import PrivateUser
logger = get_logger()
@ -62,7 +62,7 @@ class BaseHttpService(Generic[T, D], ABC):
self.background_tasks = background_tasks
# Static Globals Dependency Injection
self.db = get_database(session)
self.db = get_repositories(session)
self.app_dirs = get_app_dirs()
self.settings = get_app_settings()
self.t = get_locale_provider().t

View File

@ -9,13 +9,13 @@ from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer._access_model import AccessModel
from mealie.repos.repository_generic import RepositoryGeneric
from mealie.schema.response import ErrorResponse
C = TypeVar("C", bound=BaseModel)
R = TypeVar("R", bound=BaseModel)
U = TypeVar("U", bound=BaseModel)
DAL = TypeVar("DAL", bound=AccessModel)
DAL = TypeVar("DAL", bound=RepositoryGeneric)
logger = get_logger()
@ -25,16 +25,16 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
@property
@abstractmethod
def dal(self) -> DAL:
def repo(self) -> DAL:
...
def populate_item(self, id: int) -> R:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def _create_one(self, data: C, default_msg="generic-create-error", exception_msgs: dict | None = None) -> R:
try:
self.item = self.dal.create(data)
self.item = self.repo.create(data)
except Exception as ex:
logger.exception(ex)
self.session.rollback()
@ -58,13 +58,13 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
return
target_id = item_id or self.item.id
self.item = self.dal.update(target_id, data)
self.item = self.repo.update(target_id, data)
return self.item
def _patch_one(self, data: U, item_id: int) -> None:
try:
self.item = self.dal.patch(item_id, data.dict(exclude_unset=True, exclude_defaults=True))
self.item = self.repo.patch(item_id, data.dict(exclude_unset=True, exclude_defaults=True))
except IntegrityError:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail={"message": "generic-patch-error"})
@ -73,7 +73,7 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
logger.info(f"Deleting item with id {target_id}")
try:
self.item = self.dal.delete(target_id)
self.item = self.repo.delete(target_id)
except Exception as ex:
logger.exception(ex)
raise HTTPException(

View File

@ -23,15 +23,15 @@ class AdminGroupService(
_schema = GroupInDB
@cached_property
def dal(self):
def repo(self):
return self.db.groups
def populate_item(self, id: UUID4) -> GroupInDB:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[GroupInDB]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: GroupBase) -> GroupInDB:
return create_new_group(self.db, data)
@ -46,7 +46,7 @@ class AdminGroupService(
if data.name not in ["", self.item.name]:
self.item.name = data.name
self.item = self.dal.update(target_id, self.item)
self.item = self.repo.update(target_id, self.item)
return self.item

View File

@ -16,15 +16,15 @@ class AdminUserService(
_schema = UserOut
@cached_property
def dal(self):
def repo(self):
return self.db.users
def populate_item(self, id: int) -> UserOut:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[UserOut]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: UserIn) -> UserOut:
return self._create_one(data)

View File

@ -12,7 +12,7 @@ from mealie.core import root_logger
from mealie.core.config import get_app_dirs
app_dirs = get_app_dirs()
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
logger = root_logger.get_logger()
@ -113,7 +113,7 @@ def backup_all(
):
db_export = ExportDatabase(tag=tag, templates=templates)
db = get_database(session)
db = get_repositories(session)
if export_users:
all_users = db.users.get_all()

View File

@ -8,7 +8,7 @@ from pydantic.main import BaseModel
from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
from mealie.schema.admin import CommentImport, GroupImport, NotificationImport, RecipeImport, UserImport
from mealie.schema.events import EventNotificationIn
from mealie.schema.recipe import Recipe, RecipeCommentOut
@ -38,7 +38,7 @@ class ImportDatabase:
"""
self.user = user
self.session = session
self.db = get_database(session)
self.db = get_repositories(session)
self.archive = app_dirs.BACKUP_DIR.joinpath(zip_archive)
self.force_imports = force_import

View File

@ -1,8 +1,8 @@
import apprise
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.events import Event, EventCategory
@ -37,7 +37,7 @@ def post_notifications(event: Event, notification_urls=list[str], hard_fail=Fals
def save_event(title, text, category, session: Session, attachment=None):
event = Event(title=title, text=text, category=category)
session = session or create_session()
db = get_database(session)
db = get_repositories(session)
db.events.create(event.dict())
notification_objects = db.event_notifications.get(match_value=True, match_key=category, limit=9999)

View File

@ -8,7 +8,7 @@ from uuid import UUID
from pydantic import BaseModel
from mealie.core.root_logger import get_logger
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.schema.reports.reports import ReportEntryCreate
from .._base_service import BaseService
@ -29,7 +29,7 @@ class ExportedItem:
class ABCExporter(BaseService):
write_dir_to_zip: Callable[[Path, str, Optional[list[str]]], None]
def __init__(self, db: Database, group_id: UUID) -> None:
def __init__(self, db: AllRepositories, group_id: UUID) -> None:
self.logger = get_logger()
self.db = db
self.group_id = group_id

View File

@ -4,7 +4,7 @@ import zipfile
from pathlib import Path
from uuid import UUID, uuid4
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.user import GroupInDB
from mealie.utils.fs_stats import pretty_size
@ -21,7 +21,7 @@ class Exporter(BaseService):
self.temp_path = temp_zip
self.exporters = exporters
def run(self, db: Database) -> GroupDataExport:
def run(self, db: AllRepositories) -> GroupDataExport:
# Create Zip File
self.temp_path.touch()

View File

@ -1,14 +1,14 @@
from typing import Iterator
from uuid import UUID
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.schema.recipe import Recipe
from ._abc_exporter import ABCExporter, ExportedItem
class RecipeExporter(ABCExporter):
def __init__(self, db: Database, group_id: UUID, recipes: list[str]) -> None:
def __init__(self, db: AllRepositories, group_id: UUID, recipes: list[str]) -> None:
"""
RecipeExporter is used to export a list of recipes to a zip file. The zip
file is then saved to a temporary directory and then available for a one-time

View File

@ -21,7 +21,7 @@ class CookbookService(
_schema = ReadCookBook
@cached_property
def dal(self):
def repo(self):
return self.db.cookbooks
def populate_item(self, item_id: int) -> RecipeCookBook:
@ -31,13 +31,13 @@ class CookbookService(
pass
if isinstance(item_id, int):
self.item = self.dal.get_one(item_id, override_schema=RecipeCookBook)
self.item = self.repo.get_one(item_id, override_schema=RecipeCookBook)
else:
self.item = self.dal.get_one(item_id, key="slug", override_schema=RecipeCookBook)
self.item = self.repo.get_one(item_id, key="slug", override_schema=RecipeCookBook)
def get_all(self) -> list[ReadCookBook]:
items = self.dal.get(self.group_id, "group_id", limit=999)
items = self.repo.get(self.group_id, "group_id", limit=999)
items.sort(key=lambda x: x.position)
return items
@ -52,7 +52,7 @@ class CookbookService(
updated = []
for cookbook in data:
cb = self.dal.update(cookbook.id, cookbook)
cb = self.repo.update(cookbook.id, cookbook)
updated.append(cb)
return updated

View File

@ -1,11 +1,11 @@
from uuid import uuid4
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.group.group_preferences import CreateGroupPreferences
from mealie.schema.user.user import GroupBase, GroupInDB
def create_new_group(db: Database, g_base: GroupBase, g_preferences: CreateGroupPreferences = None) -> GroupInDB:
def create_new_group(db: AllRepositories, g_base: GroupBase, g_preferences: CreateGroupPreferences = None) -> GroupInDB:
created_group = db.groups.create(g_base)
# Assign Temporary ID before group is created

View File

@ -21,19 +21,19 @@ class MealService(CrudHttpMixins[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry
item: ReadPlanEntry
@cached_property
def dal(self):
def repo(self):
return self.db.meals
def populate_item(self, id: int) -> ReadPlanEntry:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_slice(self, start: date = None, end: date = None) -> list[ReadPlanEntry]:
# 2 days ago
return self.dal.get_slice(start, end, group_id=self.group_id)
return self.repo.get_slice(start, end, group_id=self.group_id)
def get_today(self) -> list[ReadPlanEntry]:
return self.dal.get_today(group_id=self.group_id)
return self.repo.get_today(group_id=self.group_id)
def create_one(self, data: CreatePlanEntry) -> ReadPlanEntry:
data = self.cast(data, SavePlanEntry)

View File

@ -23,7 +23,7 @@ class GroupMigrationService(UserHttpService[int, ReportOut]):
_schema = ReportOut
@cached_property
def dal(self):
def repo(self):
raise NotImplementedError
def populate_item(self, _: UUID4) -> ReportOut:

View File

@ -17,15 +17,15 @@ class GroupReportService(CrudHttpMixins[ReportOut, ReportCreate, ReportCreate],
_schema = ReportOut
@cached_property
def dal(self):
def repo(self):
return self.db.group_reports
def populate_item(self, id: int) -> ReportOut:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def _get_all(self, report_type: ReportCategory = None) -> list[ReportSummary]:
return self.dal.multi_query({"group_id": self.group_id, "category": report_type}, limit=9999)
return self.repo.multi_query({"group_id": self.group_id, "category": report_type}, limit=9999)
def delete_one(self, id: int = None) -> ReportOut:
return self._delete_one(id)

View File

@ -18,15 +18,15 @@ class WebhookService(CrudHttpMixins[ReadWebhook, CreateWebhook, CreateWebhook],
_schema = ReadWebhook
@cached_property
def dal(self):
def repo(self):
return self.db.webhooks
def populate_item(self, id: int) -> ReadWebhook:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[ReadWebhook]:
return self.dal.get(self.group_id, match_key="group_id", limit=9999)
return self.repo.get(self.group_id, match_key="group_id", limit=9999)
def create_one(self, data: CreateWebhook) -> ReadWebhook:
data = self.cast(data, SaveWebhook)

View File

@ -5,7 +5,7 @@ from uuid import UUID
from pydantic import UUID4
from mealie.core import root_logger
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.schema.recipe import Recipe
from mealie.schema.reports.reports import (
ReportCategory,
@ -29,7 +29,9 @@ class BaseMigrator(BaseService):
report_id: int
report: ReportOut
def __init__(self, archive: Path, db: Database, session, user_id: UUID4, group_id: UUID, add_migration_tag: bool):
def __init__(
self, archive: Path, db: AllRepositories, session, user_id: UUID4, group_id: UUID, add_migration_tag: bool
):
self.archive = archive
self.db = db
self.session = session

View File

@ -4,8 +4,8 @@ from pydantic import UUID4, BaseModel
from slugify import slugify
from sqlalchemy.orm import Session
from mealie.db.data_access_layer.access_model_factory import AccessModel
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.repos.repository_factory import RepositoryGeneric
from mealie.schema.recipe import RecipeCategory
from mealie.schema.recipe.recipe import RecipeTag
@ -13,13 +13,13 @@ T = TypeVar("T", bound=BaseModel)
class DatabaseMigrationHelpers:
def __init__(self, db: Database, session: Session, group_id: int, user_id: UUID4) -> None:
def __init__(self, db: AllRepositories, session: Session, group_id: int, user_id: UUID4) -> None:
self.group_id = group_id
self.user_id = user_id
self.session = session
self.db = db
def _get_or_set_generic(self, accessor: AccessModel, items: list[str], out_model: T) -> list[T]:
def _get_or_set_generic(self, accessor: RepositoryGeneric, items: list[str], out_model: T) -> list[T]:
"""
Utility model for getting or setting categories or tags. This will only work for those two cases.

View File

@ -25,7 +25,7 @@ class RecipeCommentsService(
_schema = RecipeCommentOut
@cached_property
def dal(self):
def repo(self):
return self.db.comments
def _check_comment_belongs_to_user(self) -> None:
@ -33,11 +33,11 @@ class RecipeCommentsService(
raise HTTPException(detail="Comment does not belong to user")
def populate_item(self, id: UUID) -> RecipeCommentOut:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[RecipeCommentOut]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: RecipeCommentCreate) -> RecipeCommentOut:
save_data = RecipeCommentSave(text=data.text, user_id=self.user.id, recipe_id=data.recipe_id)

View File

@ -17,15 +17,15 @@ class RecipeFoodService(
_schema = IngredientFood
@cached_property
def dal(self):
def repo(self):
return self.db.ingredient_foods
def populate_item(self, id: int) -> IngredientFood:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[IngredientFood]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: CreateIngredientFood) -> IngredientFood:
return self._create_one(data)

View File

@ -11,7 +11,7 @@ from sqlalchemy import exc
from mealie.core.dependencies.grouped import UserDeps
from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer.recipe_access_model import RecipeDataAccessModel
from mealie.repos.repository_recipes import RepositoryRecipes
from mealie.schema.recipe.recipe import CreateRecipe, Recipe, RecipeSummary
from mealie.schema.recipe.recipe_settings import RecipeSettings
from mealie.services._base_http_service.crud_http_mixins import CrudHttpMixins
@ -40,7 +40,7 @@ class RecipeService(CrudHttpMixins[CreateRecipe, Recipe, Recipe], UserHttpServic
return {exc.IntegrityError: self.t("recipe.unique-name-error")}
@cached_property
def dal(self) -> RecipeDataAccessModel:
def repo(self) -> RepositoryRecipes:
return self.db.recipes.by_group(self.group_id)
@classmethod

View File

@ -17,15 +17,15 @@ class RecipeToolService(
_schema = RecipeTool
@cached_property
def dal(self):
def repo(self):
return self.db.tools
def populate_item(self, id: int) -> RecipeTool:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[RecipeTool]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: RecipeToolCreate) -> RecipeTool:
return self._create_one(data)

View File

@ -17,15 +17,15 @@ class RecipeUnitService(
_schema = IngredientUnit
@cached_property
def dal(self):
def repo(self):
return self.db.ingredient_units
def populate_item(self, id: int) -> IngredientUnit:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[IngredientUnit]:
return self.dal.get_all()
return self.repo.get_all()
def create_one(self, data: CreateIngredientUnit) -> IngredientUnit:
return self._create_one(data)

View File

@ -4,8 +4,8 @@ import requests
from sqlalchemy.orm.session import Session
from mealie.core import root_logger
from mealie.db.database import get_database
from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.group.webhook import ReadWebhook
from ..scheduled_func import Cron, ScheduledFunc
@ -16,7 +16,7 @@ logger = root_logger.get_logger()
def post_webhooks(webhook_id: int, session: Session = None):
session = session or create_session()
db = get_database(session)
db = get_repositories(session)
webhook: ReadWebhook = db.webhooks.get_one(webhook_id)
if not webhook.enabled:
@ -39,7 +39,7 @@ def post_webhooks(webhook_id: int, session: Session = None):
def update_group_webhooks():
session = create_session()
db = get_database(session)
db = get_repositories(session)
webhooks: list[ReadWebhook] = db.webhooks.get_all()

View File

@ -4,7 +4,7 @@ from typing import Any, Callable
from sqlalchemy.orm import Session
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
from mealie.schema.server.tasks import ServerTask, ServerTaskCreate, ServerTaskNames
from .._base_http_service.http_services import UserHttpService
@ -32,7 +32,7 @@ class BackgroundExecutor(UserHttpService):
def test_executor_func(task_id: int, session: Session) -> None:
database = get_database(session)
database = get_repositories(session)
task = database.server_tasks.get_one(task_id)
task.append_log("test task has started")

View File

@ -9,15 +9,15 @@ class ServerTasksHttpService(UserHttpService[int, ServerTask]):
_schema = ServerTask
@cached_property
def dal(self):
def repo(self):
return self.db.server_tasks
def populate_item(self, id: int) -> ServerTask:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[ServerTask]:
return self.dal.multi_query(query_by={"group_id": self.group_id}, order_by="created_at")
return self.repo.multi_query(query_by={"group_id": self.group_id}, order_by="created_at")
class AdminServerTasks(AdminHttpService[int, ServerTask]):
@ -25,12 +25,12 @@ class AdminServerTasks(AdminHttpService[int, ServerTask]):
_schema = ServerTask
@cached_property
def dal(self):
def repo(self):
return self.db.server_tasks
def populate_item(self, id: int) -> ServerTask:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self) -> list[ServerTask]:
return self.dal.get_all(order_by="created_at")
return self.repo.get_all(order_by="created_at")

View File

@ -22,11 +22,11 @@ class SharedRecipeService(
_schema = RecipeShareToken
@cached_property
def dal(self):
def repo(self):
return self.db.recipe_share_tokens
def populate_item(self, id: UUID4) -> RecipeShareToken:
self.item = self.dal.get_one(id)
self.item = self.repo.get_one(id)
return self.item
def get_all(self, recipe_id=None) -> list[RecipeShareTokenSummary]:
@ -48,4 +48,4 @@ class SharedRecipeService(
def delete_one(self, item_id: UUID4 = None) -> None:
item_id = item_id or self.item.id
return self.dal.delete(item_id)
return self.repo.delete(item_id)

View File

@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger
from mealie.core.security import hash_password, url_safe_token
from mealie.db.database import get_database
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user.user_passwords import SavePasswordResetToken
from mealie.services._base_service import BaseService
from mealie.services.email import EmailService
@ -13,7 +13,7 @@ logger = get_logger(__name__)
class PasswordResetService(BaseService):
def __init__(self, session: Session) -> None:
self.db = get_database(session)
self.db = get_repositories(session)
super().__init__()
def generate_reset_token(self, email: str) -> SavePasswordResetToken:

View File

@ -3,15 +3,15 @@ import json
import requests
from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user import GroupInDB
from mealie.services.events import create_scheduled_event
def post_webhooks(group: int, session: Session = None, force=True):
session = session or create_session()
db = get_database(session)
db = get_repositories(session)
group_settings: GroupInDB = db.groups.get(group)
if not group_settings.webhook_enable and not force:

View File

@ -1,14 +1,14 @@
import pytest
from mealie.db.database import Database, get_database
from mealie.db.db_setup import SessionLocal
from mealie.repos.all_repositories import AllRepositories, get_repositories
@pytest.fixture()
def database() -> Database:
def database() -> AllRepositories:
try:
db = SessionLocal()
yield get_database(db)
yield get_repositories(db)
finally:
db.close()

View File

@ -1,9 +1,9 @@
from mealie.db.database import Database
from mealie.repos.all_repositories import AllRepositories
from mealie.schema.user import PrivateUser
from tests.utils.fixture_schemas import TestUser
def test_user_directory_deleted_on_delete(database: Database, unique_user: TestUser) -> None:
def test_user_directory_deleted_on_delete(database: AllRepositories, unique_user: TestUser) -> None:
user_dir = PrivateUser.get_directory(unique_user.user_id)
assert user_dir.exists()
database.users.delete(unique_user.user_id)