fix: Make Mealie Timezone-Aware (#3847)

Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com>
This commit is contained in:
Michael Genson
2024-07-08 16:12:20 -05:00
committed by GitHub
parent 17f9eef551
commit d5f7a883df
69 changed files with 250 additions and 176 deletions

View File

@@ -13,7 +13,7 @@ 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.db.models._model_utils.guid import GUID
from mealie.services._base_service import BaseService
PROJECT_DIR = Path(__file__).parent.parent.parent.parent

View File

@@ -25,7 +25,7 @@ class BackupV2(BaseService):
db_file = self.settings.DB_URL.removeprefix("sqlite:///") # type: ignore
# Create a backup of the SQLite database
timestamp = datetime.datetime.now().strftime("%Y.%m.%d")
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y.%m.%d")
shutil.copy(db_file, self.directories.DATA_DIR.joinpath(f"mealie_{timestamp}.bak.db"))
def _postgres(self) -> None:
@@ -37,7 +37,7 @@ class BackupV2(BaseService):
exclude_ext = {".zip"}
exclude_dirs = {"backups", ".temp"}
timestamp = datetime.datetime.now().strftime("%Y.%m.%d.%H.%M.%S")
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y.%m.%d.%H.%M.%S")
backup_name = f"mealie_{timestamp}.zip"
backup_file = self.directories.BACKUP_DIR / backup_name

View File

@@ -1,5 +1,5 @@
import uuid
from datetime import date, datetime
from datetime import date, datetime, timezone
from enum import Enum, auto
from typing import Any
@@ -188,4 +188,4 @@ class Event(MealieModel):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.event_id = uuid.uuid4()
self.timestamp = datetime.now()
self.timestamp = datetime.now(timezone.utc)

View File

@@ -43,7 +43,7 @@ class Exporter(BaseService):
name="Data Export",
size=pretty_size(export_path.stat().st_size),
filename=export_path.name,
expires=datetime.datetime.now() + datetime.timedelta(days=1),
expires=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1),
)
db.group_exports.create(group_data_export)

View File

@@ -1,6 +1,6 @@
import tempfile
import zipfile
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from bs4 import BeautifulSoup
@@ -35,7 +35,7 @@ class CopyMeThatMigrator(BaseMigrator):
self.name = "copymethat"
self.key_aliases = [
MigrationAlias(key="last_made", alias="made_this", func=lambda x: datetime.now()),
MigrationAlias(key="last_made", alias="made_this", func=lambda x: datetime.now(timezone.utc)),
MigrationAlias(key="notes", alias="recipeNotes"),
MigrationAlias(key="orgURL", alias="original_link"),
MigrationAlias(key="rating", alias="ratingValue"),

View File

@@ -1,6 +1,6 @@
import json
import shutil
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from shutil import copytree, rmtree
from typing import Any
@@ -157,7 +157,7 @@ class RecipeService(BaseService):
recipe_id=new_recipe.id,
subject="Recipe Created",
event_type=TimelineEventType.system,
timestamp=new_recipe.created_at or datetime.now(),
timestamp=new_recipe.created_at or datetime.now(timezone.utc),
)
self.repos.recipe_timeline_events.create(timeline_event_data)

View File

@@ -1,5 +1,5 @@
import asyncio
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from pathlib import Path
from mealie.core import root_logger
@@ -28,7 +28,7 @@ class SchedulerService:
async def schedule_daily():
now = datetime.now()
now = datetime.now(timezone.utc)
daily_schedule_time = get_app_settings().DAILY_SCHEDULE_TIME
logger.debug(
"Current time is %s and DAILY_SCHEDULE_TIME is %s",

View File

@@ -16,7 +16,7 @@ def purge_group_data_exports(max_minutes_old=ONE_DAY_AS_MINUTES):
logger = root_logger.get_logger()
logger.debug("purging group data exports")
limit = datetime.datetime.now() - datetime.timedelta(minutes=max_minutes_old)
limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=max_minutes_old)
with session_context() as session:
stmt = select(GroupDataExportsModel).filter(cast(GroupDataExportsModel.expires, DateTime) <= limit)
@@ -38,7 +38,7 @@ def purge_excess_files() -> None:
directories = get_app_dirs()
logger = root_logger.get_logger()
limit = datetime.datetime.now() - datetime.timedelta(minutes=ONE_DAY_AS_MINUTES * 2)
limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=ONE_DAY_AS_MINUTES * 2)
for file in directories.GROUPS_DIR.glob("**/export/*.zip"):
# TODO: fix comparison types

View File

@@ -14,7 +14,7 @@ MAX_DAYS_OLD = 2
def purge_password_reset_tokens():
"""Purges all events after x days"""
logger.debug("purging password reset tokens")
limit = datetime.datetime.now() - datetime.timedelta(days=MAX_DAYS_OLD)
limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=MAX_DAYS_OLD)
with session_context() as session:
stmt = delete(PasswordResetModel).filter(PasswordResetModel.created_at <= limit)

View File

@@ -14,7 +14,7 @@ MAX_DAYS_OLD = 4
def purge_group_registration():
"""Purges all events after x days"""
logger.debug("purging expired registration tokens")
limit = datetime.datetime.now() - datetime.timedelta(days=MAX_DAYS_OLD)
limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=MAX_DAYS_OLD)
with session_context() as session:
stmt = delete(GroupInviteToken).filter(GroupInviteToken.created_at <= limit)

View File

@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.user.user import PrivateUser
@@ -30,7 +30,7 @@ class UserService(BaseService):
return unlocked
def lock_user(self, user: PrivateUser) -> PrivateUser:
user.locked_at = datetime.now()
user.locked_at = datetime.now(timezone.utc)
return self.repos.users.update(user.id, user)
def unlock_user(self, user: PrivateUser) -> PrivateUser: