mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 06:23:34 -07:00
settings and theme import logic
This commit is contained in:
parent
da2a3d2d32
commit
db29b08c96
10 changed files with 59 additions and 42 deletions
|
@ -29,6 +29,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
async create(tag, template) {
|
async create(tag, template) {
|
||||||
|
if (typeof template == String) {
|
||||||
|
template = [template];
|
||||||
|
}
|
||||||
|
console.log(tag, template);
|
||||||
let response = apiReq.post(backupURLs.createBackup, {
|
let response = apiReq.post(backupURLs.createBackup, {
|
||||||
tag: tag,
|
tag: tag,
|
||||||
template: template,
|
template: template,
|
||||||
|
|
|
@ -121,9 +121,7 @@ export default {
|
||||||
async createBackup() {
|
async createBackup() {
|
||||||
this.backupLoading = true;
|
this.backupLoading = true;
|
||||||
|
|
||||||
let response = await api.backups.create(this.backupTag, [
|
let response = await api.backups.create(this.backupTag, this.templates);
|
||||||
this.selectedTemplate,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (response.status == 201) {
|
if (response.status == 201) {
|
||||||
this.selectedBackup = null;
|
this.selectedBackup = null;
|
||||||
|
|
Binary file not shown.
|
@ -9,7 +9,7 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/backups/available/", tags=["Import / Export"], response_model=Imports)
|
@router.get("/api/backups/available/", tags=["Import / Export"], response_model=Imports)
|
||||||
async def available_imports():
|
def available_imports():
|
||||||
"""Returns a list of avaiable .zip files for import into Mealie."""
|
"""Returns a list of avaiable .zip files for import into Mealie."""
|
||||||
imports = []
|
imports = []
|
||||||
templates = []
|
templates = []
|
||||||
|
@ -23,7 +23,7 @@ async def available_imports():
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/backups/export/database/", tags=["Import / Export"], status_code=201)
|
@router.post("/api/backups/export/database/", tags=["Import / Export"], status_code=201)
|
||||||
async def export_database(data: BackupJob):
|
def export_database(data: BackupJob):
|
||||||
"""Generates a backup of the recipe database in json format."""
|
"""Generates a backup of the recipe database in json format."""
|
||||||
export_path = backup_all(data.tag, data.template)
|
export_path = backup_all(data.tag, data.template)
|
||||||
try:
|
try:
|
||||||
|
@ -38,13 +38,13 @@ async def export_database(data: BackupJob):
|
||||||
@router.post(
|
@router.post(
|
||||||
"/api/backups/{file_name}/import/", tags=["Import / Export"], status_code=200
|
"/api/backups/{file_name}/import/", tags=["Import / Export"], status_code=200
|
||||||
)
|
)
|
||||||
async def import_database(file_name: str):
|
def import_database(file_name: str):
|
||||||
""" Import a database backup file generated from Mealie. """
|
""" Import a database backup file generated from Mealie. """
|
||||||
import_db = ImportDatabase(
|
import_db = ImportDatabase(
|
||||||
zip_archive=file_name,
|
zip_archive=file_name,
|
||||||
import_recipes=True,
|
import_recipes=True,
|
||||||
import_settings=False,
|
import_settings=True,
|
||||||
import_themes=False,
|
import_themes=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
imported = import_db.run()
|
imported = import_db.run()
|
||||||
|
@ -56,7 +56,7 @@ async def import_database(file_name: str):
|
||||||
tags=["Import / Export"],
|
tags=["Import / Export"],
|
||||||
status_code=200,
|
status_code=200,
|
||||||
)
|
)
|
||||||
async def delete_backup(backup_name: str):
|
def delete_backup(backup_name: str):
|
||||||
""" Removes a database backup from the file system """
|
""" Removes a database backup from the file system """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -9,14 +9,14 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/meal-plan/all/", tags=["Meal Plan"], response_model=List[MealPlan])
|
@router.get("/api/meal-plan/all/", tags=["Meal Plan"], response_model=List[MealPlan])
|
||||||
async def get_all_meals():
|
def get_all_meals():
|
||||||
""" Returns a list of all available Meal Plan """
|
""" Returns a list of all available Meal Plan """
|
||||||
|
|
||||||
return MealPlan.get_all()
|
return MealPlan.get_all()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/meal-plan/create/", tags=["Meal Plan"])
|
@router.post("/api/meal-plan/create/", tags=["Meal Plan"])
|
||||||
async def set_meal_plan(data: MealPlan):
|
def set_meal_plan(data: MealPlan):
|
||||||
""" Creates a meal plan database entry """
|
""" Creates a meal plan database entry """
|
||||||
data.process_meals()
|
data.process_meals()
|
||||||
data.save_to_db()
|
data.save_to_db()
|
||||||
|
@ -30,7 +30,7 @@ async def set_meal_plan(data: MealPlan):
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/meal-plan/{plan_id}/update/", tags=["Meal Plan"])
|
@router.post("/api/meal-plan/{plan_id}/update/", tags=["Meal Plan"])
|
||||||
async def update_meal_plan(plan_id: str, meal_plan: MealPlan):
|
def update_meal_plan(plan_id: str, meal_plan: MealPlan):
|
||||||
""" Updates a meal plan based off ID """
|
""" Updates a meal plan based off ID """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -46,7 +46,7 @@ async def update_meal_plan(plan_id: str, meal_plan: MealPlan):
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/meal-plan/{plan_id}/delete/", tags=["Meal Plan"])
|
@router.delete("/api/meal-plan/{plan_id}/delete/", tags=["Meal Plan"])
|
||||||
async def delete_meal_plan(plan_id):
|
def delete_meal_plan(plan_id):
|
||||||
""" Removes a meal plan from the database """
|
""" Removes a meal plan from the database """
|
||||||
|
|
||||||
MealPlan.delete(plan_id)
|
MealPlan.delete(plan_id)
|
||||||
|
@ -58,7 +58,7 @@ async def delete_meal_plan(plan_id):
|
||||||
"/api/meal-plan/today/",
|
"/api/meal-plan/today/",
|
||||||
tags=["Meal Plan"],
|
tags=["Meal Plan"],
|
||||||
)
|
)
|
||||||
async def get_today():
|
def get_today():
|
||||||
"""
|
"""
|
||||||
Returns the recipe slug for the meal scheduled for today.
|
Returns the recipe slug for the meal scheduled for today.
|
||||||
If no meal is scheduled nothing is returned
|
If no meal is scheduled nothing is returned
|
||||||
|
@ -68,7 +68,7 @@ async def get_today():
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/meal-plan/this-week/", tags=["Meal Plan"], response_model=MealPlan)
|
@router.get("/api/meal-plan/this-week/", tags=["Meal Plan"], response_model=MealPlan)
|
||||||
async def get_this_week():
|
def get_this_week():
|
||||||
""" Returns the meal plan data for this week """
|
""" Returns the meal plan data for this week """
|
||||||
|
|
||||||
return MealPlan.this_week()
|
return MealPlan.this_week()
|
||||||
|
|
|
@ -12,7 +12,7 @@ router = APIRouter()
|
||||||
|
|
||||||
# Chowdown
|
# Chowdown
|
||||||
@router.post("/api/migration/chowdown/repo/", tags=["Migration"])
|
@router.post("/api/migration/chowdown/repo/", tags=["Migration"])
|
||||||
async def import_chowdown_recipes(repo: ChowdownURL):
|
def import_chowdown_recipes(repo: ChowdownURL):
|
||||||
""" Import Chowsdown Recipes from Repo URL """
|
""" Import Chowsdown Recipes from Repo URL """
|
||||||
try:
|
try:
|
||||||
report = chowdow_migrate(repo.url)
|
report = chowdow_migrate(repo.url)
|
||||||
|
@ -31,7 +31,7 @@ async def import_chowdown_recipes(repo: ChowdownURL):
|
||||||
|
|
||||||
# Nextcloud
|
# Nextcloud
|
||||||
@router.get("/api/migration/nextcloud/available/", tags=["Migration"])
|
@router.get("/api/migration/nextcloud/available/", tags=["Migration"])
|
||||||
async def get_avaiable_nextcloud_imports():
|
def get_avaiable_nextcloud_imports():
|
||||||
""" Returns a list of avaiable directories that can be imported into Mealie """
|
""" Returns a list of avaiable directories that can be imported into Mealie """
|
||||||
available = []
|
available = []
|
||||||
for dir in MIGRATION_DIR.iterdir():
|
for dir in MIGRATION_DIR.iterdir():
|
||||||
|
@ -44,14 +44,14 @@ async def get_avaiable_nextcloud_imports():
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/migration/nextcloud/{selection}/import/", tags=["Migration"])
|
@router.post("/api/migration/nextcloud/{selection}/import/", tags=["Migration"])
|
||||||
async def import_nextcloud_directory(selection: str):
|
def import_nextcloud_directory(selection: str):
|
||||||
""" Imports all the recipes in a given directory """
|
""" Imports all the recipes in a given directory """
|
||||||
|
|
||||||
return nextcloud_migrate(selection)
|
return nextcloud_migrate(selection)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/migration/{file_folder_name}/delete/", tags=["Migration"])
|
@router.delete("/api/migration/{file_folder_name}/delete/", tags=["Migration"])
|
||||||
async def delete_migration_data(file_folder_name: str):
|
def delete_migration_data(file_folder_name: str):
|
||||||
""" Removes migration data from the file system """
|
""" Removes migration data from the file system """
|
||||||
|
|
||||||
remove_path = MIGRATION_DIR.joinpath(file_folder_name)
|
remove_path = MIGRATION_DIR.joinpath(file_folder_name)
|
||||||
|
@ -67,7 +67,7 @@ async def delete_migration_data(file_folder_name: str):
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/migration/upload/", tags=["Migration"])
|
@router.post("/api/migration/upload/", tags=["Migration"])
|
||||||
async def upload_nextcloud_zipfile(archive: UploadFile = File(...)):
|
def upload_nextcloud_zipfile(archive: UploadFile = File(...)):
|
||||||
""" Upload a .zip File to later be imported into Mealie """
|
""" Upload a .zip File to later be imported into Mealie """
|
||||||
dest = MIGRATION_DIR.joinpath(archive.filename)
|
dest = MIGRATION_DIR.joinpath(archive.filename)
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,7 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/all-recipes/", tags=["Recipes"], response_model=List[dict])
|
@router.get("/api/all-recipes/", tags=["Recipes"], response_model=List[dict])
|
||||||
async def get_all_recipes(
|
def get_all_recipes(keys: Optional[List[str]] = Query(...), num: Optional[int] = 100):
|
||||||
keys: Optional[List[str]] = Query(...), num: Optional[int] = 100
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Returns key data for all recipes based off the query paramters provided.
|
Returns key data for all recipes based off the query paramters provided.
|
||||||
For example, if slug, image, and name are provided you will recieve a list of
|
For example, if slug, image, and name are provided you will recieve a list of
|
||||||
|
@ -31,7 +29,7 @@ async def get_all_recipes(
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/all-recipes/", tags=["Recipes"], response_model=List[dict])
|
@router.post("/api/all-recipes/", tags=["Recipes"], response_model=List[dict])
|
||||||
async def get_all_recipes_post(body: AllRecipeRequest):
|
def get_all_recipes_post(body: AllRecipeRequest):
|
||||||
"""
|
"""
|
||||||
Returns key data for all recipes based off the body data provided.
|
Returns key data for all recipes based off the body data provided.
|
||||||
For example, if slug, image, and name are provided you will recieve a list of
|
For example, if slug, image, and name are provided you will recieve a list of
|
||||||
|
@ -47,7 +45,7 @@ async def get_all_recipes_post(body: AllRecipeRequest):
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/recipe/{recipe_slug}/", tags=["Recipes"], response_model=Recipe)
|
@router.get("/api/recipe/{recipe_slug}/", tags=["Recipes"], response_model=Recipe)
|
||||||
async def get_recipe(recipe_slug: str):
|
def get_recipe(recipe_slug: str):
|
||||||
""" Takes in a recipe slug, returns all data for a recipe """
|
""" Takes in a recipe slug, returns all data for a recipe """
|
||||||
recipe = Recipe.get_by_slug(recipe_slug)
|
recipe = Recipe.get_by_slug(recipe_slug)
|
||||||
|
|
||||||
|
@ -55,7 +53,7 @@ async def get_recipe(recipe_slug: str):
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/recipe/image/{recipe_slug}/", tags=["Recipes"])
|
@router.get("/api/recipe/image/{recipe_slug}/", tags=["Recipes"])
|
||||||
async def get_recipe_img(recipe_slug: str):
|
def get_recipe_img(recipe_slug: str):
|
||||||
""" Takes in a recipe slug, returns the static image """
|
""" Takes in a recipe slug, returns the static image """
|
||||||
recipe_image = read_image(recipe_slug)
|
recipe_image = read_image(recipe_slug)
|
||||||
|
|
||||||
|
@ -69,7 +67,7 @@ async def get_recipe_img(recipe_slug: str):
|
||||||
status_code=201,
|
status_code=201,
|
||||||
response_model=str,
|
response_model=str,
|
||||||
)
|
)
|
||||||
async def parse_recipe_url(url: RecipeURLIn):
|
def parse_recipe_url(url: RecipeURLIn):
|
||||||
""" Takes in a URL and attempts to scrape data and load it into the database """
|
""" Takes in a URL and attempts to scrape data and load it into the database """
|
||||||
|
|
||||||
slug = create_from_url(url.url)
|
slug = create_from_url(url.url)
|
||||||
|
@ -78,7 +76,7 @@ async def parse_recipe_url(url: RecipeURLIn):
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/recipe/create/", tags=["Recipes"])
|
@router.post("/api/recipe/create/", tags=["Recipes"])
|
||||||
async def create_from_json(data: Recipe) -> str:
|
def create_from_json(data: Recipe) -> str:
|
||||||
""" Takes in a JSON string and loads data into the database as a new entry"""
|
""" Takes in a JSON string and loads data into the database as a new entry"""
|
||||||
created_recipe = data.save_to_db()
|
created_recipe = data.save_to_db()
|
||||||
|
|
||||||
|
@ -97,7 +95,7 @@ def update_recipe_image(
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/recipe/{recipe_slug}/update/", tags=["Recipes"])
|
@router.post("/api/recipe/{recipe_slug}/update/", tags=["Recipes"])
|
||||||
async def update_recipe(recipe_slug: str, data: Recipe):
|
def update_recipe(recipe_slug: str, data: Recipe):
|
||||||
""" Updates a recipe by existing slug and data. """
|
""" Updates a recipe by existing slug and data. """
|
||||||
|
|
||||||
new_slug = data.update(recipe_slug)
|
new_slug = data.update(recipe_slug)
|
||||||
|
@ -106,7 +104,7 @@ async def update_recipe(recipe_slug: str, data: Recipe):
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/recipe/{recipe_slug}/delete/", tags=["Recipes"])
|
@router.delete("/api/recipe/{recipe_slug}/delete/", tags=["Recipes"])
|
||||||
async def delete_recipe(recipe_slug: str):
|
def delete_recipe(recipe_slug: str):
|
||||||
""" Deletes a recipe by slug """
|
""" Deletes a recipe by slug """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -8,21 +8,21 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/site-settings/", tags=["Settings"])
|
@router.get("/api/site-settings/", tags=["Settings"])
|
||||||
async def get_main_settings():
|
def get_main_settings():
|
||||||
""" Returns basic site settings """
|
""" Returns basic site settings """
|
||||||
|
|
||||||
return SiteSettings.get_site_settings()
|
return SiteSettings.get_site_settings()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/site-settings/webhooks/test/", tags=["Settings"])
|
@router.post("/api/site-settings/webhooks/test/", tags=["Settings"])
|
||||||
async def test_webhooks():
|
def test_webhooks():
|
||||||
""" Run the function to test your webhooks """
|
""" Run the function to test your webhooks """
|
||||||
|
|
||||||
return post_webhooks()
|
return post_webhooks()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/site-settings/update/", tags=["Settings"])
|
@router.post("/api/site-settings/update/", tags=["Settings"])
|
||||||
async def update_settings(data: SiteSettings):
|
def update_settings(data: SiteSettings):
|
||||||
""" Returns Site Settings """
|
""" Returns Site Settings """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -37,20 +37,20 @@ async def update_settings(data: SiteSettings):
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/site-settings/themes/", tags=["Themes"])
|
@router.get("/api/site-settings/themes/", tags=["Themes"])
|
||||||
async def get_all_themes():
|
def get_all_themes():
|
||||||
""" Returns all site themes """
|
""" Returns all site themes """
|
||||||
|
|
||||||
return SiteTheme.get_all()
|
return SiteTheme.get_all()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/site-settings/themes/{theme_name}/", tags=["Themes"])
|
@router.get("/api/site-settings/themes/{theme_name}/", tags=["Themes"])
|
||||||
async def get_single_theme(theme_name: str):
|
def get_single_theme(theme_name: str):
|
||||||
""" Returns a named theme """
|
""" Returns a named theme """
|
||||||
return SiteTheme.get_by_name(theme_name)
|
return SiteTheme.get_by_name(theme_name)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/site-settings/themes/create/", tags=["Themes"])
|
@router.post("/api/site-settings/themes/create/", tags=["Themes"])
|
||||||
async def create_theme(data: SiteTheme):
|
def create_theme(data: SiteTheme):
|
||||||
""" Creates a site color theme database entry """
|
""" Creates a site color theme database entry """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -64,7 +64,7 @@ async def create_theme(data: SiteTheme):
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/site-settings/themes/{theme_name}/update/", tags=["Themes"])
|
@router.post("/api/site-settings/themes/{theme_name}/update/", tags=["Themes"])
|
||||||
async def update_theme(theme_name: str, data: SiteTheme):
|
def update_theme(theme_name: str, data: SiteTheme):
|
||||||
""" Update a theme database entry """
|
""" Update a theme database entry """
|
||||||
try:
|
try:
|
||||||
data.update_document()
|
data.update_document()
|
||||||
|
@ -77,7 +77,7 @@ async def update_theme(theme_name: str, data: SiteTheme):
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/site-settings/themes/{theme_name}/delete/", tags=["Themes"])
|
@router.delete("/api/site-settings/themes/{theme_name}/delete/", tags=["Themes"])
|
||||||
async def delete_theme(theme_name: str):
|
def delete_theme(theme_name: str):
|
||||||
""" Deletes theme from the database """
|
""" Deletes theme from the database """
|
||||||
try:
|
try:
|
||||||
SiteTheme.delete_theme(theme_name)
|
SiteTheme.delete_theme(theme_name)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from services.recipe_services import Recipe
|
from services.recipe_services import Recipe
|
||||||
|
from services.settings_services import SiteSettings, SiteTheme
|
||||||
from settings import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
from settings import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
||||||
from utils.logger import logger
|
from utils.logger import logger
|
||||||
|
|
||||||
|
@ -107,10 +108,26 @@ class ImportDatabase:
|
||||||
shutil.copy(image, IMG_DIR)
|
shutil.copy(image, IMG_DIR)
|
||||||
|
|
||||||
def import_themes(self):
|
def import_themes(self):
|
||||||
pass
|
themes_file = self.import_dir.joinpath("themes", "themes.json")
|
||||||
|
|
||||||
|
with open(themes_file, "r") as f:
|
||||||
|
themes: list = json.loads(f.read())
|
||||||
|
for theme in themes:
|
||||||
|
new_theme = SiteTheme(**theme)
|
||||||
|
try:
|
||||||
|
new_theme.save_to_db()
|
||||||
|
except:
|
||||||
|
logger.info(f"Unable Import Theme {new_theme.name}")
|
||||||
|
|
||||||
def import_settings(self):
|
def import_settings(self):
|
||||||
pass
|
settings_file = self.import_dir.joinpath("settings", "settings.json")
|
||||||
|
|
||||||
|
with open(settings_file, "r") as f:
|
||||||
|
settings: dict = json.loads(f.read())
|
||||||
|
|
||||||
|
settings = SiteSettings(**settings)
|
||||||
|
|
||||||
|
settings.update()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
shutil.rmtree(TEMP_DIR)
|
shutil.rmtree(TEMP_DIR)
|
||||||
|
|
|
@ -2,13 +2,13 @@ import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from fastapi.responses import FileResponse
|
from unsync import unsync
|
||||||
|
|
||||||
CWD = Path(__file__).parent
|
CWD = Path(__file__).parent
|
||||||
IMG_DIR = CWD.parent.joinpath("data", "img")
|
IMG_DIR = CWD.parent.joinpath("data", "img")
|
||||||
|
|
||||||
|
|
||||||
def read_image(recipe_slug: str) -> FileResponse:
|
def read_image(recipe_slug: str) -> Path:
|
||||||
if IMG_DIR.joinpath(recipe_slug).is_file():
|
if IMG_DIR.joinpath(recipe_slug).is_file():
|
||||||
return IMG_DIR.joinpath(recipe_slug)
|
return IMG_DIR.joinpath(recipe_slug)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue