mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 06:23:34 -07:00
migration imports to new DB structure
This commit is contained in:
parent
400fbac7b9
commit
e38bb01635
8 changed files with 115 additions and 14 deletions
0
dev/manual_tests.md
Normal file
0
dev/manual_tests.md
Normal file
BIN
mealie/data/backups/dev_sample_data_2021-Jan-12.zip
Normal file
BIN
mealie/data/backups/dev_sample_data_2021-Jan-12.zip
Normal file
Binary file not shown.
|
@ -1,6 +1,7 @@
|
||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from models.backup_models import BackupJob, Imports
|
from models.backup_models import BackupJob, Imports
|
||||||
from services.backups.export import backup_all
|
from services.backups.exports import backup_all
|
||||||
|
from services.backups.imports import ImportDatabase
|
||||||
from settings import BACKUP_DIR, TEMPLATE_DIR
|
from settings import BACKUP_DIR, TEMPLATE_DIR
|
||||||
from utils.snackbar import SnackResponse
|
from utils.snackbar import SnackResponse
|
||||||
|
|
||||||
|
@ -39,7 +40,14 @@ async def export_database(data: BackupJob):
|
||||||
)
|
)
|
||||||
async def import_database(file_name: str):
|
async def import_database(file_name: str):
|
||||||
""" Import a database backup file generated from Mealie. """
|
""" Import a database backup file generated from Mealie. """
|
||||||
imported = import_from_archive(file_name)
|
import_db = ImportDatabase(
|
||||||
|
zip_archive=file_name,
|
||||||
|
import_recipes=True,
|
||||||
|
import_settings=False,
|
||||||
|
import_themes=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
imported = import_db.run()
|
||||||
return imported
|
return imported
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import json
|
|
||||||
import shutil
|
|
||||||
import zipfile
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from utils.logger import logger
|
|
||||||
|
|
||||||
from settings import IMG_DIR, BACKUP_DIR, TEMPLATE_DIR, TEMP_DIR
|
|
||||||
|
|
103
mealie/services/backups/imports.py
Normal file
103
mealie/services/backups/imports.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from services.recipe_services import Recipe
|
||||||
|
from settings import BACKUP_DIR, IMG_DIR, TEMP_DIR, TEMPLATE_DIR
|
||||||
|
from utils.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
class ImportDatabase:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
zip_archive: str,
|
||||||
|
import_recipes: bool = True,
|
||||||
|
import_settings: bool = True,
|
||||||
|
import_themes: bool = True,
|
||||||
|
force_import: bool = False,
|
||||||
|
rebase: bool = False,
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
self.archive = BACKUP_DIR.joinpath(zip_archive)
|
||||||
|
self.imp_recipes = import_recipes
|
||||||
|
self.imp_settings = import_settings
|
||||||
|
self.imp_themes = import_themes
|
||||||
|
self.force_imports = force_import
|
||||||
|
self.force_rebase = rebase
|
||||||
|
|
||||||
|
if self.archive.is_file():
|
||||||
|
self.import_dir = TEMP_DIR.joinpath("active_import")
|
||||||
|
self.import_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with zipfile.ZipFile(self.archive, "r") as zip_ref:
|
||||||
|
zip_ref.extractall(self.import_dir)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise Exception("Import file does not exist")
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.imp_recipes:
|
||||||
|
report = self.import_recipes()
|
||||||
|
if self.imp_settings:
|
||||||
|
self.import_settings()
|
||||||
|
if self.imp_themes:
|
||||||
|
self.import_themes()
|
||||||
|
|
||||||
|
self.clean_up()
|
||||||
|
|
||||||
|
return report if report else None
|
||||||
|
|
||||||
|
def import_recipes(self):
|
||||||
|
recipe_dir: Path = self.import_dir.joinpath("recipes")
|
||||||
|
|
||||||
|
successful_imports = []
|
||||||
|
failed_imports = []
|
||||||
|
|
||||||
|
for recipe in recipe_dir.glob("*.json"):
|
||||||
|
with open(recipe, "r") as f:
|
||||||
|
recipe_dict = json.loads(f.read())
|
||||||
|
recipe_dict = ImportDatabase._recipe_migration(recipe_dict)
|
||||||
|
|
||||||
|
try:
|
||||||
|
recipe_obj = Recipe(**recipe_dict)
|
||||||
|
recipe_obj.save_to_db()
|
||||||
|
successful_imports.append(recipe.stem)
|
||||||
|
logger.info(f"Imported: {recipe.stem}")
|
||||||
|
except:
|
||||||
|
logger.info(f"Failed Import: {recipe.stem}")
|
||||||
|
failed_imports.append(recipe.stem)
|
||||||
|
|
||||||
|
self._import_images(successful_imports)
|
||||||
|
|
||||||
|
return {"successful": successful_imports, "failed": failed_imports}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _recipe_migration(recipe_dict: dict) -> dict:
|
||||||
|
try:
|
||||||
|
del recipe_dict["_id"]
|
||||||
|
del recipe_dict["dateAdded"]
|
||||||
|
except:
|
||||||
|
logger.info("Detected new backup Schema, skipping migration...")
|
||||||
|
return recipe_dict
|
||||||
|
# Migration from list to Object Type Data
|
||||||
|
if type(recipe_dict["extras"]) == list:
|
||||||
|
recipe_dict["extras"] = {}
|
||||||
|
|
||||||
|
return recipe_dict
|
||||||
|
|
||||||
|
def _import_images(self, successful_imports: List[str]):
|
||||||
|
image_dir = self.import_dir.joinpath("images")
|
||||||
|
for image in image_dir.iterdir():
|
||||||
|
if image.stem in successful_imports:
|
||||||
|
shutil.copy(image, IMG_DIR)
|
||||||
|
|
||||||
|
def import_themes(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def import_settings(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
shutil.rmtree(TEMP_DIR)
|
|
@ -6,9 +6,8 @@ from pathlib import Path
|
||||||
|
|
||||||
from services.recipe_services import IMG_DIR, Recipe
|
from services.recipe_services import IMG_DIR, Recipe
|
||||||
from services.scrape_services import normalize_data, process_recipe_data
|
from services.scrape_services import normalize_data, process_recipe_data
|
||||||
|
from settings import TEMP_DIR
|
||||||
CWD = Path(__file__).parent
|
CWD = Path(__file__).parent
|
||||||
TEMP_DIR = CWD.parent.parent.joinpath("data", "temp")
|
|
||||||
MIGRTAION_DIR = CWD.parent.parent.joinpath("data", "migration")
|
MIGRTAION_DIR = CWD.parent.parent.joinpath("data", "migration")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import requests
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from utils.logger import logger
|
from utils.logger import logger
|
||||||
|
|
||||||
from services.backups.export import auto_backup_job
|
from services.backups.exports import auto_backup_job
|
||||||
from services.meal_services import MealPlan
|
from services.meal_services import MealPlan
|
||||||
from services.recipe_services import Recipe
|
from services.recipe_services import Recipe
|
||||||
from services.settings_services import SiteSettings
|
from services.settings_services import SiteSettings
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue