settings and theme import logic

This commit is contained in:
Hayden 2021-01-12 15:45:29 -09:00
commit db29b08c96
10 changed files with 59 additions and 42 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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:

View file

@ -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()

View file

@ -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)

View file

@ -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:

View file

@ -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)

View file

@ -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)

View file

@ -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: