mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
theme + settings refactor
This commit is contained in:
parent
664b50c7f0
commit
866e7de498
19 changed files with 236 additions and 262 deletions
|
@ -12,7 +12,6 @@ from routes import (
|
|||
setting_routes,
|
||||
static_routes,
|
||||
theme_routes,
|
||||
user_routes,
|
||||
)
|
||||
from routes.recipe import (
|
||||
all_recipe_routes,
|
||||
|
@ -22,18 +21,6 @@ from routes.recipe import (
|
|||
)
|
||||
from utils.logger import logger
|
||||
|
||||
"""
|
||||
TODO:
|
||||
- [x] Fix Duplicate Category
|
||||
- [x] Fix category overflow
|
||||
- [ ] Enable Database Name Versioning
|
||||
- [ ] Finish Frontend Category Management
|
||||
- [x] Delete Category
|
||||
- [ ] Sort Sidebar A-Z
|
||||
- [ ] Refactor Test Endpoints - Abstract to fixture?
|
||||
|
||||
|
||||
"""
|
||||
app = FastAPI(
|
||||
title="Mealie",
|
||||
description="A place for all your recipes",
|
||||
|
@ -51,6 +38,10 @@ def start_scheduler():
|
|||
import services.scheduler.scheduled_jobs
|
||||
|
||||
|
||||
def init_settings():
|
||||
import services.theme_services
|
||||
|
||||
|
||||
def api_routers():
|
||||
# Recipes
|
||||
app.include_router(all_recipe_routes.router)
|
||||
|
@ -64,8 +55,6 @@ def api_routers():
|
|||
app.include_router(theme_routes.router)
|
||||
# Backups/Imports Routes
|
||||
app.include_router(backup_routes.router)
|
||||
# User Routes
|
||||
app.include_router(user_routes.router)
|
||||
# Migration Routes
|
||||
app.include_router(migration_routes.router)
|
||||
app.include_router(debug_routes.router)
|
||||
|
@ -90,6 +79,7 @@ app.include_router(static_routes.router)
|
|||
# generate_api_docs(app)
|
||||
|
||||
start_scheduler()
|
||||
init_settings()
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("-----SYSTEM STARTUP-----")
|
||||
|
|
|
@ -9,7 +9,6 @@ from db.sql.theme_models import SiteThemeModel
|
|||
"""
|
||||
# TODO
|
||||
- [ ] Abstract Classes to use save_new, and update from base models
|
||||
- [x] Create Category and Tags Table with Many to Many relationship
|
||||
"""
|
||||
|
||||
|
||||
|
@ -49,7 +48,7 @@ class _Settings(BaseDocument):
|
|||
self.primary_key = "name"
|
||||
self.sql_model = SiteSettingsModel
|
||||
|
||||
def save_new(self, session: Session, main: dict, webhooks: dict) -> str:
|
||||
def create(self, session: Session, main: dict, webhooks: dict) -> str:
|
||||
new_settings = self.sql_model(main.get("name"), webhooks)
|
||||
|
||||
session.add(new_settings)
|
||||
|
|
|
@ -106,7 +106,7 @@ class BaseDocument:
|
|||
|
||||
return db_entry
|
||||
|
||||
def save_new(self, session: Session, document: dict) -> dict:
|
||||
def create(self, session: Session, document: dict) -> dict:
|
||||
"""Creates a new database entry for the given SQL Alchemy Model.
|
||||
|
||||
Args: \n
|
||||
|
|
38
mealie/models/meal_models.py
Normal file
38
mealie/models/meal_models.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
from datetime import date
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Meal(BaseModel):
|
||||
slug: Optional[str]
|
||||
name: Optional[str]
|
||||
date: date
|
||||
dateText: str
|
||||
image: Optional[str]
|
||||
description: Optional[str]
|
||||
|
||||
|
||||
class MealData(BaseModel):
|
||||
name: Optional[str]
|
||||
slug: str
|
||||
dateText: str
|
||||
|
||||
|
||||
class MealPlan(BaseModel):
|
||||
uid: Optional[str]
|
||||
startDate: date
|
||||
endDate: date
|
||||
meals: List[Meal]
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"startDate": date.today(),
|
||||
"endDate": date.today(),
|
||||
"meals": [
|
||||
{"slug": "Packed Mac and Cheese", "date": date.today()},
|
||||
{"slug": "Eggs and Toast", "date": date.today()},
|
||||
],
|
||||
}
|
||||
}
|
|
@ -1,39 +1,80 @@
|
|||
from typing import List, Optional
|
||||
from pydantic.main import BaseModel
|
||||
import datetime
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
from slugify import slugify
|
||||
|
||||
|
||||
class RecipeNote(BaseModel):
|
||||
title: str
|
||||
text: str
|
||||
|
||||
|
||||
class RecipeStep(BaseModel):
|
||||
text: str
|
||||
|
||||
class AllRecipeResponse(BaseModel):
|
||||
|
||||
|
||||
class Recipe(BaseModel):
|
||||
# Standard Schema
|
||||
name: str
|
||||
description: Optional[str]
|
||||
image: Optional[Any]
|
||||
recipeYield: Optional[str]
|
||||
recipeIngredient: Optional[list]
|
||||
recipeInstructions: Optional[list]
|
||||
|
||||
totalTime: Optional[str] = None
|
||||
prepTime: Optional[str] = None
|
||||
performTime: Optional[str] = None
|
||||
|
||||
# Mealie Specific
|
||||
slug: Optional[str] = ""
|
||||
categories: Optional[List[str]] = []
|
||||
tags: Optional[List[str]] = []
|
||||
dateAdded: Optional[datetime.date]
|
||||
notes: Optional[List[RecipeNote]] = []
|
||||
rating: Optional[int]
|
||||
orgURL: Optional[str]
|
||||
extras: Optional[dict] = {}
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": [
|
||||
{
|
||||
"slug": "crockpot-buffalo-chicken",
|
||||
"image": "crockpot-buffalo-chicken.jpg",
|
||||
"name": "Crockpot Buffalo Chicken",
|
||||
},
|
||||
{
|
||||
"slug": "downtown-marinade",
|
||||
"image": "downtown-marinade.jpg",
|
||||
"name": "Downtown Marinade",
|
||||
},
|
||||
{
|
||||
"slug": "detroit-style-pepperoni-pizza",
|
||||
"image": "detroit-style-pepperoni-pizza.jpg",
|
||||
"name": "Detroit-Style Pepperoni Pizza",
|
||||
},
|
||||
{
|
||||
"slug": "crispy-carrots",
|
||||
"image": "crispy-carrots.jpg",
|
||||
"name": "Crispy Carrots",
|
||||
},
|
||||
]
|
||||
"example": {
|
||||
"name": "Chicken and Rice With Leeks and Salsa Verde",
|
||||
"description": "This one-skillet dinner gets deep oniony flavor from lots of leeks cooked down to jammy tenderness.",
|
||||
"image": "chicken-and-rice-with-leeks-and-salsa-verde.jpg",
|
||||
"recipeYield": "4 Servings",
|
||||
"recipeIngredient": [
|
||||
"1 1/2 lb. skinless, boneless chicken thighs (4-8 depending on size)",
|
||||
"Kosher salt, freshly ground pepper",
|
||||
"3 Tbsp. unsalted butter, divided",
|
||||
],
|
||||
"recipeInstructions": [
|
||||
{
|
||||
"text": "Season chicken with salt and pepper.",
|
||||
},
|
||||
],
|
||||
"slug": "chicken-and-rice-with-leeks-and-salsa-verde",
|
||||
"tags": ["favorite", "yummy!"],
|
||||
"categories": ["Dinner", "Pasta"],
|
||||
"notes": [{"title": "Watch Out!", "text": "Prep the day before!"}],
|
||||
"orgURL": "https://www.bonappetit.com/recipe/chicken-and-rice-with-leeks-and-salsa-verde",
|
||||
"rating": 3,
|
||||
"extras": {"message": "Don't forget to defrost the chicken!"},
|
||||
}
|
||||
}
|
||||
|
||||
@validator("slug", always=True, pre=True)
|
||||
def validate_slug(slug: str, values):
|
||||
name: str = values["name"]
|
||||
calc_slug: str = slugify(name)
|
||||
|
||||
if slug == calc_slug:
|
||||
return slug
|
||||
else:
|
||||
slug = calc_slug
|
||||
return slug
|
||||
|
||||
|
||||
class AllRecipeRequest(BaseModel):
|
||||
properties: List[str]
|
||||
|
|
26
mealie/models/settings_models.py
Normal file
26
mealie/models/settings_models.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Webhooks(BaseModel):
|
||||
webhookTime: str = "00:00"
|
||||
webhookURLs: Optional[List[str]] = []
|
||||
enabled: bool = False
|
||||
|
||||
|
||||
class SiteSettings(BaseModel):
|
||||
name: str = "main"
|
||||
webhooks: Webhooks
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "main",
|
||||
"webhooks": {
|
||||
"webhookTime": "00:00",
|
||||
"webhookURLs": ["https://mywebhookurl.com/webhook"],
|
||||
"enable": False,
|
||||
},
|
||||
}
|
||||
}
|
31
mealie/models/theme_models.py
Normal file
31
mealie/models/theme_models.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
class Colors(BaseModel):
|
||||
primary: str
|
||||
accent: str
|
||||
secondary: str
|
||||
success: str
|
||||
info: str
|
||||
warning: str
|
||||
error: str
|
||||
|
||||
|
||||
class SiteTheme(BaseModel):
|
||||
name: str
|
||||
colors: Colors
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "default",
|
||||
"colors": {
|
||||
"primary": "#E58325",
|
||||
"accent": "#00457A",
|
||||
"secondary": "#973542",
|
||||
"success": "#5AB1BB",
|
||||
"info": "#4990BA",
|
||||
"warning": "#FF4081",
|
||||
"error": "#EF5350",
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
username: str
|
||||
email: Optional[str] = None
|
||||
full_name: Optional[str] = None
|
||||
disabled: Optional[bool] = None
|
|
@ -1,6 +1,7 @@
|
|||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from services.settings_services import SiteSettings
|
||||
from models.settings_models import SiteSettings
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.post_webhooks import post_webhooks
|
||||
from utils.snackbar import SnackResponse
|
||||
|
@ -12,7 +13,7 @@ router = APIRouter(prefix="/api/site-settings", tags=["Settings"])
|
|||
def get_main_settings(session: Session = Depends(generate_session)):
|
||||
""" Returns basic site settings """
|
||||
|
||||
return SiteSettings.get_site_settings(session)
|
||||
return db.settings.get(session, "main")
|
||||
|
||||
|
||||
@router.post("/webhooks/test")
|
||||
|
@ -25,6 +26,6 @@ def test_webhooks():
|
|||
@router.put("")
|
||||
def update_settings(data: SiteSettings, session: Session = Depends(generate_session)):
|
||||
""" Returns Site Settings """
|
||||
data.update(session)
|
||||
db.settings.update(session, "main", data.dict())
|
||||
|
||||
return SnackResponse.success("Settings Updated")
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from services.settings_services import SiteTheme
|
||||
from models.theme_models import SiteTheme
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.snackbar import SnackResponse
|
||||
from db.database import db
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["Themes"])
|
||||
|
||||
|
@ -11,13 +12,13 @@ router = APIRouter(prefix="/api", tags=["Themes"])
|
|||
def get_all_themes(session: Session = Depends(generate_session)):
|
||||
""" Returns all site themes """
|
||||
|
||||
return SiteTheme.get_all(session)
|
||||
return db.themes.get_all(session)
|
||||
|
||||
|
||||
@router.post("/themes/create")
|
||||
def create_theme(data: SiteTheme, session: Session = Depends(generate_session)):
|
||||
""" Creates a site color theme database entry """
|
||||
data.save_to_db(session)
|
||||
db.themes.create(session, data.dict())
|
||||
|
||||
return SnackResponse.success("Theme Saved")
|
||||
|
||||
|
@ -25,7 +26,7 @@ def create_theme(data: SiteTheme, session: Session = Depends(generate_session)):
|
|||
@router.get("/themes/{theme_name}")
|
||||
def get_single_theme(theme_name: str, session: Session = Depends(generate_session)):
|
||||
""" Returns a named theme """
|
||||
return SiteTheme.get_by_name(session, theme_name)
|
||||
return db.themes.get(session, theme_name)
|
||||
|
||||
|
||||
@router.put("/themes/{theme_name}")
|
||||
|
@ -33,7 +34,7 @@ def update_theme(
|
|||
theme_name: str, data: SiteTheme, session: Session = Depends(generate_session)
|
||||
):
|
||||
""" Update a theme database entry """
|
||||
data.update_document(session)
|
||||
db.themes.update(session, theme_name, data.dict())
|
||||
|
||||
return SnackResponse.info(f"Theme Updated: {theme_name}")
|
||||
|
||||
|
@ -41,6 +42,6 @@ def update_theme(
|
|||
@router.delete("/themes/{theme_name}")
|
||||
def delete_theme(theme_name: str, session: Session = Depends(generate_session)):
|
||||
""" Deletes theme from the database """
|
||||
SiteTheme.delete_theme(session, theme_name)
|
||||
db.themes.delete(session, theme_name)
|
||||
|
||||
return SnackResponse.error(f"Theme Deleted: {theme_name}")
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
|
||||
# from fastapi_login import LoginManager
|
||||
# from fastapi_login.exceptions import InvalidCredentialsException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# SECRET = "876cfb59db03d9c17cefec967b00255d3f7d93a823e5dc2a"
|
||||
# manager = LoginManager(SECRET, tokenUrl="/api/auth/token")
|
||||
|
||||
# fake_db = {"johndoe@e.mail": {"password": "hunter2"}}
|
||||
|
||||
|
||||
# @manager.user_loader
|
||||
# def load_user(email: str): # could also be an asynchronous function
|
||||
# user = fake_db.get(email)
|
||||
# return user
|
||||
|
||||
|
||||
# @router.post("/api/auth/token", tags=["User Gen"])
|
||||
# def login(data: OAuth2PasswordRequestForm = Depends()):
|
||||
# email = data.username
|
||||
# password = data.password
|
||||
|
||||
# user = load_user(email) # we are using the same function to retrieve the user
|
||||
# if not user:
|
||||
# raise InvalidCredentialsException # you can also use your own HTTPException
|
||||
# elif password != user["password"]:
|
||||
# raise InvalidCredentialsException
|
||||
|
||||
# access_token = manager.create_access_token(data=dict(sub=email))
|
||||
# return {"access_token": access_token, "token_type": "bearer"}
|
|
@ -4,11 +4,11 @@ from datetime import datetime
|
|||
from pathlib import Path
|
||||
|
||||
from app_config import BACKUP_DIR, IMG_DIR, TEMP_DIR, TEMPLATE_DIR
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from jinja2 import Template
|
||||
from services.meal_services import MealPlan
|
||||
from services.recipe_services import Recipe
|
||||
from services.settings_services import SiteSettings, SiteTheme
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
|
@ -88,20 +88,18 @@ class ExportDatabase:
|
|||
shutil.copy(file, self.img_dir.joinpath(file.name))
|
||||
|
||||
def export_settings(self):
|
||||
all_settings = SiteSettings.get_site_settings(self.session)
|
||||
all_settings = db.settings.get(self.session, "main")
|
||||
out_file = self.settings_dir.joinpath("settings.json")
|
||||
ExportDatabase._write_json_file(all_settings.dict(), out_file)
|
||||
ExportDatabase._write_json_file(all_settings, out_file)
|
||||
|
||||
def export_themes(self):
|
||||
all_themes = SiteTheme.get_all(self.session)
|
||||
all_themes = db.themes.get_all(self.session)
|
||||
if all_themes:
|
||||
all_themes = [x.dict() for x in all_themes]
|
||||
out_file = self.themes_dir.joinpath("themes.json")
|
||||
ExportDatabase._write_json_file(all_themes, out_file)
|
||||
|
||||
def export_meals(
|
||||
self,
|
||||
): #! Problem Parseing Datetime Objects... May come back to this
|
||||
def export_meals(self):
|
||||
#! Problem Parseing Datetime Objects... May come back to this
|
||||
meal_plans = MealPlan.get_all(self.session)
|
||||
if meal_plans:
|
||||
meal_plans = [x.dict() for x in meal_plans]
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import json
|
||||
import shutil
|
||||
import zipfile
|
||||
from logging import error
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from app_config import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
||||
from db.database import db
|
||||
from models.theme_models import SiteTheme
|
||||
from services.recipe_services import Recipe
|
||||
from services.settings_services import SiteSettings, SiteTheme
|
||||
from services.settings_services import SiteSettings
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.logger import logger
|
||||
|
||||
|
@ -54,6 +57,7 @@ class ImportDatabase:
|
|||
raise Exception("Import file does not exist")
|
||||
|
||||
def run(self):
|
||||
report = {}
|
||||
if self.imp_recipes:
|
||||
report = self.import_recipes()
|
||||
if self.imp_settings:
|
||||
|
@ -128,11 +132,13 @@ class ImportDatabase:
|
|||
themes_file = self.import_dir.joinpath("themes", "themes.json")
|
||||
|
||||
with open(themes_file, "r") as f:
|
||||
themes: list = json.loads(f.read())
|
||||
themes: list[dict] = json.loads(f.read())
|
||||
for theme in themes:
|
||||
if theme.get("name") == "default":
|
||||
continue
|
||||
new_theme = SiteTheme(**theme)
|
||||
try:
|
||||
new_theme.save_to_db(self.session)
|
||||
db.themes.create(self.session, new_theme.dict())
|
||||
except:
|
||||
logger.info(f"Unable Import Theme {new_theme.name}")
|
||||
|
||||
|
@ -142,9 +148,7 @@ class ImportDatabase:
|
|||
with open(settings_file, "r") as f:
|
||||
settings: dict = json.loads(f.read())
|
||||
|
||||
settings = SiteSettings(**settings)
|
||||
|
||||
settings.update(self.session)
|
||||
db.settings.update(self.session, settings)
|
||||
|
||||
def clean_up(self):
|
||||
shutil.rmtree(TEMP_DIR)
|
||||
|
|
|
@ -8,19 +8,6 @@ from sqlalchemy.orm.session import Session
|
|||
|
||||
from services.recipe_services import Recipe
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
THIS_WEEK = CWD.parent.joinpath("data", "meal_plan", "this_week.json")
|
||||
NEXT_WEEK = CWD.parent.joinpath("data", "meal_plan", "next_week.json")
|
||||
WEEKDAYS = [
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
"sunday",
|
||||
]
|
||||
|
||||
|
||||
class Meal(BaseModel):
|
||||
slug: Optional[str]
|
||||
|
@ -81,7 +68,7 @@ class MealPlan(BaseModel):
|
|||
self.meals = meals
|
||||
|
||||
def save_to_db(self, session: Session):
|
||||
db.meals.save_new(session, self.dict())
|
||||
db.meals.create(session, self.dict())
|
||||
|
||||
@staticmethod
|
||||
def get_all(session: Session) -> List:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import datetime
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, List, Optional
|
||||
|
||||
|
@ -98,7 +97,7 @@ class Recipe(BaseModel):
|
|||
except:
|
||||
recipe_dict["image"] = "no image"
|
||||
|
||||
recipe_doc = db.recipes.save_new(session, recipe_dict)
|
||||
recipe_doc = db.recipes.create(session, recipe_dict)
|
||||
recipe = Recipe(**recipe_doc)
|
||||
|
||||
return recipe.slug
|
||||
|
|
|
@ -3,8 +3,9 @@ from db.db_setup import create_session
|
|||
from services.backups.exports import auto_backup_job
|
||||
from services.scheduler.global_scheduler import scheduler
|
||||
from services.scheduler.scheduler_utils import Cron, cron_parser
|
||||
from services.settings_services import SiteSettings
|
||||
from utils.logger import logger
|
||||
from models.settings_models import SiteSettings
|
||||
from db.database import db
|
||||
from utils.post_webhooks import post_webhooks
|
||||
|
||||
|
||||
|
@ -15,7 +16,8 @@ def update_webhook_schedule():
|
|||
poll the database for changes and reschedule the webhook time
|
||||
"""
|
||||
session = create_session()
|
||||
settings = SiteSettings.get_site_settings(session=session)
|
||||
settings = db.settings.get(session, "main")
|
||||
settings = SiteSettings(**settings)
|
||||
time = cron_parser(settings.webhooks.webhookTime)
|
||||
job = JOB_STORE.get("webhooks")
|
||||
|
||||
|
|
|
@ -1,135 +1,6 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from db.database import db
|
||||
from db.db_setup import create_session, sql_exists
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
class Webhooks(BaseModel):
|
||||
webhookTime: str = "00:00"
|
||||
webhookURLs: Optional[List[str]] = []
|
||||
enabled: bool = False
|
||||
|
||||
|
||||
class SiteSettings(BaseModel):
|
||||
name: str = "main"
|
||||
webhooks: Webhooks
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "main",
|
||||
"webhooks": {
|
||||
"webhookTime": "00:00",
|
||||
"webhookURLs": ["https://mywebhookurl.com/webhook"],
|
||||
"enable": False,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_all(session: Session):
|
||||
db.settings.get_all(session)
|
||||
|
||||
@classmethod
|
||||
def get_site_settings(cls, session: Session):
|
||||
try:
|
||||
document = db.settings.get(session=session, match_value="main")
|
||||
except:
|
||||
webhooks = Webhooks()
|
||||
default_entry = SiteSettings(name="main", webhooks=webhooks)
|
||||
document = db.settings.save_new(
|
||||
session, default_entry.dict(), webhooks.dict()
|
||||
)
|
||||
|
||||
return cls(**document)
|
||||
|
||||
def update(self, session: Session):
|
||||
db.settings.update(session, "main", new_data=self.dict())
|
||||
|
||||
|
||||
class Colors(BaseModel):
|
||||
primary: str
|
||||
accent: str
|
||||
secondary: str
|
||||
success: str
|
||||
info: str
|
||||
warning: str
|
||||
error: str
|
||||
|
||||
|
||||
class SiteTheme(BaseModel):
|
||||
name: str
|
||||
colors: Colors
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "default",
|
||||
"colors": {
|
||||
"primary": "#E58325",
|
||||
"accent": "#00457A",
|
||||
"secondary": "#973542",
|
||||
"success": "#5AB1BB",
|
||||
"info": "#4990BA",
|
||||
"warning": "#FF4081",
|
||||
"error": "#EF5350",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_by_name(cls, session: Session, theme_name):
|
||||
db_entry = db.themes.get(session, theme_name)
|
||||
name = db_entry.get("name")
|
||||
colors = Colors(**db_entry.get("colors"))
|
||||
|
||||
return cls(name=name, colors=colors)
|
||||
|
||||
@staticmethod
|
||||
def get_all(session: Session):
|
||||
all_themes = db.themes.get_all(session)
|
||||
for index, theme in enumerate(all_themes):
|
||||
name = theme.get("name")
|
||||
colors = Colors(**theme.get("colors"))
|
||||
|
||||
all_themes[index] = SiteTheme(name=name, colors=colors)
|
||||
|
||||
return all_themes
|
||||
|
||||
def save_to_db(self, session: Session):
|
||||
db.themes.save_new(session, self.dict())
|
||||
|
||||
def update_document(self, session: Session):
|
||||
db.themes.update(session, self.name, self.dict())
|
||||
|
||||
@staticmethod
|
||||
def delete_theme(session: Session, theme_name: str) -> str:
|
||||
""" Removes the theme by name """
|
||||
db.themes.delete(session, theme_name)
|
||||
|
||||
|
||||
def default_theme_init():
|
||||
default_colors = {
|
||||
"primary": "#E58325",
|
||||
"accent": "#00457A",
|
||||
"secondary": "#973542",
|
||||
"success": "#5AB1BB",
|
||||
"info": "#4990BA",
|
||||
"warning": "#FF4081",
|
||||
"error": "#EF5350",
|
||||
}
|
||||
session = create_session()
|
||||
try:
|
||||
SiteTheme.get_by_name(session, "default")
|
||||
logger.info("Default theme exists... skipping generation")
|
||||
except:
|
||||
logger.info("Generating Default Theme")
|
||||
colors = Colors(**default_colors)
|
||||
default_theme = SiteTheme(name="default", colors=colors)
|
||||
default_theme.save_to_db(session)
|
||||
from models.settings_models import SiteSettings, Webhooks
|
||||
|
||||
|
||||
def default_settings_init():
|
||||
|
@ -139,11 +10,10 @@ def default_settings_init():
|
|||
except:
|
||||
webhooks = Webhooks()
|
||||
default_entry = SiteSettings(name="main", webhooks=webhooks)
|
||||
document = db.settings.save_new(session, default_entry.dict(), webhooks.dict())
|
||||
document = db.settings.create(session, default_entry.dict(), webhooks.dict())
|
||||
|
||||
session.close()
|
||||
|
||||
|
||||
if not sql_exists:
|
||||
default_settings_init()
|
||||
default_theme_init()
|
||||
|
|
28
mealie/services/theme_services.py
Normal file
28
mealie/services/theme_services.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from db.database import db
|
||||
from db.db_setup import create_session, sql_exists
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
def default_theme_init():
|
||||
default_theme = {
|
||||
"name": "default",
|
||||
"colors": {
|
||||
"primary": "#E58325",
|
||||
"accent": "#00457A",
|
||||
"secondary": "#973542",
|
||||
"success": "#5AB1BB",
|
||||
"info": "#4990BA",
|
||||
"warning": "#FF4081",
|
||||
"error": "#EF5350",
|
||||
},
|
||||
}
|
||||
session = create_session()
|
||||
try:
|
||||
db.themes.create(session, default_theme)
|
||||
logger.info("Generating default theme...")
|
||||
except:
|
||||
logger.info("Default Theme Exists.. skipping generation")
|
||||
|
||||
|
||||
if not sql_exists:
|
||||
default_theme_init()
|
|
@ -1,15 +1,17 @@
|
|||
import json
|
||||
|
||||
import requests
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from models.settings_models import SiteSettings
|
||||
from services.meal_services import MealPlan
|
||||
from services.recipe_services import Recipe
|
||||
from services.settings_services import SiteSettings
|
||||
|
||||
|
||||
def post_webhooks():
|
||||
session = create_session()
|
||||
all_settings = SiteSettings.get_site_settings(session)
|
||||
all_settings = db.get(session, "main")
|
||||
all_settings = SiteSettings(**all_settings)
|
||||
|
||||
if all_settings.webhooks.enabled:
|
||||
todays_meal = Recipe.get_by_slug(MealPlan.today()).dict()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue