Merge branch 'mealie-next' into fix/translation-issues-when-scraping

This commit is contained in:
Michael Genson
2024-01-10 11:35:28 -06:00
committed by GitHub
79 changed files with 1318 additions and 573 deletions

View File

@@ -1,4 +1,5 @@
import datetime
import uuid
from os import path
from pathlib import Path
@@ -10,6 +11,8 @@ from sqlalchemy.orm import sessionmaker
from alembic import command
from alembic.config import Config
from mealie.db import init_db
from mealie.db.models._model_utils import GUID
from mealie.services._base_service import BaseService
PROJECT_DIR = Path(__file__).parent.parent.parent.parent
@@ -38,23 +41,33 @@ class AlchemyExporter(BaseService):
self.session_maker = sessionmaker(bind=self.engine)
@staticmethod
def convert_to_datetime(data: dict) -> dict:
def is_uuid(value: str) -> bool:
try:
uuid.UUID(value)
return True
except ValueError:
return False
def convert_types(self, data: dict) -> dict:
"""
walks the dictionary to convert all things that look like timestamps to datetime objects
walks the dictionary to restore all things that look like string representations of their complex types
used in the context of reading a json file into a database via SQLAlchemy.
"""
for key, value in data.items():
if isinstance(value, dict):
data = AlchemyExporter.convert_to_datetime(value)
data = self.convert_types(value)
elif isinstance(value, list): # assume that this is a list of dictionaries
data[key] = [AlchemyExporter.convert_to_datetime(item) for item in value]
data[key] = [self.convert_types(item) for item in value]
elif isinstance(value, str):
if key in AlchemyExporter.look_for_datetime:
data[key] = AlchemyExporter.DateTimeParser(dt=value).dt
if key in AlchemyExporter.look_for_date:
data[key] = AlchemyExporter.DateTimeParser(date=value).date
if key in AlchemyExporter.look_for_time:
data[key] = AlchemyExporter.DateTimeParser(time=value).time
if self.is_uuid(value):
# convert the data to the current database's native GUID type
data[key] = GUID.convert_value_to_guid(value, self.engine.dialect)
if key in self.look_for_datetime:
data[key] = self.DateTimeParser(dt=value).dt
if key in self.look_for_date:
data[key] = self.DateTimeParser(date=value).date
if key in self.look_for_time:
data[key] = self.DateTimeParser(time=value).time
return data
def dump_schema(self) -> dict:
@@ -105,7 +118,7 @@ class AlchemyExporter(BaseService):
del db_dump["alembic_version"]
"""Restores all data from dictionary into the database"""
with self.engine.begin() as connection:
data = AlchemyExporter.convert_to_datetime(db_dump)
data = self.convert_types(db_dump)
self.meta.reflect(bind=self.engine)
for table_name, rows in data.items():
@@ -139,8 +152,8 @@ SELECT SETVAL('shopping_list_item_extras_id_seq', (SELECT MAX(id) FROM shopping_
)
)
# Run all migrations up to current version
command.upgrade(alembic_cfg, "head")
# Re-init database to finish migrations
init_db.main()
def drop_all(self) -> None:
"""Drops all data from the database"""

View File

@@ -83,7 +83,7 @@ class BackupV2(BaseService):
# Validation
if not contents.validate():
self.logger.error(
"Invalid backup file. file does not contain required elements (data directory and database.json"
"Invalid backup file. file does not contain required elements (data directory and database.json)"
)
raise ValueError("Invalid backup file")

View File

@@ -212,7 +212,7 @@
<td style="width: 550px">
<img
height="auto"
src="https://api-test.emailbuilder.top/saemailbuilder/dc23dc82-ffd7-4f4c-b563-94f23db4c2c3/images/256d8bd6-ffde-4bf2-b577-dd8306dae877/file.png"
src="https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/mealie-email-banner.png"
style="
border: 0;
display: block;

View File

@@ -16,7 +16,7 @@ class ApprisePublisher:
def __init__(self, hard_fail=False) -> None:
asset = apprise.AppriseAsset(
async_mode=True,
image_url_mask="https://raw.githubusercontent.com/hay-kot/mealie/dev/frontend/public/img/icons/android-chrome-maskable-512x512.png",
image_url_mask="https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-maskable-512x512.png",
)
self.apprise = apprise.Apprise(asset=asset)
self.hard_fail = hard_fail