Replace pytz code

This commit is contained in:
Sonny Bakker 2023-08-06 16:29:56 +02:00
parent 2879bc8305
commit e93a323959
22 changed files with 117 additions and 101 deletions

View file

@ -2,12 +2,11 @@ import logging
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import timedelta from datetime import timedelta
from zoneinfo import ZoneInfo
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.utils import timezone from django.utils import timezone
import pytz
from feedparser import parse from feedparser import parse
from newsreader.news.collection.base import ( from newsreader.news.collection.base import (
@ -58,7 +57,7 @@ class FeedBuilder(PostBuilder):
"published_parsed": "publication_date", "published_parsed": "publication_date",
"author": "author", "author": "author",
} }
tz = pytz.timezone(self.stream.rule.timezone) tz = ZoneInfo(self.stream.rule.timezone)
data = {"rule_id": self.stream.rule.pk} data = {"rule_id": self.stream.rule.pk}
for field, model_field in field_mapping.items(): for field, model_field in field_mapping.items():

View file

@ -1,19 +1,30 @@
from datetime import timezone as python_timezone
from zoneinfo import available_timezones
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import pytz
from newsreader.core.forms import CheckboxInput from newsreader.core.forms import CheckboxInput
from newsreader.news.collection.forms.base import CollectionRuleForm from newsreader.news.collection.forms.base import CollectionRuleForm
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
def get_timezones():
return [
(
_timezone,
_timezone,
)
for _timezone in available_timezones()
]
class FeedForm(CollectionRuleForm): class FeedForm(CollectionRuleForm):
timezone = forms.ChoiceField( timezone = forms.ChoiceField(
widget=forms.Select(attrs={"size": len(pytz.all_timezones)}), widget=forms.Select(attrs={"size": len(get_timezones())}),
choices=((timezone, timezone) for timezone in pytz.all_timezones), choices=get_timezones(),
help_text=_("The timezone which the feed uses"), help_text=_("The timezone which the feed uses"),
initial=pytz.utc, initial=python_timezone.utc,
) )
class Meta: class Meta:

View file

@ -1,10 +1,10 @@
from datetime import timezone
from django import forms from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import pytz
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.forms.base import CollectionRuleForm from newsreader.news.collection.forms.base import CollectionRuleForm
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
@ -36,7 +36,7 @@ class SubRedditForm(CollectionRuleForm):
instance = super().save(commit=False) instance = super().save(commit=False)
instance.type = RuleTypeChoices.subreddit instance.type = RuleTypeChoices.subreddit
instance.timezone = str(pytz.utc) instance.timezone = str(timezone.utc)
if commit: if commit:
instance.save() instance.save()

View file

@ -1,8 +1,8 @@
from datetime import timezone
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import pytz
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.forms.base import CollectionRuleForm from newsreader.news.collection.forms.base import CollectionRuleForm
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
@ -21,7 +21,7 @@ class TwitterTimelineForm(CollectionRuleForm):
instance = super().save(commit=False) instance = super().save(commit=False)
instance.type = RuleTypeChoices.twitter_timeline instance.type = RuleTypeChoices.twitter_timeline
instance.timezone = str(pytz.utc) instance.timezone = str(timezone.utc)
instance.url = f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name={instance.screen_name}&tweet_mode=extended" instance.url = f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name={instance.screen_name}&tweet_mode=extended"
if commit: if commit:

View file

@ -1,13 +1,24 @@
from datetime import timezone
from zoneinfo import available_timezones
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import pytz
from newsreader.core.models import TimeStampedModel from newsreader.core.models import TimeStampedModel
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
def get_timezones():
return [
(
_timezone,
_timezone,
)
for _timezone in available_timezones()
]
class CollectionRuleQuerySet(models.QuerySet): class CollectionRuleQuerySet(models.QuerySet):
def enabled(self): def enabled(self):
return self.filter(enabled=True) return self.filter(enabled=True)
@ -26,9 +37,9 @@ class CollectionRule(TimeStampedModel):
favicon = models.URLField(blank=True, null=True) favicon = models.URLField(blank=True, null=True)
timezone = models.CharField( timezone = models.CharField(
choices=((timezone, timezone) for timezone in pytz.all_timezones), choices=get_timezones(),
max_length=100, max_length=100,
default=str(pytz.utc), default=str(timezone.utc),
) )
category = models.ForeignKey( category = models.ForeignKey(

View file

@ -2,6 +2,7 @@ import logging
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime, timedelta from datetime import datetime, timedelta
from datetime import timezone as _timezone
from html import unescape from html import unescape
from json.decoder import JSONDecodeError from json.decoder import JSONDecodeError
from urllib.parse import urlencode from urllib.parse import urlencode
@ -12,7 +13,6 @@ from django.core.cache import cache
from django.utils import timezone from django.utils import timezone
from django.utils.html import format_html from django.utils.html import format_html
import pytz
import requests import requests
from newsreader.news.collection.base import ( from newsreader.news.collection.base import (
@ -215,7 +215,8 @@ class RedditBuilder(PostBuilder):
try: try:
parsed_date = datetime.fromtimestamp(entry_data["created_utc"]) parsed_date = datetime.fromtimestamp(entry_data["created_utc"])
created_date = pytz.utc.localize(parsed_date)
created_date = parsed_date.replace(tzinfo=_timezone.utc)
except (OverflowError, OSError) as e: except (OverflowError, OSError) as e:
raise BuilderParseException(payload=entry) from e raise BuilderParseException(payload=entry) from e
except KeyError as e: except KeyError as e:

View file

@ -1,12 +1,10 @@
import json import json
from datetime import date, datetime, time from datetime import date, datetime, time, timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import pytz
from newsreader.accounts.tests.factories import UserFactory from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.tests.factories import FeedFactory from newsreader.news.collection.tests.factories import FeedFactory
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
@ -154,21 +152,21 @@ class NestedRuleListViewTestCase(TestCase):
title="I'm the first post", title="I'm the first post",
rule=rule, rule=rule,
publication_date=datetime.combine( publication_date=datetime.combine(
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc date(2019, 5, 20), time(hour=16, minute=7, second=37), timezone.utc
), ),
), ),
FeedPostFactory( FeedPostFactory(
title="I'm the second post", title="I'm the second post",
rule=rule, rule=rule,
publication_date=datetime.combine( publication_date=datetime.combine(
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc date(2019, 7, 20), time(hour=18, minute=7, second=37), timezone.utc
), ),
), ),
FeedPostFactory( FeedPostFactory(
title="I'm the third post", title="I'm the third post",
rule=rule, rule=rule,
publication_date=datetime.combine( publication_date=datetime.combine(
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc date(2019, 7, 20), time(hour=16, minute=7, second=37), timezone.utc
), ),
), ),
] ]

View file

@ -1,11 +1,10 @@
from datetime import datetime from datetime import datetime
from datetime import timezone as _timezone
from unittest.mock import Mock from unittest.mock import Mock
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
import pytz
from freezegun import freeze_time from freezegun import freeze_time
from newsreader.news.collection.feed import FeedBuilder from newsreader.news.collection.feed import FeedBuilder
@ -35,7 +34,7 @@ class FeedBuilderTestCase(TestCase):
post = posts[0] post = posts[0]
publication_date = datetime( publication_date = datetime(
2019, 5, 20, hour=16, minute=32, second=38, tzinfo=pytz.utc 2019, 5, 20, hour=16, minute=32, second=38, tzinfo=_timezone.utc
) )
self.assertEqual( self.assertEqual(
@ -59,7 +58,7 @@ class FeedBuilderTestCase(TestCase):
post = posts[1] post = posts[1]
publication_date = datetime( publication_date = datetime(
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=pytz.utc 2019, 5, 20, hour=16, minute=7, second=37, tzinfo=_timezone.utc
) )
self.assertEqual( self.assertEqual(
@ -94,7 +93,7 @@ class FeedBuilderTestCase(TestCase):
post = posts[0] post = posts[0]
publication_date = datetime( publication_date = datetime(
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=pytz.utc 2019, 5, 20, hour=16, minute=7, second=37, tzinfo=_timezone.utc
) )
self.assertEqual(post.publication_date, publication_date) self.assertEqual(post.publication_date, publication_date)
@ -109,7 +108,7 @@ class FeedBuilderTestCase(TestCase):
post = posts[1] post = posts[1]
publication_date = datetime( publication_date = datetime(
2019, 5, 20, hour=12, minute=19, second=19, tzinfo=pytz.utc 2019, 5, 20, hour=12, minute=19, second=19, tzinfo=_timezone.utc
) )
self.assertEqual(post.publication_date, publication_date) self.assertEqual(post.publication_date, publication_date)

View file

@ -1,12 +1,11 @@
from datetime import date, datetime, time from datetime import date, datetime, time
from datetime import timezone as _timezone
from time import struct_time from time import struct_time
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
import pytz
from freezegun import freeze_time from freezegun import freeze_time
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
@ -100,7 +99,7 @@ class FeedCollectorTestCase(TestCase):
def test_forbidden(self): def test_forbidden(self):
self.mocked_fetch.side_effect = StreamForbiddenException self.mocked_fetch.side_effect = StreamForbiddenException
old_run = pytz.utc.localize(datetime(2019, 10, 30, 12, 30)) old_run = datetime(2019, 10, 30, 12, 30, tzinfo=_timezone.utc)
rule = FeedFactory(last_run=old_run) rule = FeedFactory(last_run=old_run)
collector = FeedCollector() collector = FeedCollector()
@ -130,7 +129,7 @@ class FeedCollectorTestCase(TestCase):
self.assertEquals(rule.succeeded, False) self.assertEquals(rule.succeeded, False)
self.assertEquals(rule.error, "Stream timed out") self.assertEquals(rule.error, "Stream timed out")
self.assertEquals( self.assertEquals(
rule.last_run, pytz.utc.localize(datetime(2019, 10, 30, 12, 30)) rule.last_run, datetime(2019, 10, 30, 12, 30, tzinfo=_timezone.utc)
) )
def test_duplicates(self): def test_duplicates(self):
@ -139,7 +138,7 @@ class FeedCollectorTestCase(TestCase):
rule = FeedFactory() rule = FeedFactory()
aware_datetime = build_publication_date( aware_datetime = build_publication_date(
struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), pytz.utc struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), _timezone.utc
) )
first_post = FeedPostFactory( first_post = FeedPostFactory(
@ -152,7 +151,7 @@ class FeedCollectorTestCase(TestCase):
) )
aware_datetime = build_publication_date( aware_datetime = build_publication_date(
struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), pytz.utc struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), _timezone.utc
) )
second_post = FeedPostFactory( second_post = FeedPostFactory(
@ -165,7 +164,7 @@ class FeedCollectorTestCase(TestCase):
) )
aware_datetime = build_publication_date( aware_datetime = build_publication_date(
struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), pytz.utc struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), _timezone.utc
) )
third_post = FeedPostFactory( third_post = FeedPostFactory(

View file

@ -1,10 +1,8 @@
from datetime import datetime from datetime import datetime, timezone
from unittest.mock import Mock from unittest.mock import Mock
from django.test import TestCase from django.test import TestCase
import pytz
from newsreader.news.collection.reddit import RedditBuilder from newsreader.news.collection.reddit import RedditBuilder
from newsreader.news.collection.tests.factories import SubredditFactory from newsreader.news.collection.tests.factories import SubredditFactory
from newsreader.news.collection.tests.reddit.builder.mocks import * from newsreader.news.collection.tests.reddit.builder.mocks import *
@ -59,7 +57,7 @@ class RedditBuilderTestCase(TestCase):
"https://www.reddit.com/r/linux/comments/hm0qct/linux_experiencesrants_or_educationcertifications/", "https://www.reddit.com/r/linux/comments/hm0qct/linux_experiencesrants_or_educationcertifications/",
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 7, 6, 6, 11, 22)) post.publication_date, datetime(2020, 7, 6, 6, 11, 22, tzinfo=timezone.utc)
) )
def test_empty_data(self): def test_empty_data(self):

View file

@ -1,12 +1,11 @@
from datetime import datetime from datetime import datetime
from datetime import timezone as _timezone
from unittest.mock import patch from unittest.mock import patch
from uuid import uuid4 from uuid import uuid4
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
import pytz
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamDeniedException, StreamDeniedException,
@ -82,7 +81,8 @@ class RedditCollectorTestCase(TestCase):
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 7, 11, 22, 23, 24)) post.publication_date,
datetime(2020, 7, 11, 22, 23, 24, tzinfo=_timezone.utc),
) )
self.assertEquals(post.author, "HannahB888") self.assertEquals(post.author, "HannahB888")
@ -99,7 +99,8 @@ class RedditCollectorTestCase(TestCase):
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 7, 12, 10, 29, 10)) post.publication_date,
datetime(2020, 7, 12, 10, 29, 10, tzinfo=_timezone.utc),
) )
self.assertEquals(post.author, "Sebaron") self.assertEquals(post.author, "Sebaron")

View file

@ -1,11 +1,9 @@
from datetime import datetime from datetime import datetime, timezone
from unittest.mock import Mock from unittest.mock import Mock
from django.test import TestCase from django.test import TestCase
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
import pytz
from ftfy import fix_text from ftfy import fix_text
from newsreader.news.collection.tests.factories import TwitterTimelineFactory from newsreader.news.collection.tests.factories import TwitterTimelineFactory
@ -69,7 +67,7 @@ class TwitterBuilderTestCase(TestCase):
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291528756373286914" post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291528756373286914"
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 8, 7, 0, 17, 5)) post.publication_date, datetime(2020, 8, 7, 0, 17, 5, tzinfo=timezone.utc)
) )
post = posts["1288550304095416320"] post = posts["1288550304095416320"]
@ -85,7 +83,7 @@ class TwitterBuilderTestCase(TestCase):
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1288550304095416320" post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1288550304095416320"
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 7, 29, 19, 1, 47)) post.publication_date, datetime(2020, 7, 29, 19, 1, 47, tzinfo=timezone.utc)
) )
# note that only one media type can be uploaded to an Tweet # note that only one media type can be uploaded to an Tweet
@ -114,7 +112,7 @@ class TwitterBuilderTestCase(TestCase):
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1269039237166321664" post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1269039237166321664"
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 6, 5, 22, 51, 46)) post.publication_date, datetime(2020, 6, 5, 22, 51, 46, tzinfo=timezone.utc)
) )
self.assertInHTML( self.assertInHTML(
@ -179,7 +177,7 @@ class TwitterBuilderTestCase(TestCase):
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291080532361527296" post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291080532361527296"
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 8, 5, 18, 36, 0)) post.publication_date, datetime(2020, 8, 5, 18, 36, 0, tzinfo=timezone.utc)
) )
self.assertIn(full_text, post.body) self.assertIn(full_text, post.body)

View file

@ -1,12 +1,11 @@
from datetime import datetime from datetime import datetime
from datetime import timezone as _timezone
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
from uuid import uuid4 from uuid import uuid4
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
import pytz
from freezegun import freeze_time from freezegun import freeze_time
from ftfy import fix_text from ftfy import fix_text
@ -67,7 +66,8 @@ class TwitterCollectorTestCase(TestCase):
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 9, 18, 20, 32, 22)) post.publication_date,
datetime(2020, 9, 18, 20, 32, 22, tzinfo=_timezone.utc),
) )
title = truncate_text( title = truncate_text(
@ -89,7 +89,8 @@ class TwitterCollectorTestCase(TestCase):
) )
self.assertEquals( self.assertEquals(
post.publication_date, pytz.utc.localize(datetime(2020, 9, 18, 18, 50, 11)) post.publication_date,
datetime(2020, 9, 18, 18, 50, 11, tzinfo=_timezone.utc),
) )
body = fix_text( body = fix_text(

View file

@ -1,8 +1,8 @@
from datetime import timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import pytz
from django_celery_beat.models import PeriodicTask from django_celery_beat.models import PeriodicTask
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
@ -21,7 +21,7 @@ class FeedCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.form_data.update( self.form_data.update(
name="new rule", name="new rule",
url="https://www.rss.com/rss", url="https://www.rss.com/rss",
timezone=pytz.utc, timezone=str(timezone.utc),
category=str(self.category.pk), category=str(self.category.pk),
) )
@ -34,7 +34,7 @@ class FeedCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.assertEquals(rule.type, RuleTypeChoices.feed) self.assertEquals(rule.type, RuleTypeChoices.feed)
self.assertEquals(rule.url, "https://www.rss.com/rss") self.assertEquals(rule.url, "https://www.rss.com/rss")
self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.timezone, str(timezone.utc))
self.assertEquals(rule.favicon, None) self.assertEquals(rule.favicon, None)
self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.category.pk, self.category.pk)
self.assertEquals(rule.user.pk, self.user.pk) self.assertEquals(rule.user.pk, self.user.pk)

View file

@ -1,9 +1,9 @@
from datetime import timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import pytz
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
from newsreader.news.collection.reddit import REDDIT_API_URL, REDDIT_URL from newsreader.news.collection.reddit import REDDIT_API_URL, REDDIT_URL
@ -38,7 +38,7 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.assertEquals(rule.type, RuleTypeChoices.subreddit) self.assertEquals(rule.type, RuleTypeChoices.subreddit)
self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww") self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww")
self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.timezone, str(timezone.utc))
self.assertEquals(rule.favicon, None) self.assertEquals(rule.favicon, None)
self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.category.pk, self.category.pk)
self.assertEquals(rule.user.pk, self.user.pk) self.assertEquals(rule.user.pk, self.user.pk)
@ -70,7 +70,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
"name": self.rule.name, "name": self.rule.name,
"url": self.rule.url, "url": self.rule.url,
"category": str(self.category.pk), "category": str(self.category.pk),
"timezone": pytz.utc, "timezone": str(timezone.utc),
"reddit_allow_nfsw": False, "reddit_allow_nfsw": False,
"reddit_allow_spoiler": False, "reddit_allow_spoiler": False,
"reddit_allow_viewed": True, "reddit_allow_viewed": True,
@ -125,7 +125,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.assertEquals(rule.type, RuleTypeChoices.subreddit) self.assertEquals(rule.type, RuleTypeChoices.subreddit)
self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww") self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww")
self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.timezone, str(timezone.utc))
self.assertEquals(rule.favicon, None) self.assertEquals(rule.favicon, None)
self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.category.pk, self.category.pk)
self.assertEquals(rule.user.pk, self.user.pk) self.assertEquals(rule.user.pk, self.user.pk)

View file

@ -1,8 +1,8 @@
from datetime import timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import pytz
from django_celery_beat.models import PeriodicTask from django_celery_beat.models import PeriodicTask
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
@ -37,7 +37,7 @@ class TwitterTimelineCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
rule.url, rule.url,
f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=RobertsSpaceInd&tweet_mode=extended", f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=RobertsSpaceInd&tweet_mode=extended",
) )
self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.timezone, str(timezone.utc))
self.assertEquals(rule.favicon, None) self.assertEquals(rule.favicon, None)
self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.category.pk, self.category.pk)
self.assertEquals(rule.user.pk, self.user.pk) self.assertEquals(rule.user.pk, self.user.pk)
@ -70,7 +70,7 @@ class TwitterTimelineUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
"name": self.rule.name, "name": self.rule.name,
"screen_name": self.rule.screen_name, "screen_name": self.rule.screen_name,
"category": str(self.category.pk), "category": str(self.category.pk),
"timezone": pytz.utc, "timezone": str(timezone.utc),
} }
def test_name_change(self): def test_name_change(self):
@ -123,7 +123,7 @@ class TwitterTimelineUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.rule.url, self.rule.url,
f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=CyberpunkGame&tweet_mode=extended", f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=CyberpunkGame&tweet_mode=extended",
) )
self.assertEquals(self.rule.timezone, str(pytz.utc)) self.assertEquals(self.rule.timezone, str(timezone.utc))
self.assertEquals(self.rule.favicon, None) self.assertEquals(self.rule.favicon, None)
self.assertEquals(self.rule.category.pk, self.category.pk) self.assertEquals(self.rule.category.pk, self.category.pk)
self.assertEquals(self.rule.user.pk, self.user.pk) self.assertEquals(self.rule.user.pk, self.user.pk)

View file

@ -2,6 +2,7 @@ import logging
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime from datetime import datetime
from datetime import timezone as _timezone
from json import JSONDecodeError from json import JSONDecodeError
from django.conf import settings from django.conf import settings
@ -10,8 +11,6 @@ from django.utils import timezone
from django.utils.html import format_html, urlize from django.utils.html import format_html, urlize
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import pytz
from ftfy import fix_text from ftfy import fix_text
from requests_oauthlib import OAuth1 as OAuth from requests_oauthlib import OAuth1 as OAuth
@ -82,9 +81,11 @@ class TwitterBuilder(PostBuilder):
Post, "title", self.sanitize_fragment(data["full_text"]) Post, "title", self.sanitize_fragment(data["full_text"])
) )
publication_date = pytz.utc.localize( parsed_date = datetime.strptime(
datetime.strptime(data["created_at"], "%a %b %d %H:%M:%S +0000 %Y") data["created_at"], "%a %b %d %H:%M:%S +0000 %Y"
) )
publication_date = parsed_date.replace(tzinfo=_timezone.utc)
except KeyError as e: except KeyError as e:
raise BuilderMissingDataException(payload=data) from e raise BuilderMissingDataException(payload=data) from e
except (OverflowError, OSError) as e: except (OverflowError, OSError) as e:

View file

@ -1,10 +1,10 @@
from datetime import datetime from datetime import datetime
from datetime import timezone as _timezone
from django.conf import settings from django.conf import settings
from django.db.models.fields import CharField, TextField from django.db.models.fields import CharField, TextField
from django.utils import timezone from django.utils import timezone
import pytz
import requests import requests
from requests.exceptions import RequestException from requests.exceptions import RequestException
@ -22,7 +22,7 @@ def build_publication_date(dt, tz):
except (TypeError, ValueError): except (TypeError, ValueError):
return timezone.now() return timezone.now()
return published_parsed.astimezone(pytz.utc) return published_parsed.astimezone(_timezone.utc)
def fetch(url, auth=None, headers={}): def fetch(url, auth=None, headers={}):

View file

@ -1,8 +1,8 @@
import json import json
from django.urls import reverse_lazy from zoneinfo import available_timezones
import pytz from django.urls import reverse_lazy
from django_celery_beat.models import IntervalSchedule, PeriodicTask from django_celery_beat.models import IntervalSchedule, PeriodicTask
@ -25,7 +25,9 @@ class CollectionRuleDetailMixin:
context_data = super().get_context_data(**kwargs) context_data = super().get_context_data(**kwargs)
categories = Category.objects.filter(user=self.request.user).order_by("name") categories = Category.objects.filter(user=self.request.user).order_by("name")
timezones = [timezone for timezone in pytz.all_timezones]
_available_timezones = available_timezones()
timezones = [timezone for timezone in _available_timezones]
context_data["categories"] = categories context_data["categories"] = categories
context_data["timezones"] = timezones context_data["timezones"] = timezones

View file

@ -1,12 +1,10 @@
import json import json
from datetime import datetime from datetime import datetime, timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import pytz
from newsreader.accounts.tests.factories import UserFactory from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.tests.factories import FeedFactory from newsreader.news.collection.tests.factories import FeedFactory
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
@ -29,15 +27,15 @@ class CategoryListViewTestCase(TestCase):
def test_ordering(self): def test_ordering(self):
categories = [ categories = [
CategoryFactory( CategoryFactory(
created=datetime(2019, 5, 20, 16, 7, 37, tzinfo=pytz.utc), created=datetime(2019, 5, 20, 16, 7, 37, tzinfo=timezone.utc),
user=self.user, user=self.user,
), ),
CategoryFactory( CategoryFactory(
created=datetime(2019, 7, 20, 18, 7, 37, tzinfo=pytz.utc), created=datetime(2019, 7, 20, 18, 7, 37, tzinfo=timezone.utc),
user=self.user, user=self.user,
), ),
CategoryFactory( CategoryFactory(
created=datetime(2019, 7, 20, 16, 7, 37, tzinfo=pytz.utc), created=datetime(2019, 7, 20, 16, 7, 37, tzinfo=timezone.utc),
user=self.user, user=self.user,
), ),
] ]
@ -430,12 +428,12 @@ class NestedCategoryPostView(TestCase):
FeedPostFactory.create( FeedPostFactory.create(
title="Second Reuters post", title="Second Reuters post",
rule=reuters_rule, rule=reuters_rule,
publication_date=datetime(2019, 5, 21, 15, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 21, 15, tzinfo=timezone.utc),
), ),
FeedPostFactory.create( FeedPostFactory.create(
title="First Reuters post", title="First Reuters post",
rule=reuters_rule, rule=reuters_rule,
publication_date=datetime(2019, 5, 20, 12, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 12, tzinfo=timezone.utc),
), ),
] ]
@ -443,12 +441,12 @@ class NestedCategoryPostView(TestCase):
FeedPostFactory.create( FeedPostFactory.create(
title="Second Guardian post", title="Second Guardian post",
rule=guardian_rule, rule=guardian_rule,
publication_date=datetime(2019, 5, 21, 14, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 21, 14, tzinfo=timezone.utc),
), ),
FeedPostFactory.create( FeedPostFactory.create(
title="First Guardian post", title="First Guardian post",
rule=guardian_rule, rule=guardian_rule,
publication_date=datetime(2019, 5, 20, 11, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 11, tzinfo=timezone.utc),
), ),
] ]
@ -456,12 +454,12 @@ class NestedCategoryPostView(TestCase):
FeedPostFactory.create( FeedPostFactory.create(
title="Second BBC post", title="Second BBC post",
rule=bbc_rule, rule=bbc_rule,
publication_date=datetime(2019, 5, 21, 16, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 21, 16, tzinfo=timezone.utc),
), ),
FeedPostFactory.create( FeedPostFactory.create(
title="First BBC post", title="First BBC post",
rule=bbc_rule, rule=bbc_rule,
publication_date=datetime(2019, 5, 20, 13, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 13, tzinfo=timezone.utc),
), ),
] ]

View file

@ -1,10 +1,8 @@
from datetime import datetime from datetime import datetime, timezone
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
import pytz
from newsreader.accounts.tests.factories import UserFactory from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.tests.factories import FeedFactory from newsreader.news.collection.tests.factories import FeedFactory
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
@ -32,17 +30,17 @@ class PostListViewTestCase(TestCase):
FeedPostFactory( FeedPostFactory(
title="I'm the first post", title="I'm the first post",
rule=rule, rule=rule,
publication_date=datetime(2019, 5, 20, 16, 7, 38, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 16, 7, 38, tzinfo=timezone.utc),
), ),
FeedPostFactory( FeedPostFactory(
title="I'm the second post", title="I'm the second post",
rule=rule, rule=rule,
publication_date=datetime(2019, 5, 20, 16, 7, 37, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 16, 7, 37, tzinfo=timezone.utc),
), ),
FeedPostFactory( FeedPostFactory(
title="I'm the third post", title="I'm the third post",
rule=rule, rule=rule,
publication_date=datetime(2019, 5, 20, 16, 7, 36, tzinfo=pytz.utc), publication_date=datetime(2019, 5, 20, 16, 7, 36, tzinfo=timezone.utc),
), ),
] ]

View file

@ -1,6 +1,7 @@
from datetime import timezone
import factory import factory
import factory.fuzzy import factory.fuzzy
import pytz
from newsreader.accounts.tests.factories import UserFactory from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.reddit import REDDIT_API_URL from newsreader.news.collection.reddit import REDDIT_API_URL
@ -19,7 +20,7 @@ class PostFactory(factory.django.DjangoModelFactory):
title = factory.Faker("sentence") title = factory.Faker("sentence")
body = factory.Faker("paragraph") body = factory.Faker("paragraph")
author = factory.Faker("name") author = factory.Faker("name")
publication_date = factory.Faker("date_time_this_year", tzinfo=pytz.utc) publication_date = factory.Faker("date_time_this_year", tzinfo=timezone.utc)
url = factory.Faker("url") url = factory.Faker("url")
remote_identifier = factory.Faker("uuid4") remote_identifier = factory.Faker("uuid4")