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 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 utils.snackbar import SnackResponse
|
||||
|
||||
|
@ -39,7 +40,14 @@ async def export_database(data: BackupJob):
|
|||
)
|
||||
async def import_database(file_name: str):
|
||||
""" 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
|
||||
|
||||
|
||||
|
|
|
@ -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.scrape_services import normalize_data, process_recipe_data
|
||||
|
||||
from settings import TEMP_DIR
|
||||
CWD = Path(__file__).parent
|
||||
TEMP_DIR = CWD.parent.parent.joinpath("data", "temp")
|
||||
MIGRTAION_DIR = CWD.parent.parent.joinpath("data", "migration")
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import requests
|
|||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
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.recipe_services import Recipe
|
||||
from services.settings_services import SiteSettings
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue