diff --git a/docs/docs/changelog/v0.4.1.md b/docs/docs/changelog/v0.4.1.md index 747fa6a8473a..2b2a6d7bcedb 100644 --- a/docs/docs/changelog/v0.4.1.md +++ b/docs/docs/changelog/v0.4.1.md @@ -12,4 +12,5 @@ - Fix Backup download blocked by authentication - Random meal-planner will no longer duplicate recipes unless no other options - New Quick Week button to generate next 5 day week of recipe slots. +- Minor UI tweaks diff --git a/frontend/src/components/Admin/MealPlanner/TimePickerDialog.vue b/frontend/src/components/Admin/MealPlanner/TimePickerDialog.vue index eda11de4aa59..35423f9e818d 100644 --- a/frontend/src/components/Admin/MealPlanner/TimePickerDialog.vue +++ b/frontend/src/components/Admin/MealPlanner/TimePickerDialog.vue @@ -42,4 +42,7 @@ export default { \ No newline at end of file diff --git a/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue b/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue index e3f79077a532..036a3516a60b 100644 --- a/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue +++ b/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue @@ -10,14 +10,14 @@ @@ -55,12 +55,8 @@ export default { }; - \ No newline at end of file diff --git a/frontend/src/pages/Admin/MealPlanner/index.vue b/frontend/src/pages/Admin/MealPlanner/index.vue index a1b953430890..e9266b53a449 100644 --- a/frontend/src/pages/Admin/MealPlanner/index.vue +++ b/frontend/src/pages/Admin/MealPlanner/index.vue @@ -57,28 +57,23 @@ {{ groupSettings.webhookTime }}

- - - - - - - - - - mdi-webhook - {{ $t("settings.webhooks.test-webhooks") }} - - + + + + + mdi-webhook + {{ $t("settings.webhooks.test-webhooks") }} + diff --git a/mealie/core/config.py b/mealie/core/config.py index aca765dfff10..0f5e21c2f30c 100644 --- a/mealie/core/config.py +++ b/mealie/core/config.py @@ -1,8 +1,9 @@ import os import secrets from pathlib import Path +from typing import Optional, Union -import dotenv +from pydantic import BaseSettings, Field, validator APP_VERSION = "v0.4.0" DB_VERSION = "v0.4.0" @@ -11,7 +12,6 @@ CWD = Path(__file__).parent BASE_DIR = CWD.parent.parent ENV = BASE_DIR.joinpath(".env") -dotenv.load_dotenv(ENV) PRODUCTION = os.environ.get("ENV") @@ -38,6 +38,11 @@ def determine_secrets(data_dir: Path, production: bool) -> str: return new_secret +# General +DATA_DIR = determine_data_dir(PRODUCTION) +LOGGER_FILE = DATA_DIR.joinpath("mealie.log") + + class AppDirectories: def __init__(self, cwd, data_dir) -> None: self.DATA_DIR = data_dir @@ -74,36 +79,51 @@ class AppDirectories: dir.mkdir(parents=True, exist_ok=True) -class AppSettings: - def __init__(self, app_dirs: AppDirectories) -> None: - global DB_VERSION - self.PRODUCTION = bool(os.environ.get("ENV")) - self.IS_DEMO = os.getenv("DEMO", "False") == "True" - self.API_PORT = int(os.getenv("API_PORT", 9000)) - self.API = os.getenv("API_DOCS", "True") == "True" - self.DOCS_URL = "/docs" if self.API else None - self.REDOC_URL = "/redoc" if self.API else None - self.SECRET = determine_secrets(app_dirs.DATA_DIR, self.PRODUCTION) - self.DATABASE_TYPE = os.getenv("DB_TYPE", "sqlite") - - # Used to Set SQLite File Version - self.SQLITE_FILE = None - if self.DATABASE_TYPE == "sqlite": - self.SQLITE_FILE = app_dirs.SQLITE_DIR.joinpath(f"mealie_{DB_VERSION}.sqlite") - else: - raise Exception("Unable to determine database type. Acceptible options are 'sqlite'") - - self.DEFAULT_GROUP = os.getenv("DEFAULT_GROUP", "Home") - self.DEFAULT_PASSWORD = os.getenv("DEFAULT_PASSWORD", "MyPassword") - - # Not Used! - self.SFTP_USERNAME = os.getenv("SFTP_USERNAME", None) - self.SFTP_PASSWORD = os.getenv("SFTP_PASSWORD", None) - - -# General -DATA_DIR = determine_data_dir(PRODUCTION) -LOGGER_FILE = DATA_DIR.joinpath("mealie.log") - app_dirs = AppDirectories(CWD, DATA_DIR) -settings = AppSettings(app_dirs) + + +class AppSettings(BaseSettings): + global DATA_DIR + PRODUCTION: bool = Field(False, env="ENV") + IS_DEMO: bool = False + API_PORT: int = 9000 + API_DOCS: bool = True + + @property + def DOCS_URL(self) -> str: + return "/docs" if self.API_DOCS else None + + @property + def REDOC_URL(self) -> str: + return "/redoc" if self.API_DOCS else None + + SECRET: str = determine_secrets(DATA_DIR, PRODUCTION) + DATABASE_TYPE: str = Field("sqlite", env="DB_TYPE") + + @validator("DATABASE_TYPE", pre=True) + def validate_db_type(cls, v: str) -> Optional[str]: + if v != "sqlite": + raise ValueError("Unable to determine database type. Acceptible options are 'sqlite'") + else: + return v + + # Used to Set SQLite File Version + SQLITE_FILE: Optional[Union[str, Path]] + + @validator("SQLITE_FILE", pre=True) + def identify_sqlite_file(cls, v: str) -> Optional[str]: + return app_dirs.SQLITE_DIR.joinpath(f"mealie_{DB_VERSION}.sqlite") + + DEFAULT_GROUP: str = "Home" + DEFAULT_PASSWORD: str = "MyPassword" + + # Not Used! + SFTP_USERNAME: Optional[str] + SFTP_PASSWORD: Optional[str] + + class Config: + env_file = BASE_DIR.joinpath(".env") + env_file_encoding = "utf-8" + + +settings = AppSettings() diff --git a/tests/unit_tests/test_config.py b/tests/unit_tests/test_config.py index fc88f11b8d29..d434e12adfff 100644 --- a/tests/unit_tests/test_config.py +++ b/tests/unit_tests/test_config.py @@ -4,19 +4,39 @@ import pytest from mealie.core.config import CWD, DATA_DIR, AppDirectories, AppSettings, determine_data_dir, determine_secrets +def test_default_settings(monkeypatch): + monkeypatch.delenv("DEFAULT_GROUP", raising=False) + monkeypatch.delenv("DEFAULT_PASSWORD", raising=False) + monkeypatch.delenv("API_PORT", raising=False) + monkeypatch.delenv("API_DOCS", raising=False) + monkeypatch.delenv("DB_TYPE", raising=False) + monkeypatch.delenv("IS_DEMO", raising=False) + + app_settings = AppSettings() + + assert app_settings.DEFAULT_GROUP == "Home" + assert app_settings.DEFAULT_PASSWORD == "MyPassword" + assert app_settings.DATABASE_TYPE == "sqlite" + assert app_settings.API_PORT == 9000 + assert app_settings.API_DOCS is True + assert app_settings.IS_DEMO is False + + assert app_settings.REDOC_URL == "/redoc" + assert app_settings.DOCS_URL == "/docs" + + def test_non_default_settings(monkeypatch): monkeypatch.setenv("DEFAULT_GROUP", "Test Group") monkeypatch.setenv("DEFAULT_PASSWORD", "Test Password") monkeypatch.setenv("API_PORT", "8000") monkeypatch.setenv("API_DOCS", False) - app_dirs = AppDirectories(CWD, DATA_DIR) - app_settings = AppSettings(app_dirs) + app_settings = AppSettings() assert app_settings.DEFAULT_GROUP == "Test Group" assert app_settings.DEFAULT_PASSWORD == "Test Password" assert app_settings.API_PORT == 8000 - assert app_settings.API is False + assert app_settings.API_DOCS is False assert app_settings.REDOC_URL is None assert app_settings.DOCS_URL is None @@ -25,9 +45,8 @@ def test_non_default_settings(monkeypatch): def test_unknown_database(monkeypatch): monkeypatch.setenv("DB_TYPE", "nonsense") - with pytest.raises(Exception, match="Unable to determine database type. Acceptible options are 'sqlite'"): - app_dirs = AppDirectories(CWD, DATA_DIR) - AppSettings(app_dirs) + with pytest.raises(ValueError, match="Unable to determine database type. Acceptible options are 'sqlite'"): + AppSettings() def test_secret_generation(tmp_path):