mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-02-11 10:23:12 -05:00
Feature/improve localization (#1147)
* use locale to set language header * rewrite i18n provider and drop dependency * rename file * rename CrudMixin to HttpRepo * refactor: code-cleanup * add crowdin source * remove unused translations * grab translations from dev branch * add translation support for foods, units, and labels * remove rich import
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from sqlite3 import IntegrityError
|
||||
|
||||
from mealie.lang.providers import AbstractLocaleProvider
|
||||
from mealie.lang.providers import Translator
|
||||
|
||||
|
||||
class PermissionDenied(Exception):
|
||||
@@ -19,7 +19,7 @@ class NoEntryFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def mealie_registered_exceptions(t: AbstractLocaleProvider) -> dict:
|
||||
def mealie_registered_exceptions(t: Translator) -> dict:
|
||||
"""
|
||||
This function returns a dictionary of all the globally registered exceptions in the Mealie application.
|
||||
"""
|
||||
|
||||
@@ -18,7 +18,7 @@ def fix_slug_food_names(db: AllRepositories):
|
||||
|
||||
all_foods = db.ingredient_foods.get_all()
|
||||
|
||||
seed_foods: dict[str, str] = json.loads(food_resources.en_us.read_text())
|
||||
seed_foods: dict[str, str] = json.loads(food_resources.en_US.read_text())
|
||||
|
||||
for food in all_foods:
|
||||
if food.name in seed_foods:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"generic": {
|
||||
"server-error": "Something went wrong"
|
||||
"server-error": "An unexpected error occurred"
|
||||
},
|
||||
"recipe": {
|
||||
"unique-name-error": "Recipe names must be unique"
|
||||
@@ -10,4 +10,4 @@
|
||||
"no-entry-found": "The requested resource was not found",
|
||||
"integrity-error": "Database integrity error"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from abc import abstractmethod
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Protocol
|
||||
|
||||
import i18n
|
||||
from bcrypt import os
|
||||
from fastapi import Header
|
||||
|
||||
from mealie.pkgs import i18n
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
TRANSLATIONS = CWD / "messages"
|
||||
|
||||
|
||||
class AbstractLocaleProvider(ABC):
|
||||
class Translator(Protocol):
|
||||
@abstractmethod
|
||||
def t(self, key):
|
||||
def t(self, key, default=None, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class i18nProvider(AbstractLocaleProvider):
|
||||
def __init__(self, locale):
|
||||
i18n.set("file_format", "json")
|
||||
i18n.set("filename_format", "{locale}.{format}")
|
||||
i18n.set("skip_locale_root_data", True)
|
||||
i18n.load_path.append(TRANSLATIONS)
|
||||
i18n.set("locale", locale)
|
||||
i18n.set("fallback", "en-US")
|
||||
self._t = i18n.t
|
||||
|
||||
def t(self, key):
|
||||
return self._t(key)
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_locale_provider():
|
||||
lang = os.environ.get("LANG", "en-US")
|
||||
return i18nProvider(lang)
|
||||
def _load_factory() -> i18n.ProviderFactory:
|
||||
return i18n.ProviderFactory(
|
||||
directory=TRANSLATIONS,
|
||||
fallback_locale="en-US",
|
||||
)
|
||||
|
||||
|
||||
def local_provider(accept_language: str | None = Header(None)) -> Translator:
|
||||
factory = _load_factory()
|
||||
accept_language = accept_language or "en-US"
|
||||
return factory.get(accept_language)
|
||||
|
||||
2
mealie/pkgs/i18n/__init__.py
Normal file
2
mealie/pkgs/i18n/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .json_provider import *
|
||||
from .provider_factory import *
|
||||
34
mealie/pkgs/i18n/json_provider.py
Normal file
34
mealie/pkgs/i18n/json_provider.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class JsonProvider:
|
||||
translations: dict
|
||||
|
||||
def __init__(self, path: Path | dict):
|
||||
if isinstance(path, Path):
|
||||
self.translations = json.loads(path.read_text())
|
||||
else:
|
||||
self.translations = path
|
||||
|
||||
def t(self, key: str, default=None, **kwargs) -> str:
|
||||
keys = key.split(".")
|
||||
|
||||
translation_value: dict | str = self.translations
|
||||
last = len(keys) - 1
|
||||
|
||||
for i, k in enumerate(keys):
|
||||
if k not in translation_value:
|
||||
break
|
||||
|
||||
try:
|
||||
translation_value = translation_value[k] # type: ignore
|
||||
except Exception:
|
||||
break
|
||||
|
||||
if i == last:
|
||||
return translation_value
|
||||
|
||||
return default or key
|
||||
43
mealie/pkgs/i18n/provider_factory.py
Normal file
43
mealie/pkgs/i18n/provider_factory.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from .json_provider import JsonProvider
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class InUseProvider:
|
||||
provider: JsonProvider
|
||||
locks: int
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class ProviderFactory:
|
||||
directory: Path
|
||||
fallback_locale: str = "en-US"
|
||||
filename_format = "{locale}.{format}"
|
||||
|
||||
_store: dict[str, InUseProvider] = field(default_factory=dict)
|
||||
|
||||
@property
|
||||
def fallback_file(self) -> Path:
|
||||
return self.directory / self.filename_format.format(locale=self.fallback_locale, format="json")
|
||||
|
||||
def _load(self, locale: str) -> JsonProvider:
|
||||
filename = self.filename_format.format(locale=locale, format="json")
|
||||
path = self.directory / filename
|
||||
|
||||
return JsonProvider(path) if path.exists() else JsonProvider(self.fallback_file)
|
||||
|
||||
def release(self, locale) -> None:
|
||||
if locale in self._store:
|
||||
self._store[locale].locks -= 1
|
||||
if self._store[locale].locks == 0:
|
||||
del self._store[locale]
|
||||
|
||||
def get(self, locale: str) -> JsonProvider:
|
||||
if locale in self._store:
|
||||
self._store[locale].locks += 1
|
||||
else:
|
||||
self._store[locale] = InUseProvider(provider=self._load(locale), locks=1)
|
||||
|
||||
return self._store[locale].provider
|
||||
@@ -2,4 +2,4 @@ from pathlib import Path
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
|
||||
en_us = CWD / "en-us.json"
|
||||
en_US = CWD / "en-US.json"
|
||||
|
||||
@@ -2,4 +2,4 @@ from pathlib import Path
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
|
||||
en_us = CWD / "en-us.json"
|
||||
en_US = CWD / "en-US.json"
|
||||
|
||||
@@ -2,4 +2,4 @@ from pathlib import Path
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
|
||||
en_us = CWD / "en-us.json"
|
||||
en_US = CWD / "en-US.json"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .abc_controller import *
|
||||
from .base_controllers import *
|
||||
from .controller import *
|
||||
from .dependencies import *
|
||||
from .mixins import *
|
||||
|
||||
@@ -11,29 +11,26 @@ class OperationChecks:
|
||||
|
||||
user: PrivateUser
|
||||
|
||||
ForbiddenException = HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
UnauthorizedException = HTTPException(status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def __init__(self, user: PrivateUser) -> None:
|
||||
self.user = user
|
||||
|
||||
def _raise_unauthorized(self) -> None:
|
||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def _raise_forbidden(self) -> None:
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# =========================================
|
||||
# User Permission Checks
|
||||
|
||||
def can_manage(self) -> bool:
|
||||
if not self.user.can_manage:
|
||||
self._raise_forbidden()
|
||||
raise self.ForbiddenException
|
||||
return True
|
||||
|
||||
def can_invite(self) -> bool:
|
||||
if not self.user.can_invite:
|
||||
self._raise_forbidden()
|
||||
raise self.ForbiddenException
|
||||
return True
|
||||
|
||||
def can_organize(self) -> bool:
|
||||
if not self.user.can_organize:
|
||||
self._raise_forbidden()
|
||||
raise self.ForbiddenException
|
||||
return True
|
||||
|
||||
@@ -151,8 +151,8 @@ def _allocate_routes_by_method_name(router: APIRouter, url: str, function_member
|
||||
responses = None
|
||||
kwargs = {}
|
||||
status_code = 200
|
||||
return_types_func = getattr(func, RETURN_TYPES_FUNC_KEY, None)
|
||||
if return_types_func:
|
||||
|
||||
if return_types_func := getattr(func, RETURN_TYPES_FUNC_KEY, None):
|
||||
response_model, status_code, responses, kwargs = return_types_func()
|
||||
|
||||
api_resource = router.api_route(
|
||||
|
||||
@@ -10,40 +10,46 @@ from mealie.core.root_logger import get_logger
|
||||
from mealie.core.settings.directories import AppDirectories
|
||||
from mealie.core.settings.settings import AppSettings
|
||||
from mealie.db.db_setup import generate_session
|
||||
from mealie.lang import AbstractLocaleProvider, get_locale_provider
|
||||
from mealie.lang import Translator, local_provider
|
||||
from mealie.repos import AllRepositories
|
||||
from mealie.schema.user.user import PrivateUser
|
||||
|
||||
|
||||
class SharedDependencies:
|
||||
session: Session
|
||||
t: AbstractLocaleProvider
|
||||
t: Translator
|
||||
acting_user: PrivateUser | None
|
||||
|
||||
def __init__(self, session: Session, acting_user: PrivateUser | None) -> None:
|
||||
self.t = get_locale_provider()
|
||||
def __init__(self, session: Session, acting_user: PrivateUser | None, provider: Translator | None = None) -> None:
|
||||
self.t = provider or local_provider()
|
||||
self.session = session
|
||||
self.acting_user = acting_user
|
||||
|
||||
@classmethod
|
||||
def public(cls, session: Session = Depends(generate_session)) -> "SharedDependencies":
|
||||
return cls(session, None)
|
||||
def public(
|
||||
cls,
|
||||
session: Session = Depends(generate_session),
|
||||
translator: Translator = Depends(local_provider),
|
||||
) -> "SharedDependencies":
|
||||
return cls(session, None, translator)
|
||||
|
||||
@classmethod
|
||||
def user(
|
||||
cls,
|
||||
session: Session = Depends(generate_session),
|
||||
user: PrivateUser = Depends(get_current_user),
|
||||
translator: Translator = Depends(local_provider),
|
||||
) -> "SharedDependencies":
|
||||
return cls(session, user)
|
||||
return cls(session, user, translator)
|
||||
|
||||
@classmethod
|
||||
def admin(
|
||||
cls,
|
||||
session: Session = Depends(generate_session),
|
||||
admin: PrivateUser = Depends(get_admin_user),
|
||||
translator: Translator = Depends(local_provider),
|
||||
) -> "SharedDependencies":
|
||||
return cls(session, admin)
|
||||
return cls(session, admin, translator)
|
||||
|
||||
@cached_property
|
||||
def logger(self) -> Logger:
|
||||
|
||||
@@ -13,15 +13,15 @@ R = TypeVar("R", bound=BaseModel)
|
||||
U = TypeVar("U", bound=BaseModel)
|
||||
|
||||
|
||||
class CrudMixins(Generic[C, R, U]):
|
||||
class HttpRepo(Generic[C, R, U]):
|
||||
"""
|
||||
The CrudMixins[C, R, U] class is a mixin class that provides a common set of methods for CRUD operations.
|
||||
The HttpRepo[C, R, U] class is a mixin class that provides a common set of methods for CRUD operations.
|
||||
This class is inteded to be used in a composition pattern where a class has a mixin property. For example:
|
||||
|
||||
```
|
||||
class MyClass:
|
||||
def __init(self repo, logger):
|
||||
self.mixins = CrudMixins(repo, logger)
|
||||
def __init__(self, repo, logger):
|
||||
self.mixins = HttpRepo(repo, logger)
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
@@ -18,6 +18,7 @@ class AdminAboutController(BaseAdminController):
|
||||
@router.get("", response_model=AdminAboutInfo)
|
||||
def get_app_info(self):
|
||||
"""Get general application information"""
|
||||
|
||||
settings = self.deps.settings
|
||||
|
||||
return AdminAboutInfo(
|
||||
@@ -48,12 +49,11 @@ class AdminAboutController(BaseAdminController):
|
||||
@router.get("/check", response_model=CheckAppConfig)
|
||||
def check_app_config(self):
|
||||
settings = self.deps.settings
|
||||
url_set = settings.BASE_URL != "http://localhost:8080"
|
||||
|
||||
return CheckAppConfig(
|
||||
email_ready=settings.SMTP_ENABLE,
|
||||
ldap_ready=settings.LDAP_ENABLED,
|
||||
base_url_set=url_set,
|
||||
base_url_set=settings.BASE_URL != "http://localhost:8080",
|
||||
is_up_to_date=get_latest_version() == APP_VERSION,
|
||||
)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from mealie.services.group_services.group_service import GroupService
|
||||
|
||||
from .._base import BaseAdminController, controller
|
||||
from .._base.dependencies import SharedDependencies
|
||||
from .._base.mixins import CrudMixins
|
||||
from .._base.mixins import HttpRepo
|
||||
|
||||
router = APIRouter(prefix="/groups", tags=["Admin: Groups"])
|
||||
|
||||
@@ -33,7 +33,7 @@ class AdminUserManagementRoutes(BaseAdminController):
|
||||
|
||||
@property
|
||||
def mixins(self):
|
||||
return CrudMixins[GroupBase, GroupInDB, GroupAdminUpdate](
|
||||
return HttpRepo[GroupBase, GroupInDB, GroupAdminUpdate](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -6,7 +6,7 @@ from pydantic import UUID4
|
||||
from mealie.core import security
|
||||
from mealie.routes._base import BaseAdminController, controller
|
||||
from mealie.routes._base.dependencies import SharedDependencies
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.response.responses import ErrorResponse
|
||||
from mealie.schema.user.user import UserIn, UserOut
|
||||
@@ -30,7 +30,7 @@ class AdminUserManagementRoutes(BaseAdminController):
|
||||
|
||||
@property
|
||||
def mixins(self):
|
||||
return CrudMixins[UserIn, UserOut, UserOut](self.repo, self.deps.logger, self.registered_exceptions)
|
||||
return HttpRepo[UserIn, UserOut, UserOut](self.repo, self.deps.logger, self.registered_exceptions)
|
||||
|
||||
@router.get("", response_model=list[UserOut])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -7,7 +7,7 @@ router = APIRouter(prefix="/about")
|
||||
|
||||
|
||||
@router.get("", response_model=AppInfo)
|
||||
async def get_app_info():
|
||||
def get_app_info():
|
||||
"""Get general application information"""
|
||||
settings = get_app_settings()
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.core.exceptions import mealie_registered_exceptions
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.recipe.recipe_comments import (
|
||||
RecipeCommentCreate,
|
||||
@@ -30,8 +30,8 @@ class RecipeCommentRoutes(BaseUserController):
|
||||
# CRUD Operations
|
||||
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
|
||||
def _check_comment_belongs_to_user(self, item_id: UUID4) -> None:
|
||||
comment = self.repo.get_one(item_id)
|
||||
|
||||
@@ -5,7 +5,7 @@ from pydantic import UUID4
|
||||
|
||||
from mealie.core.exceptions import mealie_registered_exceptions
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.cookbook import CreateCookBook, ReadCookBook, RecipeCookBook, SaveCookBook, UpdateCookBook
|
||||
|
||||
@@ -26,7 +26,7 @@ class GroupCookbookController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[CreateCookBook, ReadCookBook, UpdateCookBook](
|
||||
return HttpRepo[CreateCookBook, ReadCookBook, UpdateCookBook](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.group.group_events import (
|
||||
GroupEventNotifierCreate,
|
||||
GroupEventNotifierOut,
|
||||
@@ -35,8 +35,8 @@ class GroupEventsNotifierController(BaseUserController):
|
||||
# CRUD Operations
|
||||
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
|
||||
@router.get("", response_model=list[GroupEventNotifierOut])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -4,9 +4,9 @@ from fastapi import APIRouter
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.core.exceptions import mealie_registered_exceptions
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.reports.reports import ReportCategory, ReportCreate, ReportOut, ReportSummary
|
||||
|
||||
router = APIRouter(prefix="/groups/reports", tags=["Groups: Reports"])
|
||||
@@ -25,7 +25,7 @@ class GroupReportsController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[ReportCreate, ReportOut, ReportCreate](
|
||||
return HttpRepo[ReportCreate, ReportOut, ReportCreate](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -2,7 +2,7 @@ from functools import cached_property
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.group.group_permissions import SetPermissions
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.labels import (
|
||||
MultiPurposeLabelCreate,
|
||||
MultiPurposeLabelOut,
|
||||
@@ -32,8 +32,8 @@ class MultiPurposeLabelsController(BaseUserController):
|
||||
# CRUD Operations
|
||||
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
|
||||
@router.get("", response_model=list[MultiPurposeLabelSummary])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -6,7 +6,7 @@ from fastapi import APIRouter, HTTPException
|
||||
from mealie.core.exceptions import mealie_registered_exceptions
|
||||
from mealie.repos.repository_meals import RepositoryMeals
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.meal_plan import CreatePlanEntry, ReadPlanEntry, SavePlanEntry, UpdatePlanEntry
|
||||
from mealie.schema.meal_plan.new_meal import CreatRandomEntry
|
||||
@@ -31,7 +31,7 @@ class GroupMealplanController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry](
|
||||
return HttpRepo[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.recipe.recipe_category import CategoryBase
|
||||
from mealie.schema.user.user import GroupInDB
|
||||
@@ -12,7 +12,7 @@ router = UserAPIRouter(prefix="/groups/categories", tags=["Groups: Mealplan Cate
|
||||
class GroupMealplanConfigController(BaseUserController):
|
||||
@property
|
||||
def mixins(self):
|
||||
return CrudMixins[GroupInDB, GroupInDB, GroupInDB](self.repos.groups, self.deps.logger)
|
||||
return HttpRepo[GroupInDB, GroupInDB, GroupInDB](self.repos.groups, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[CategoryBase])
|
||||
def get_mealplan_categories(self):
|
||||
|
||||
@@ -2,9 +2,9 @@ from functools import cached_property
|
||||
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.meal_plan.plan_rules import PlanRulesCreate, PlanRulesOut, PlanRulesSave
|
||||
@@ -20,7 +20,7 @@ class GroupMealplanConfigController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[PlanRulesCreate, PlanRulesOut, PlanRulesOut](self.repo, self.deps.logger)
|
||||
return HttpRepo[PlanRulesCreate, PlanRulesOut, PlanRulesOut](self.repo, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[PlanRulesOut])
|
||||
def get_all(self):
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema.group.group_shopping_list import (
|
||||
ShoppingListCreate,
|
||||
ShoppingListItemCreate,
|
||||
@@ -38,7 +38,7 @@ class ShoppingListItemController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[ShoppingListItemCreate, ShoppingListItemOut, ShoppingListItemCreate](
|
||||
return HttpRepo[ShoppingListItemCreate, ShoppingListItemOut, ShoppingListItemCreate](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
)
|
||||
@@ -106,8 +106,8 @@ class ShoppingListController(BaseUserController):
|
||||
# CRUD Operations
|
||||
|
||||
@cached_property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
|
||||
|
||||
@router.get("", response_model=list[ShoppingListSummary])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.group.webhook import CreateWebhook, ReadWebhook, SaveWebhook
|
||||
from mealie.schema.query import GetAll
|
||||
@@ -20,8 +20,8 @@ class ReadWebhookController(BaseUserController):
|
||||
return self.repos.webhooks.by_group(self.group_id)
|
||||
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins[CreateWebhook, SaveWebhook, CreateWebhook](self.repo, self.deps.logger)
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo[CreateWebhook, SaveWebhook, CreateWebhook](self.repo, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[ReadWebhook])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -4,7 +4,7 @@ from fastapi import APIRouter
|
||||
from pydantic import UUID4, BaseModel
|
||||
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
|
||||
from mealie.schema.recipe.recipe import RecipeCategory
|
||||
@@ -32,7 +32,7 @@ class RecipeCategoryController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins(self.repo, self.deps.logger)
|
||||
return HttpRepo(self.repo, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[CategorySummary])
|
||||
def get_all(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ from fastapi import APIRouter, HTTPException, status
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.recipe import RecipeTagResponse, TagIn
|
||||
from mealie.schema.recipe.recipe import RecipeTag
|
||||
@@ -21,7 +21,7 @@ class TagController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins(self.repo, self.deps.logger)
|
||||
return HttpRepo(self.repo, self.deps.logger)
|
||||
|
||||
@router.get("")
|
||||
async def get_all(self):
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.recipe.recipe import RecipeTool
|
||||
@@ -21,8 +21,8 @@ class RecipeToolController(BaseUserController):
|
||||
return self.repos.tools.by_group(self.group_id)
|
||||
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins[RecipeToolCreate, RecipeTool, RecipeToolCreate](self.repo, self.deps.logger)
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo[RecipeToolCreate, RecipeTool, RecipeToolCreate](self.repo, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[RecipeTool])
|
||||
def get_all(self, q: GetAll = Depends(GetAll)):
|
||||
|
||||
@@ -20,7 +20,7 @@ from mealie.pkgs import cache
|
||||
from mealie.repos.all_repositories import get_repositories
|
||||
from mealie.repos.repository_recipes import RepositoryRecipes
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.recipe import CreateRecipeByUrl, Recipe, RecipeImageTypes
|
||||
@@ -47,7 +47,7 @@ class BaseRecipeController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[CreateRecipe, Recipe, Recipe](self.repo, self.deps.logger)
|
||||
return HttpRepo[CreateRecipe, Recipe, Recipe](self.repo, self.deps.logger)
|
||||
|
||||
|
||||
class RecipeGetAll(GetAll):
|
||||
|
||||
@@ -3,7 +3,7 @@ from functools import cached_property
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.recipe import RecipeShareTokenSummary
|
||||
from mealie.schema.recipe.recipe_share_token import RecipeShareToken, RecipeShareTokenCreate, RecipeShareTokenSave
|
||||
@@ -19,7 +19,7 @@ class RecipeSharedController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[RecipeShareTokenSave, RecipeShareToken, RecipeShareTokenCreate](self.repo, self.deps.logger)
|
||||
return HttpRepo[RecipeShareTokenSave, RecipeShareToken, RecipeShareTokenCreate](self.repo, self.deps.logger)
|
||||
|
||||
@router.get("", response_model=list[RecipeShareTokenSummary])
|
||||
def get_all(self, recipe_id: UUID4 = None):
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.recipe.recipe_ingredient import CreateIngredientFood, IngredientFood, MergeFood, SaveIngredientFood
|
||||
@@ -22,7 +22,7 @@ class IngredientFoodsController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[SaveIngredientFood, IngredientFood, CreateIngredientFood](
|
||||
return HttpRepo[SaveIngredientFood, IngredientFood, CreateIngredientFood](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -3,9 +3,9 @@ from functools import cached_property
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.schema import mapper
|
||||
from mealie.schema.query import GetAll
|
||||
from mealie.schema.recipe.recipe_ingredient import CreateIngredientUnit, IngredientUnit, MergeUnit, SaveIngredientUnit
|
||||
@@ -22,7 +22,7 @@ class IngredientUnitsController(BaseUserController):
|
||||
|
||||
@cached_property
|
||||
def mixins(self):
|
||||
return CrudMixins[CreateIngredientUnit, IngredientUnit, CreateIngredientUnit](
|
||||
return HttpRepo[CreateIngredientUnit, IngredientUnit, CreateIngredientUnit](
|
||||
self.repo,
|
||||
self.deps.logger,
|
||||
self.registered_exceptions,
|
||||
|
||||
@@ -3,8 +3,8 @@ from pydantic import UUID4
|
||||
|
||||
from mealie.core.security import hash_password, verify_password
|
||||
from mealie.routes._base import BaseAdminController, controller
|
||||
from mealie.routes._base.abc_controller import BaseUserController
|
||||
from mealie.routes._base.mixins import CrudMixins
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import AdminAPIRouter, UserAPIRouter
|
||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||
from mealie.schema.response import ErrorResponse, SuccessResponse
|
||||
@@ -17,8 +17,8 @@ admin_router = AdminAPIRouter(prefix="/users", tags=["Users: Admin CRUD"])
|
||||
@controller(admin_router)
|
||||
class AdminUserController(BaseAdminController):
|
||||
@property
|
||||
def mixins(self) -> CrudMixins:
|
||||
return CrudMixins[UserIn, UserOut, UserBase](self.repos.users, self.deps.logger)
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo[UserIn, UserOut, UserBase](self.repos.users, self.deps.logger)
|
||||
|
||||
@admin_router.get("", response_model=list[UserOut])
|
||||
def get_all_users(self):
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
from mealie.core.config import get_app_dirs, get_app_settings
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.lang import get_locale_provider
|
||||
|
||||
|
||||
class BaseService:
|
||||
def __init__(self) -> None:
|
||||
self.directories = get_app_dirs()
|
||||
self.settings = get_app_settings()
|
||||
self.t = get_locale_provider()
|
||||
self.logger = get_logger()
|
||||
|
||||
Reference in New Issue
Block a user