Skip to content

Commit

Permalink
Add error logging to the timestamp migration and improved migration
Browse files Browse the repository at this point in the history
This also changes the migration of items with 2 timestamps, so it still
migrates the valid one, if the other is invalid.

See wagtail#9590
  • Loading branch information
th3hamm0r authored and lb- committed Jul 16, 2023
1 parent 74af3e3 commit 73e29e2
Showing 1 changed file with 38 additions and 11 deletions.
49 changes: 38 additions & 11 deletions wagtail/migrations/0088_fix_log_entry_json_timestamps.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# Generated by Django 3.2.6 on 2022-11-09 07:50

import datetime
import logging

import django.core.serializers.json
from django.conf import settings
from django.db import migrations, models
from django.utils import timezone, dateparse

logger = logging.getLogger("wagtail.migrations")


def legacy_to_iso_format(date_string, tz=None):
dt = datetime.datetime.strptime(date_string, "%d %b %Y %H:%M")
Expand Down Expand Up @@ -43,7 +46,13 @@ def migrate_logs_with_created_only(model, converter):
# to UTC by django.
item.data["revision"]["created"] = converter(created)
except ValueError:
# TODO TBD: log error?
logger.warning(
"Failed to migrate 'created' timestamp '%s' of %s %s (%s)",
item.data["revision"]["created"],
model.__name__,
item.pk,
converter.__name__,
)
continue
except KeyError:
continue
Expand All @@ -62,24 +71,42 @@ def migrate_schedule_logs(model, converter):
created = item.data["revision"]["created"]
# May be unset for "wagtail.schedule.cancel"-logs.
go_live_at = item.data["revision"].get("go_live_at")
changed = False
try:
# "created" is set to timezone.now() for new revisions ("wagtail.publish.schedule")
# and to self.created_at for "wagtail.schedule.cancel", which is set to UTC
# by django.
item.data["revision"]["created"] = converter(created)

if go_live_at:
# The go_live_at date is set to the revision object's "go_live_at".
# The revision's object is created by deserializing the json data (see wagtail.models.Revision.as_object()),
# and this process converts all datetime objects to the local timestamp (see https://github.com/wagtail/django-modelcluster/blob/8666f16eaf23ca98afc160b0a4729864411c0563/modelcluster/models.py#L109-L115).
# That's the reason, why this date is the only date, which is not stored in the log's JSON as UTC, but in the default timezone.
changed = True
except ValueError:
logger.warning(
"Failed to migrate 'created' timestamp '%s' of %s %s (%s)",
created,
model.__name__,
item.pk,
converter.__name__,
)

if go_live_at:
# The go_live_at date is set to the revision object's "go_live_at".
# The revision's object is created by deserializing the json data (see wagtail.models.Revision.as_object()),
# and this process converts all datetime objects to the local timestamp (see https://github.com/wagtail/django-modelcluster/blob/8666f16eaf23ca98afc160b0a4729864411c0563/modelcluster/models.py#L109-L115).
# That's the reason, why this date is the only date, which is not stored in the log's JSON as UTC, but in the default timezone.
try:
item.data["revision"]["go_live_at"] = converter(
go_live_at, tz=timezone.get_default_timezone()
)
except ValueError:
# TODO TBD: log error?
continue
else:
changed = True
except ValueError:
logger.warning(
"Failed to migrate 'go_live_at' timestamp '%s' of %s %s (%s)",
go_live_at,
model.__name__,
item.pk,
converter.__name__,
)

if changed:
item.save(update_fields=["data"])


Expand Down

0 comments on commit 73e29e2

Please sign in to comment.