diff --git a/frontend/src/api/backup.js b/frontend/src/api/backup.js index 1ec026a83..1957b2b16 100644 --- a/frontend/src/api/backup.js +++ b/frontend/src/api/backup.js @@ -29,6 +29,10 @@ export default { }, async create(tag, template) { + if (typeof template == String) { + template = [template]; + } + console.log(tag, template); let response = apiReq.post(backupURLs.createBackup, { tag: tag, template: template, diff --git a/frontend/src/components/Settings/Backup/index.vue b/frontend/src/components/Settings/Backup/index.vue index c6a4777df..b609d2c80 100644 --- a/frontend/src/components/Settings/Backup/index.vue +++ b/frontend/src/components/Settings/Backup/index.vue @@ -121,9 +121,7 @@ export default { async createBackup() { this.backupLoading = true; - let response = await api.backups.create(this.backupTag, [ - this.selectedTemplate, - ]); + let response = await api.backups.create(this.backupTag, this.templates); if (response.status == 201) { this.selectedBackup = null; diff --git a/mealie/data/backups/dev_sample_data_2021-Jan-03.zip b/mealie/data/backups/dev_sample_data_2021-Jan-03.zip deleted file mode 100644 index 46c254e26..000000000 Binary files a/mealie/data/backups/dev_sample_data_2021-Jan-03.zip and /dev/null differ diff --git a/mealie/routes/backup_routes.py b/mealie/routes/backup_routes.py index bfa732e1f..2dfa2b520 100644 --- a/mealie/routes/backup_routes.py +++ b/mealie/routes/backup_routes.py @@ -9,7 +9,7 @@ router = APIRouter() @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.""" imports = [] templates = [] @@ -23,7 +23,7 @@ async def available_imports(): @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.""" export_path = backup_all(data.tag, data.template) try: @@ -38,13 +38,13 @@ async def export_database(data: BackupJob): @router.post( "/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_db = ImportDatabase( zip_archive=file_name, import_recipes=True, - import_settings=False, - import_themes=False, + import_settings=True, + import_themes=True, ) imported = import_db.run() @@ -56,7 +56,7 @@ async def import_database(file_name: str): tags=["Import / Export"], status_code=200, ) -async def delete_backup(backup_name: str): +def delete_backup(backup_name: str): """ Removes a database backup from the file system """ try: diff --git a/mealie/routes/meal_routes.py b/mealie/routes/meal_routes.py index 4c9057ad9..66b2632f1 100644 --- a/mealie/routes/meal_routes.py +++ b/mealie/routes/meal_routes.py @@ -9,14 +9,14 @@ router = APIRouter() @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 """ return MealPlan.get_all() @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 """ data.process_meals() 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"]) -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 """ 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"]) -async def delete_meal_plan(plan_id): +def delete_meal_plan(plan_id): """ Removes a meal plan from the database """ MealPlan.delete(plan_id) @@ -58,7 +58,7 @@ async def delete_meal_plan(plan_id): "/api/meal-plan/today/", tags=["Meal Plan"], ) -async def get_today(): +def get_today(): """ Returns the recipe slug for the meal scheduled for today. 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) -async def get_this_week(): +def get_this_week(): """ Returns the meal plan data for this week """ return MealPlan.this_week() diff --git a/mealie/routes/migration_routes.py b/mealie/routes/migration_routes.py index 8a7430c6a..76e48002d 100644 --- a/mealie/routes/migration_routes.py +++ b/mealie/routes/migration_routes.py @@ -12,7 +12,7 @@ router = APIRouter() # Chowdown @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 """ try: report = chowdow_migrate(repo.url) @@ -31,7 +31,7 @@ async def import_chowdown_recipes(repo: ChowdownURL): # Nextcloud @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 """ available = [] 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"]) -async def import_nextcloud_directory(selection: str): +def import_nextcloud_directory(selection: str): """ Imports all the recipes in a given directory """ return nextcloud_migrate(selection) @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 """ 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"]) -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 """ dest = MIGRATION_DIR.joinpath(archive.filename) diff --git a/mealie/routes/recipe_routes.py b/mealie/routes/recipe_routes.py index 0cad0af6d..520e495c5 100644 --- a/mealie/routes/recipe_routes.py +++ b/mealie/routes/recipe_routes.py @@ -12,9 +12,7 @@ router = APIRouter() @router.get("/api/all-recipes/", tags=["Recipes"], response_model=List[dict]) -async def get_all_recipes( - keys: Optional[List[str]] = Query(...), num: Optional[int] = 100 -): +def get_all_recipes(keys: Optional[List[str]] = Query(...), num: Optional[int] = 100): """ 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 @@ -31,7 +29,7 @@ async def get_all_recipes( @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. 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) -async def get_recipe(recipe_slug: str): +def get_recipe(recipe_slug: str): """ Takes in a recipe slug, returns all data for a recipe """ 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"]) -async def get_recipe_img(recipe_slug: str): +def get_recipe_img(recipe_slug: str): """ Takes in a recipe slug, returns the static image """ recipe_image = read_image(recipe_slug) @@ -69,7 +67,7 @@ async def get_recipe_img(recipe_slug: str): status_code=201, 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 """ slug = create_from_url(url.url) @@ -78,7 +76,7 @@ async def parse_recipe_url(url: RecipeURLIn): @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""" created_recipe = data.save_to_db() @@ -97,7 +95,7 @@ def update_recipe_image( @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. """ 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"]) -async def delete_recipe(recipe_slug: str): +def delete_recipe(recipe_slug: str): """ Deletes a recipe by slug """ try: diff --git a/mealie/routes/setting_routes.py b/mealie/routes/setting_routes.py index 9e214227e..2cb93f570 100644 --- a/mealie/routes/setting_routes.py +++ b/mealie/routes/setting_routes.py @@ -8,21 +8,21 @@ router = APIRouter() @router.get("/api/site-settings/", tags=["Settings"]) -async def get_main_settings(): +def get_main_settings(): """ Returns basic site settings """ return SiteSettings.get_site_settings() @router.post("/api/site-settings/webhooks/test/", tags=["Settings"]) -async def test_webhooks(): +def test_webhooks(): """ Run the function to test your webhooks """ return post_webhooks() @router.post("/api/site-settings/update/", tags=["Settings"]) -async def update_settings(data: SiteSettings): +def update_settings(data: SiteSettings): """ Returns Site Settings """ try: @@ -37,20 +37,20 @@ async def update_settings(data: SiteSettings): @router.get("/api/site-settings/themes/", tags=["Themes"]) -async def get_all_themes(): +def get_all_themes(): """ Returns all site themes """ return SiteTheme.get_all() @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 """ return SiteTheme.get_by_name(theme_name) @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 """ try: @@ -64,7 +64,7 @@ async def create_theme(data: SiteTheme): @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 """ try: 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"]) -async def delete_theme(theme_name: str): +def delete_theme(theme_name: str): """ Deletes theme from the database """ try: SiteTheme.delete_theme(theme_name) diff --git a/mealie/services/backups/imports.py b/mealie/services/backups/imports.py index 257a5d983..cedbcc0b9 100644 --- a/mealie/services/backups/imports.py +++ b/mealie/services/backups/imports.py @@ -5,6 +5,7 @@ from pathlib import Path from typing import List from services.recipe_services import Recipe +from services.settings_services import SiteSettings, SiteTheme from settings import BACKUP_DIR, IMG_DIR, TEMP_DIR from utils.logger import logger @@ -107,10 +108,26 @@ class ImportDatabase: shutil.copy(image, IMG_DIR) 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): - 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): shutil.rmtree(TEMP_DIR) diff --git a/mealie/services/image_services.py b/mealie/services/image_services.py index a6915d763..45e733bbb 100644 --- a/mealie/services/image_services.py +++ b/mealie/services/image_services.py @@ -2,13 +2,13 @@ import shutil from pathlib import Path import requests -from fastapi.responses import FileResponse +from unsync import unsync CWD = Path(__file__).parent 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(): return IMG_DIR.joinpath(recipe_slug) else: