diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index d21c9363d..28effaf9b 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -1,5 +1,6 @@ """ activitypub-aware django model fields """ from dataclasses import MISSING +from datetime import datetime import re from uuid import uuid4 from urllib.parse import urljoin @@ -534,8 +535,10 @@ class DateTimeField(ActivitypubFieldMixin, models.DateTimeField): return value.isoformat() def field_from_activity(self, value, allow_external_connections=True): + missing_fields = datetime(1970, 1, 1) # "2022-10" => "2022-10-01" try: - date_value = dateutil.parser.parse(value) + # TODO(dato): investigate `ignoretz=True` wrt bookwyrm#3028. + date_value = dateutil.parser.parse(value, default=missing_fields) try: return timezone.make_aware(date_value) except ValueError: diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 8929e9037..f5d86ad2e 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -1,4 +1,5 @@ """ track progress of goodreads imports """ +from datetime import datetime import math import re import dateutil.parser @@ -259,38 +260,30 @@ class ImportItem(models.Model): except ValueError: return None + def _parse_datefield(self, field, /): + if not (date := self.normalized_data.get(field)): + return None + + defaults = datetime(1970, 1, 1) # "2022-10" => "2022-10-01" + parsed = dateutil.parser.parse(date, default=defaults) + + # Keep timezone if import already had one, else use default. + return parsed if timezone.is_aware(parsed) else timezone.make_aware(parsed) + @property def date_added(self): """when the book was added to this dataset""" - if self.normalized_data.get("date_added"): - parsed_date_added = dateutil.parser.parse( - self.normalized_data.get("date_added") - ) - - if timezone.is_aware(parsed_date_added): - # Keep timezone if import already had one - return parsed_date_added - - return timezone.make_aware(parsed_date_added) - return None + return self._parse_datefield("date_added") @property def date_started(self): """when the book was started""" - if self.normalized_data.get("date_started"): - return timezone.make_aware( - dateutil.parser.parse(self.normalized_data.get("date_started")) - ) - return None + return self._parse_datefield("date_started") @property def date_read(self): """the date a book was completed""" - if self.normalized_data.get("date_finished"): - return timezone.make_aware( - dateutil.parser.parse(self.normalized_data.get("date_finished")) - ) - return None + return self._parse_datefield("date_finished") @property def reads(self): diff --git a/bookwyrm/tests/views/imports/test_import.py b/bookwyrm/tests/views/imports/test_import.py index ea88b197d..7dd87d4c2 100644 --- a/bookwyrm/tests/views/imports/test_import.py +++ b/bookwyrm/tests/views/imports/test_import.py @@ -7,6 +7,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory +from django.utils import timezone from bookwyrm import forms, models, views from bookwyrm.tests.validate_html import validate_html @@ -128,7 +129,7 @@ class ImportViews(TestCase): def test_get_average_import_time_with_data(self): """Now, with data""" - now = datetime.datetime.now() + now = timezone.now() two_hours_ago = now - datetime.timedelta(hours=2) four_hours_ago = now - datetime.timedelta(hours=4) models.ImportJob.objects.create( @@ -152,7 +153,7 @@ class ImportViews(TestCase): def test_get_average_import_time_ignore_stopped(self): """Don't include stopped, do include no status""" - now = datetime.datetime.now() + now = timezone.now() two_hours_ago = now - datetime.timedelta(hours=2) four_hours_ago = now - datetime.timedelta(hours=4) models.ImportJob.objects.create(