diff --git a/ietf/api/management/commands/makeresources.py b/ietf/api/management/commands/makeresources.py index 07f8402e7..889b2cdfb 100644 --- a/ietf/api/management/commands/makeresources.py +++ b/ietf/api/management/commands/makeresources.py @@ -3,7 +3,6 @@ import os -import datetime import collections import io @@ -14,6 +13,7 @@ import debug # pyflakes:ignore from django.core.management.base import AppCommand from django.db import models from django.template import Template, Context +from django.utils import timezone from tastypie.resources import ModelResource @@ -89,7 +89,7 @@ class Command(AppCommand): info = dict( app=app.name, app_label=app.label, - date=datetime.datetime.now() + date=timezone.now() ) new_models = {} for model, rclass_name in missing_resources: diff --git a/ietf/bin/send-scheduled-mail b/ietf/bin/send-scheduled-mail index c6a2dbf50..d3474db09 100755 --- a/ietf/bin/send-scheduled-mail +++ b/ietf/bin/send-scheduled-mail @@ -3,7 +3,7 @@ # This script requires that the proper virtual python environment has been # invoked before start -import datetime, os, sys +import os, sys import syslog # boilerplate @@ -16,6 +16,7 @@ syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) import django django.setup() +from django.utils import timezone from ietf.utils.mail import log_smtp_exception, send_error_email from smtplib import SMTPException @@ -32,7 +33,7 @@ from ietf.message.models import SendQueue mode = sys.argv[1] -now = datetime.datetime.now() +now = timezone.now() needs_sending = SendQueue.objects.filter(sent_at=None).select_related("message") if mode == "specific": diff --git a/ietf/community/views.py b/ietf/community/views.py index c67f992d6..b0646424a 100644 --- a/ietf/community/views.py +++ b/ietf/community/views.py @@ -10,6 +10,7 @@ import uuid from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.shortcuts import get_object_or_404, render from django.contrib.auth.decorators import login_required +from django.utils import timezone from django.utils.html import strip_tags import debug # pyflakes:ignore @@ -218,7 +219,7 @@ def feed(request, username=None, acronym=None, group_type=None): significant = request.GET.get('significant', '') == '1' documents = docs_tracked_by_community_list(clist).values_list('pk', flat=True) - since = datetime.datetime.now() - datetime.timedelta(days=14) + since = timezone.now() - datetime.timedelta(days=14) events = DocEvent.objects.filter( doc__id__in=documents, @@ -243,7 +244,7 @@ def feed(request, username=None, acronym=None, group_type=None): 'title': title, 'subtitle': subtitle, 'id': feed_id.urn, - 'updated': datetime.datetime.now(), + 'updated': timezone.now(), }, content_type='text/xml') diff --git a/ietf/doc/expire.py b/ietf/doc/expire.py index b780c73bd..328a97404 100644 --- a/ietf/doc/expire.py +++ b/ietf/doc/expire.py @@ -4,6 +4,7 @@ from django.conf import settings +from django.utils import timezone import datetime, os, shutil, glob, re from pathlib import Path @@ -62,7 +63,7 @@ def get_expired_drafts(): def in_draft_expire_freeze(when=None): if when == None: - when = datetime.datetime.now() + when = timezone.now() meeting = Meeting.objects.filter(type='ietf', date__gte=when-datetime.timedelta(days=7)).order_by('date').first() diff --git a/ietf/doc/factories.py b/ietf/doc/factories.py index 8fd6feca7..568e79cc7 100644 --- a/ietf/doc/factories.py +++ b/ietf/doc/factories.py @@ -10,6 +10,7 @@ import datetime from typing import Optional # pyflakes:ignore from django.conf import settings +from django.utils import timezone from ietf.doc.models import ( Document, DocEvent, NewRevisionDocEvent, DocAlias, State, DocumentAuthor, StateDocEvent, BallotPositionDocEvent, BallotDocEvent, BallotType, IRSGBallotDocEvent, TelechatDocEvent, @@ -38,7 +39,7 @@ class BaseDocumentFactory(factory.django.DjangoModelFactory): rev = '00' std_level_id = None # type: Optional[str] intended_std_level_id = None - time = datetime.datetime.now() + time = timezone.now() expires = factory.LazyAttribute(lambda o: o.time+datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)) pages = factory.fuzzy.FuzzyInteger(2,400) @@ -357,7 +358,8 @@ class TelechatDocEventFactory(DocEventFactory): class Meta: model = TelechatDocEvent - telechat_date = datetime.datetime.today()+datetime.timedelta(days=14) + # note: this is evaluated at import time and not updated - all events will have the same telechat_date + telechat_date = timezone.now()+datetime.timedelta(days=14) type = 'scheduled_for_telechat' class NewRevisionDocEventFactory(DocEventFactory): @@ -410,7 +412,7 @@ class IRSGBallotDocEventFactory(BallotDocEventFactory): class Meta: model = IRSGBallotDocEvent - duedate = datetime.datetime.now() + datetime.timedelta(days=14) + duedate = timezone.now() + datetime.timedelta(days=14) ballot_type = factory.SubFactory(BallotTypeFactory, slug='irsg-approve') class BallotPositionDocEventFactory(DocEventFactory): diff --git a/ietf/doc/feeds.py b/ietf/doc/feeds.py index 1169db105..cddc3329b 100644 --- a/ietf/doc/feeds.py +++ b/ietf/doc/feeds.py @@ -10,6 +10,7 @@ from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed from django.urls import reverse as urlreverse from django.template.defaultfilters import truncatewords, truncatewords_html, date as datefilter from django.template.defaultfilters import linebreaks # type: ignore +from django.utils import timezone from django.utils.html import strip_tags from ietf.doc.models import Document, State, LastCallDocEvent, DocEvent @@ -135,7 +136,7 @@ class RfcFeed(Feed): if self.year: rfc_events = DocEvent.objects.filter(type='published_rfc',time__year=self.year).order_by('-time') else: - cutoff = datetime.datetime.now() - datetime.timedelta(days=8) + cutoff = timezone.now() - datetime.timedelta(days=8) rfc_events = DocEvent.objects.filter(type='published_rfc',time__gte=cutoff).order_by('-time') results = [(e.doc, e.time) for e in rfc_events] for doc,time in results: diff --git a/ietf/doc/mails.py b/ietf/doc/mails.py index 0f344f015..ddc669ed8 100644 --- a/ietf/doc/mails.py +++ b/ietf/doc/mails.py @@ -10,6 +10,7 @@ from django.template.loader import render_to_string from django.utils.html import strip_tags from django.conf import settings from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.encoding import force_text import debug # pyflakes:ignore @@ -418,7 +419,7 @@ def generate_issue_ballot_mail(request, doc, ballot): e = doc.latest_event(LastCallDocEvent, type="sent_last_call") last_call_expires = e.expires if e else None - last_call_has_expired = last_call_expires and last_call_expires < datetime.datetime.now() + last_call_has_expired = last_call_expires and last_call_expires < timezone.now() return render_to_string("doc/mail/issue_iesg_ballot_mail.txt", dict(doc=doc, @@ -437,7 +438,7 @@ def _send_irsg_ballot_email(request, doc, ballot, subject, template): (to, cc) = gather_address_lists('irsg_ballot_issued', doc=doc) sender = 'IESG Secretary ' - ballot_expired = ballot.duedate < datetime.datetime.now() + ballot_expired = ballot.duedate < timezone.now() active_ballot = doc.active_ballot() if active_ballot is None: needed_bps = '' diff --git a/ietf/doc/management/commands/generate_draft_aliases.py b/ietf/doc/management/commands/generate_draft_aliases.py index 796e3db63..88f4aa98c 100755 --- a/ietf/doc/management/commands/generate_draft_aliases.py +++ b/ietf/doc/management/commands/generate_draft_aliases.py @@ -16,6 +16,7 @@ from tempfile import mkstemp from django.conf import settings from django.core.management.base import BaseCommand +from django.utils import timezone import debug # pyflakes:ignore @@ -101,7 +102,7 @@ class Command(BaseCommand): 'that have seen activity in the last %s years.' % (DEFAULT_YEARS)) def handle(self, *args, **options): - show_since = datetime.datetime.now() - datetime.timedelta(DEFAULT_YEARS*365) + show_since = timezone.now() - datetime.timedelta(DEFAULT_YEARS*365) date = time.strftime("%Y-%m-%d_%H:%M:%S") signature = '# Generated by %s at %s\n' % (os.path.abspath(__file__), date) diff --git a/ietf/doc/management/commands/generate_draft_bibxml_files.py b/ietf/doc/management/commands/generate_draft_bibxml_files.py index 8bdaa0a86..218430806 100644 --- a/ietf/doc/management/commands/generate_draft_bibxml_files.py +++ b/ietf/doc/management/commands/generate_draft_bibxml_files.py @@ -11,6 +11,7 @@ import sys from django.conf import settings from django.core.management.base import BaseCommand from django.template.loader import render_to_string +from django.utils import timezone import debug # pyflakes:ignore @@ -68,7 +69,7 @@ class Command(BaseCommand): if process_all: doc_events = NewRevisionDocEvent.objects.filter(type='new_revision', doc__type_id='draft') else: - start = datetime.datetime.now() - datetime.timedelta(days=days) + start = timezone.now() - datetime.timedelta(days=days) doc_events = NewRevisionDocEvent.objects.filter(type='new_revision', doc__type_id='draft', time__gte=start) doc_events = doc_events.order_by('time') diff --git a/ietf/doc/migrations/0045_use_timezone_now_for_doc_models.py b/ietf/doc/migrations/0045_use_timezone_now_for_doc_models.py new file mode 100644 index 000000000..152f0d4c2 --- /dev/null +++ b/ietf/doc/migrations/0045_use_timezone_now_for_doc_models.py @@ -0,0 +1,39 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0044_procmaterials_states'), + ] + + operations = [ + migrations.AlterField( + model_name='deletedevent', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='docevent', + name='time', + field=models.DateTimeField(db_index=True, default=django.utils.timezone.now, help_text='When the event happened'), + ), + migrations.AlterField( + model_name='dochistory', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='document', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='documentactionholder', + name='time_added', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index 23a2403bf..b0e7fca25 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -18,6 +18,7 @@ from django.core.validators import URLValidator, RegexValidator from django.urls import reverse as urlreverse from django.contrib.contenttypes.models import ContentType from django.conf import settings +from django.utils import timezone from django.utils.encoding import force_text from django.utils.html import mark_safe # type:ignore @@ -85,7 +86,7 @@ IESG_SUBSTATE_TAGS = ('ad-f-up', 'need-rev', 'extpty') class DocumentInfo(models.Model): """Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement""" - time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True + time = models.DateTimeField(default=timezone.now) # should probably have auto_now=True type = ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ... title = models.CharField(max_length=255, validators=[validate_no_control_chars, ]) @@ -682,7 +683,7 @@ class DocumentActionHolder(models.Model): """Action holder for a document""" document = ForeignKey('Document') person = ForeignKey(Person) - time_added = models.DateTimeField(default=datetime.datetime.now) + time_added = models.DateTimeField(default=timezone.now) CLEAR_ACTION_HOLDERS_STATES = ['approved', 'ann', 'rfcqueue', 'pub', 'dead'] # draft-iesg state slugs GROUP_ROLES_OF_INTEREST = ['chair', 'techadv', 'editor', 'secr'] @@ -838,7 +839,7 @@ class Document(DocumentInfo): def previous_telechat_date(self): "Return the most recent telechat date in the past, if any (even if there's another in the future)" - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat", telechat_date__lt=datetime.datetime.now()) + e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat", telechat_date__lt=timezone.now()) return e.telechat_date if e else None def request_closed_time(self, review_req): @@ -1208,7 +1209,7 @@ EVENT_TYPES = [ class DocEvent(models.Model): """An occurrence for a document, used for tracking who, when and what.""" - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True) + time = models.DateTimeField(default=timezone.now, help_text="When the event happened", db_index=True) type = models.CharField(max_length=50, choices=EVENT_TYPES) by = ForeignKey(Person) doc = ForeignKey(Document) @@ -1388,7 +1389,7 @@ class DeletedEvent(models.Model): content_type = ForeignKey(ContentType) json = models.TextField(help_text="Deleted object in JSON format, with attribute names chosen to be suitable for passing into the relevant create method.") by = ForeignKey(Person) - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) def __str__(self): return u"%s by %s %s" % (self.content_type, self.by, self.time) diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index d2450fa62..2277e478d 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -18,6 +18,7 @@ from django.urls import reverse as urlreverse from django.core.cache import cache from django.core.exceptions import ValidationError from django.urls import NoReverseMatch +from django.utils import timezone import debug # pyflakes:ignore @@ -318,7 +319,7 @@ def timesince_days(date): """Returns the number of days since 'date' (relative to now)""" if date.__class__ is not datetime.datetime: date = datetime.datetime(date.year, date.month, date.day) - delta = datetime.datetime.now() - date + delta = timezone.now() - date return delta.days @register.filter @@ -637,19 +638,19 @@ def action_holder_badge(action_holder): >>> action_holder_badge(DocumentActionHolderFactory()) '' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=15))) + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=15))) '' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=16))) + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=16))) ' 16' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=30))) + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=30))) ' 30' >>> settings.DOC_ACTION_HOLDER_AGE_LIMIT_DAYS = old_limit """ age_limit = settings.DOC_ACTION_HOLDER_AGE_LIMIT_DAYS - age = (datetime.datetime.now() - action_holder.time_added).days + age = (timezone.now() - action_holder.time_added).days if age > age_limit: return mark_safe( ' %d' diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py index e01b5e0bd..c201e7f2d 100644 --- a/ietf/doc/tests.py +++ b/ietf/doc/tests.py @@ -25,6 +25,7 @@ from django.conf import settings from django.forms import Form from django.utils.html import escape from django.test import override_settings +from django.utils import timezone from django.utils.text import slugify from tastypie.test import ResourceTestCaseMixin @@ -385,13 +386,13 @@ class SearchTests(TestCase): # Three drafts to show with various warnings drafts = WgDraftFactory.create_batch(3,states=[('draft','active'),('draft-iesg','ad-eval')]) for index, draft in enumerate(drafts): - StateDocEventFactory(doc=draft, state=('draft-iesg','ad-eval'), time=datetime.datetime.now()-datetime.timedelta(days=[1,15,29][index])) + StateDocEventFactory(doc=draft, state=('draft-iesg','ad-eval'), time=timezone.now()-datetime.timedelta(days=[1,15,29][index])) draft.action_holders.set([PersonFactory()]) # And one draft that should not show (with the default of 7 days to view) old = WgDraftFactory() - old.docevent_set.filter(newrevisiondocevent__isnull=False).update(time=datetime.datetime.now()-datetime.timedelta(days=8)) - StateDocEventFactory(doc=old, time=datetime.datetime.now()-datetime.timedelta(days=8)) + old.docevent_set.filter(newrevisiondocevent__isnull=False).update(time=timezone.now()-datetime.timedelta(days=8)) + StateDocEventFactory(doc=old, time=timezone.now()-datetime.timedelta(days=8)) url = urlreverse('ietf.doc.views_search.recent_drafts') r = self.client.get(url) @@ -764,7 +765,7 @@ Man Expires September 22, 2015 [Page 3] replacement = WgDraftFactory( name="draft-ietf-replacement", - time=datetime.datetime.now(), + time=timezone.now(), title="Replacement Draft", stream_id=draft.stream_id, group_id=draft.group_id, abstract=draft.abstract,stream=draft.stream, rev=draft.rev, pages=draft.pages, intended_std_level_id=draft.intended_std_level_id, @@ -1580,7 +1581,7 @@ class DocTestCase(TestCase): name = "session-72-mars-1", meeting = Meeting.objects.get(number='72'), group = Group.objects.get(acronym='mars'), - modified = datetime.datetime.now(), + modified = timezone.now(), add_to_schedule=False, ) SchedulingEvent.objects.create( @@ -1610,7 +1611,7 @@ class DocTestCase(TestCase): type="changed_ballot_position", pos_id="yes", comment="Looks fine to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -1644,7 +1645,7 @@ class DocTestCase(TestCase): type="changed_ballot_position", pos_id="noobj", comment="Still looks okay to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -1666,7 +1667,7 @@ class DocTestCase(TestCase): type="changed_ballot_position", pos_id="yes", comment="Looks fine to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -2043,7 +2044,7 @@ class GenerateDraftAliasesTests(TestCase): super().tearDown() def testManagementCommand(self): - a_month_ago = datetime.datetime.now() - datetime.timedelta(30) + a_month_ago = timezone.now() - datetime.timedelta(30) ad = RoleFactory(name_id='ad', group__type_id='area', group__state_id='active').person shepherd = PersonFactory() author1 = PersonFactory() diff --git a/ietf/doc/tests_ballot.py b/ietf/doc/tests_ballot.py index 317e4e3a1..163a98a46 100644 --- a/ietf/doc/tests_ballot.py +++ b/ietf/doc/tests_ballot.py @@ -12,6 +12,7 @@ import debug # pyflakes:ignore from django.test import RequestFactory from django.utils.text import slugify from django.urls import reverse as urlreverse +from django.utils import timezone from ietf.doc.models import (Document, State, DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, TelechatDocEvent) @@ -105,7 +106,7 @@ class EditPositionTests(TestCase): draft = WgDraftFactory(ad=ad) url = urlreverse('ietf.doc.views_ballot.api_set_position') create_ballot_if_not_open(None, draft, ad, 'approve') - ad.user.last_login = datetime.datetime.now() + ad.user.last_login = timezone.now() ad.user.save() apikey = PersonalApiKey.objects.create(endpoint=url, person=ad) @@ -238,9 +239,9 @@ class EditPositionTests(TestCase): doc=draft, rev=draft.rev, type="changed_ballot_position", by=ad, balloter=ad, ballot=ballot, pos=BallotPositionName.objects.get(slug="discuss"), discuss="This draft seems to be lacking a clearer title?", - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), comment="Test!", - comment_time=datetime.datetime.now()) + comment_time=timezone.now()) url = urlreverse('ietf.doc.views_ballot.send_ballot_comment', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) @@ -466,7 +467,7 @@ class BallotWriteupsTests(TestCase): doc=draft, rev=draft.rev, desc='issued last call', - expires = datetime.datetime.now()+datetime.timedelta(days = 1 if case=='future' else -1) + expires = timezone.now()+datetime.timedelta(days = 1 if case=='future' else -1) ) url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "ad", url) @@ -791,7 +792,7 @@ class ApproveBallotTests(TestCase): doc=draft, rev=draft.rev, desc='issued last call', - expires = datetime.datetime.now()-datetime.timedelta(days=14) ) + expires = timezone.now()-datetime.timedelta(days=14) ) WriteupDocEvent.objects.create( by=Person.objects.get(name='(System)'), doc=draft, @@ -1117,7 +1118,7 @@ class RegenerateLastCallTestCase(TestCase): class BallotContentTests(TestCase): def test_ballotpositiondocevent_any_email_sent(self): - now = datetime.datetime.now() # be sure event timestamps are at distinct times + now = timezone.now() # be sure event timestamps are at distinct times bpde_with_null_send_email = BallotPositionDocEventFactory( time=now - datetime.timedelta(minutes=30), send_email=None, @@ -1219,7 +1220,7 @@ class BallotContentTests(TestCase): balloter=balloters[0], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=True, ) BallotPositionDocEventFactory( @@ -1227,7 +1228,7 @@ class BallotContentTests(TestCase): balloter=balloters[1], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=True, ) @@ -1237,7 +1238,7 @@ class BallotContentTests(TestCase): balloter=balloters[2], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) BallotPositionDocEventFactory( @@ -1245,7 +1246,7 @@ class BallotContentTests(TestCase): balloter=balloters[3], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=False, ) @@ -1255,7 +1256,7 @@ class BallotContentTests(TestCase): balloter=balloters[4], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now() - datetime.timedelta(days=1), + discuss_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ) BallotPositionDocEventFactory( @@ -1263,7 +1264,7 @@ class BallotContentTests(TestCase): balloter=balloters[4], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) BallotPositionDocEventFactory( @@ -1271,7 +1272,7 @@ class BallotContentTests(TestCase): balloter=balloters[5], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now() - datetime.timedelta(days=1), + comment_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ) BallotPositionDocEventFactory( @@ -1279,7 +1280,7 @@ class BallotContentTests(TestCase): balloter=balloters[5], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=False, ) @@ -1296,7 +1297,7 @@ class BallotContentTests(TestCase): balloter__plain='plain name1', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ).balloter send_email_balloter = BallotPositionDocEventFactory( @@ -1304,7 +1305,7 @@ class BallotContentTests(TestCase): balloter__plain='plain name2', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=True, ).balloter prev_send_email_balloter = BallotPositionDocEventFactory( @@ -1312,7 +1313,7 @@ class BallotContentTests(TestCase): balloter__plain='plain name3', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now() - datetime.timedelta(days=1), + discuss_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ).balloter BallotPositionDocEventFactory( @@ -1320,7 +1321,7 @@ class BallotContentTests(TestCase): balloter=prev_send_email_balloter, pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) @@ -1351,7 +1352,7 @@ class BallotContentTests(TestCase): balloter=balloters[0], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=None, ) BallotPositionDocEventFactory( @@ -1359,7 +1360,7 @@ class BallotContentTests(TestCase): balloter=balloters[1], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=None, ) old_balloter = BallotPositionDocEventFactory( @@ -1367,7 +1368,7 @@ class BallotContentTests(TestCase): balloter__plain='plain name', # ensure plain name is slugifiable pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=None, ).balloter diff --git a/ietf/doc/tests_bofreq.py b/ietf/doc/tests_bofreq.py index 4d02108d0..9925ec3d1 100644 --- a/ietf/doc/tests_bofreq.py +++ b/ietf/doc/tests_bofreq.py @@ -14,6 +14,7 @@ from html import unescape from django.conf import settings from django.urls import reverse as urlreverse from django.template.loader import render_to_string +from django.utils import timezone from ietf.group.factories import RoleFactory from ietf.doc.factories import BofreqFactory, NewRevisionDocEventFactory @@ -48,7 +49,7 @@ This test section has some text. states = State.objects.filter(type_id='bofreq') self.assertTrue(states.count()>0) for i in range(3*len(states)): - BofreqFactory(states=[('bofreq',states[i%len(states)].slug)],newrevisiondocevent__time=datetime.datetime.today()-datetime.timedelta(days=randint(0,20))) + BofreqFactory(states=[('bofreq',states[i%len(states)].slug)],newrevisiondocevent__time=timezone.now()-datetime.timedelta(days=randint(0,20))) r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) diff --git a/ietf/doc/tests_draft.py b/ietf/doc/tests_draft.py index 3a0f0315c..91d0542ba 100644 --- a/ietf/doc/tests_draft.py +++ b/ietf/doc/tests_draft.py @@ -13,6 +13,7 @@ from pyquery import PyQuery from django.urls import reverse as urlreverse from django.conf import settings +from django.utils import timezone from django.utils.html import escape import debug # pyflakes:ignore @@ -618,7 +619,7 @@ class ResurrectTests(DraftFileMixin, TestCase): self.assertEqual(draft.docevent_set.count(), events_before + 1) self.assertEqual(draft.latest_event().type, "completed_resurrect") self.assertEqual(draft.get_state_slug(), "active") - self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) + self.assertTrue(draft.expires >= timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue('Resurrection Completed' in outbox[-1]['Subject']) self.assertTrue('iesg-secretary' in outbox[-1]['To']) @@ -659,7 +660,7 @@ class ExpireIDsTests(DraftFileMixin, TestCase): # hack into expirable state draft.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - draft.expires = datetime.datetime.now() + datetime.timedelta(days=10) + draft.expires = timezone.now() + datetime.timedelta(days=10) draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) self.assertEqual(len(list(get_soon_to_expire_drafts(14))), 1) @@ -698,7 +699,7 @@ class ExpireIDsTests(DraftFileMixin, TestCase): # hack into expirable state draft.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - draft.expires = datetime.datetime.now() + draft.expires = timezone.now() draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) self.assertEqual(len(list(get_expired_drafts())), 1) @@ -741,7 +742,7 @@ class ExpireIDsTests(DraftFileMixin, TestCase): draft.delete() - rgdraft = RgDraftFactory(expires=datetime.datetime.now()) + rgdraft = RgDraftFactory(expires=timezone.now()) self.assertEqual(len(list(get_expired_drafts())), 1) for slug in ('iesg-rev','irsgpoll'): rgdraft.set_state(State.objects.get(type_id='draft-stream-irtf',slug=slug)) @@ -791,7 +792,7 @@ class ExpireIDsTests(DraftFileMixin, TestCase): # expire draft draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) - draft.expires = datetime.datetime.now() - datetime.timedelta(days=1) + draft.expires = timezone.now() - datetime.timedelta(days=1) draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) e = DocEvent(doc=draft, rev=draft.rev, type= "expired_document", time=draft.expires, @@ -824,7 +825,7 @@ class ExpireLastCallTests(TestCase): e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" - e.expires = datetime.datetime.now() + datetime.timedelta(days=14) + e.expires = timezone.now() + datetime.timedelta(days=14) e.save() self.assertEqual(len(list(get_expired_last_calls())), 0) @@ -832,7 +833,7 @@ class ExpireLastCallTests(TestCase): # test expired e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" - e.expires = datetime.datetime.now() + e.expires = timezone.now() e.save() drafts = list(get_expired_last_calls()) @@ -866,7 +867,7 @@ class ExpireLastCallTests(TestCase): e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" e.desc = "Blah, blah, blah.\n\nThis document makes the following downward references (downrefs):\n ** Downref: Normative reference to an Experimental RFC: RFC 4764" - e.expires = datetime.datetime.now() + e.expires = timezone.now() e.save() drafts = list(get_expired_last_calls()) @@ -1730,7 +1731,7 @@ class ChangeStreamStateTests(TestCase): self.assertEqual(draft.docevent_set.count() - events_before, 2) reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") self.assertEqual(len(reminder), 1) - due = datetime.datetime.now() + datetime.timedelta(weeks=10) + due = timezone.now() + datetime.timedelta(weeks=10) self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) self.assertEqual(len(outbox), 1) self.assertTrue("state changed" in outbox[0]["Subject"].lower()) @@ -1775,7 +1776,7 @@ class ChangeStreamStateTests(TestCase): self.assertEqual(draft.docevent_set.count() - events_before, 2) reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") self.assertEqual(len(reminder), 1) - due = datetime.datetime.now() + datetime.timedelta(weeks=10) + due = timezone.now() + datetime.timedelta(weeks=10) self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) self.assertEqual(len(outbox), 1) self.assertTrue("state changed" in outbox[0]["Subject"].lower()) @@ -1826,7 +1827,7 @@ class ChangeReplacesTests(TestCase): name="draft-test-base-b", title="Base B", group=mars_wg, - expires = datetime.datetime.now() - datetime.timedelta(days = 365 - settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + expires = timezone.now() - datetime.timedelta(days = 365 - settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), ) p = PersonFactory(name="baseb_author") e = Email.objects.create(address="baseb_author@example.com", person=p, origin=p.user.username) diff --git a/ietf/doc/tests_material.py b/ietf/doc/tests_material.py index 1e922197d..05bbc2078 100644 --- a/ietf/doc/tests_material.py +++ b/ietf/doc/tests_material.py @@ -4,7 +4,6 @@ import os import shutil -import datetime import io from pathlib import Path @@ -14,6 +13,7 @@ import debug # pyflakes:ignore from django.conf import settings from django.urls import reverse as urlreverse +from django.utils import timezone from ietf.doc.models import Document, State, DocAlias, NewRevisionDocEvent from ietf.group.factories import RoleFactory @@ -155,7 +155,7 @@ class GroupMaterialTests(TestCase): name = "session-42-mars-1", meeting = Meeting.objects.get(number='42'), group = Group.objects.get(acronym='mars'), - modified = datetime.datetime.now(), + modified = timezone.now(), ) SchedulingEvent.objects.create( session=session, diff --git a/ietf/doc/tests_review.py b/ietf/doc/tests_review.py index 7e902514d..efe5b7b06 100644 --- a/ietf/doc/tests_review.py +++ b/ietf/doc/tests_review.py @@ -14,6 +14,7 @@ from requests import Response from django.apps import apps from django.urls import reverse as urlreverse from django.conf import settings +from django.utils import timezone from pyquery import PyQuery @@ -67,7 +68,7 @@ class ReviewTests(TestCase): RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') RoleFactory(group=review_team3,person__user__username='reviewsecretary3',person__user__email='reviewsecretary3@example.com',name_id='secr') - req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.request_review', kwargs={ "name": doc.name }) @@ -145,7 +146,7 @@ class ReviewTests(TestCase): doc = WgDraftFactory(group__acronym='mars',rev='01') review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request=review_req, reviewer=rev_role.person.email_set.first(), state_id='accepted') # move the review request to a doubly-replaced document to @@ -166,7 +167,7 @@ class ReviewTests(TestCase): doc = WgDraftFactory(group__acronym='mars',rev='01', authors=[author]) review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = review_req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -195,7 +196,7 @@ class ReviewTests(TestCase): rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') RoleFactory(group=review_team,person__user__username='reviewsecretary2',person__user__email='reviewsecretary2@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request=review_req, state_id='accepted', reviewer=rev_role.person.email_set.first()) close_url = urlreverse('ietf.doc.views_review.close_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -260,7 +261,7 @@ class ReviewTests(TestCase): # previous review req = ReviewRequestFactory( - time=datetime.datetime.now() - datetime.timedelta(days=100), + time=timezone.now() - datetime.timedelta(days=100), requested_by=Person.objects.get(name="(System)"), doc=doc, type_id='early', @@ -372,7 +373,7 @@ class ReviewTests(TestCase): doc = WgDraftFactory(group__acronym='mars',rev='01') review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request=review_req, state_id='assigned', reviewer=rev_role.person.email_set.first()) url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -395,7 +396,7 @@ class ReviewTests(TestCase): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request = review_req, reviewer=rev_role.person.email_set.first(), state_id='accepted') reject_url = urlreverse('ietf.doc.views_review.reject_reviewer_assignment', kwargs={ "name": doc.name, "assignment_id": assignment.pk }) @@ -495,7 +496,7 @@ class ReviewTests(TestCase): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request=review_req, reviewer=rev_role.person.email_set.first(), state_id='accepted') # test URL construction @@ -587,7 +588,7 @@ class ReviewTests(TestCase): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request=review_req, state_id='accepted', reviewer=rev_role.person.email_set.first()) for r in ReviewResultName.objects.filter(slug__in=("issues", "ready")): review_req.team.reviewteamsettings.review_results.add(r) @@ -699,7 +700,7 @@ class ReviewTests(TestCase): assignment = reload_db_objects(assignment) self.assertEqual(assignment.state_id, "completed") # Completed time should be close to now, but will not be exactly, so check within 10s margin - completed_time_diff = datetime.datetime.now() - assignment.completed_on + completed_time_diff = timezone.now() - assignment.completed_on self.assertLess(completed_time_diff, datetime.timedelta(seconds=10)) with io.open(os.path.join(self.review_subdir, assignment.review.name + ".txt")) as f: @@ -739,7 +740,7 @@ class ReviewTests(TestCase): # - the event logging when the change when it was entered, i.e. very close to now. # - the completion of the review, set to the provided date/time events = ReviewAssignmentDocEvent.objects.filter(doc=assignment.review_request.doc).order_by('-time') - event0_time_diff = datetime.datetime.now() - events[0].time + event0_time_diff = timezone.now() - events[0].time self.assertLess(event0_time_diff, datetime.timedelta(seconds=10)) self.assertEqual(events[1].time, datetime.datetime(2012, 12, 24, 12, 13, 14)) @@ -985,7 +986,7 @@ class ReviewTests(TestCase): self.assertEqual(assignment.state_id, "completed") # The revision event time should be the date the revision was submitted, i.e. not backdated event1 = assignment.review_request.doc.latest_event(ReviewAssignmentDocEvent) - event_time_diff = datetime.datetime.now() - event1.time + event_time_diff = timezone.now() - event1.time self.assertLess(event_time_diff, datetime.timedelta(seconds=10)) self.assertTrue('revised' in event1.desc.lower()) @@ -1012,7 +1013,7 @@ class ReviewTests(TestCase): assignment = reload_db_objects(assignment) self.assertEqual(assignment.review.rev, "01") event2 = assignment.review_request.doc.latest_event(ReviewAssignmentDocEvent) - event_time_diff = datetime.datetime.now() - event2.time + event_time_diff = timezone.now() - event2.time self.assertLess(event_time_diff, datetime.timedelta(seconds=10)) # Ensure that a new event was created for the new revision (#2590) self.assertNotEqual(event1.id, event2.id) @@ -1024,7 +1025,7 @@ class ReviewTests(TestCase): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = review_req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.edit_comment', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -1046,7 +1047,7 @@ class ReviewTests(TestCase): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='accepted',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='accepted',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = review_req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.edit_deadline', kwargs={ "name": doc.name, "request_id": review_req.pk }) diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index f9ea81387..c83fa7cf6 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -18,6 +18,7 @@ from django.conf import settings from django.contrib import messages from django.forms import ValidationError from django.template.loader import render_to_string +from django.utils import timezone from django.utils.html import escape from django.urls import reverse as urlreverse @@ -807,7 +808,7 @@ def set_replaces_for_document(request, doc, new_replaces, by, email_subject, com cc.update(other_addrs.cc) RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete() if not RelatedDocument.objects.filter(target=d, relationship=relationship): - s = 'active' if d.document.expires > datetime.datetime.now() else 'expired' + s = 'active' if d.document.expires > timezone.now() else 'expired' d.document.set_state(State.objects.get(type='draft', slug=s)) for d in new_replaces: @@ -1118,7 +1119,7 @@ def build_doc_meta_block(doc, path): lines[i] = line return lines # - now = datetime.datetime.now() + now = timezone.now() draft_state = doc.get_state('draft') block = '' meta = {} diff --git a/ietf/doc/utils_charter.py b/ietf/doc/utils_charter.py index ce9552106..43982deab 100644 --- a/ietf/doc/utils_charter.py +++ b/ietf/doc/utils_charter.py @@ -11,6 +11,7 @@ import shutil from django.conf import settings from django.urls import reverse as urlreverse from django.template.loader import render_to_string +from django.utils import timezone from django.utils.encoding import smart_text, force_text import debug # pyflakes:ignore @@ -73,7 +74,7 @@ def change_group_state_after_charter_approval(group, by): save_group_in_history(group) group.state = new_state - group.time = datetime.datetime.now() + group.time = timezone.now() group.save() # create an event for the group state change, too @@ -132,7 +133,7 @@ def historic_milestones_for_charter(charter, rev): # revision (when approving a charter) just_before_next_rev = e[0].time - datetime.timedelta(seconds=5) else: - just_before_next_rev = datetime.datetime.now() + just_before_next_rev = timezone.now() res = [] if hasattr(charter, 'chartered_group'): @@ -197,7 +198,7 @@ def derive_new_work_text(review_text,group): return smart_text(m.as_string()) def default_review_text(group, charter, by): - now = datetime.datetime.now() + now = timezone.now() addrs = gather_address_lists('charter_external_review',group=group).as_strings(compact=False) e1 = WriteupDocEvent(doc=charter, rev=charter.rev, by=by) diff --git a/ietf/doc/views_charter.py b/ietf/doc/views_charter.py index c2b88ac47..3f85a19ce 100644 --- a/ietf/doc/views_charter.py +++ b/ietf/doc/views_charter.py @@ -16,6 +16,7 @@ from django.utils.safestring import mark_safe from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required +from django.utils import timezone from django.utils.encoding import force_text from django.utils.html import escape @@ -77,7 +78,7 @@ def change_state(request, name, option=None): chartering_type = get_chartering_type(charter) initial_review = charter.latest_event(InitialReviewDocEvent, type="initial_review") - if charter.get_state_slug() != "infrev" or (initial_review and initial_review.expires < datetime.datetime.now()) or chartering_type == "rechartering": + if charter.get_state_slug() != "infrev" or (initial_review and initial_review.expires < timezone.now()) or chartering_type == "rechartering": initial_review = None by = request.user.person @@ -183,7 +184,7 @@ def change_state(request, name, option=None): if charter_state.slug == "infrev" and clean["initial_time"] and clean["initial_time"] != 0: e = InitialReviewDocEvent(type="initial_review", by=by, doc=charter, rev=charter.rev) - e.expires = datetime.datetime.now() + datetime.timedelta(weeks=clean["initial_time"]) + e.expires = timezone.now() + datetime.timedelta(weeks=clean["initial_time"]) e.desc = "Initial review time expires %s" % e.expires.strftime("%Y-%m-%d") e.save() @@ -506,7 +507,7 @@ def review_announcement_text(request, name): existing_new_work.type = "changed_new_work_text" existing_new_work.desc = "%s review text was changed" % group.type.name existing_new_work.text = derive_new_work_text(existing.text,group) - existing_new_work.time = datetime.datetime.now() + existing_new_work.time = timezone.now() form = ReviewAnnouncementTextForm(initial=dict(announcement_text=escape(existing.text),new_work_text=escape(existing_new_work.text))) @@ -514,7 +515,7 @@ def review_announcement_text(request, name): form = ReviewAnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): - now = datetime.datetime.now() + now = timezone.now() events = [] t = form.cleaned_data['announcement_text'] diff --git a/ietf/doc/views_draft.py b/ietf/doc/views_draft.py index e0d73855b..5d445cfc2 100644 --- a/ietf/doc/views_draft.py +++ b/ietf/doc/views_draft.py @@ -19,6 +19,7 @@ from django.shortcuts import render, get_object_or_404, redirect from django.template.loader import render_to_string from django.forms.utils import ErrorList from django.template.defaultfilters import pluralize +from django.utils import timezone import debug # pyflakes:ignore @@ -857,7 +858,7 @@ def resurrect(request, name): events.append(e) doc.set_state(State.objects.get(used=True, type="draft", slug="active")) - doc.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) + doc.expires = timezone.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) doc.save_with_history(events) restore_draft_file(request, doc) diff --git a/ietf/doc/views_review.py b/ietf/doc/views_review.py index c7d8e5804..19c822ec9 100644 --- a/ietf/doc/views_review.py +++ b/ietf/doc/views_review.py @@ -10,7 +10,9 @@ import datetime import requests import email.utils +from django.utils import timezone from django.utils.http import is_safe_url + from simple_history.utils import update_change_reason import debug # pyflakes:ignore @@ -117,7 +119,7 @@ def request_review(request, name): if not can_request_review_of_doc(request.user, doc): permission_denied(request, "You do not have permission to perform this action") - now = datetime.datetime.now() + now = timezone.now() lc_ends = None e = doc.latest_event(LastCallDocEvent, type="sent_last_call") @@ -364,7 +366,7 @@ def reject_reviewer_assignment(request, name, assignment_id): if form.is_valid(): # reject the assignment review_assignment.state = ReviewAssignmentStateName.objects.get(slug="rejected") - review_assignment.completed_on = datetime.datetime.now() + review_assignment.completed_on = timezone.now() review_assignment.save() descr = "Assignment of request for {} review by {} to {} was rejected".format( @@ -731,13 +733,13 @@ def complete_review(request, name, assignment_id=None, acronym=None): review_request=review_request, state_id='assigned', reviewer=form.cleaned_data['reviewer'].role_email('reviewer', group=team), - assigned_on=datetime.datetime.now(), + assigned_on=timezone.now(), review = review, ) review.rev = "00" if not review.rev else "{:02}".format(int(review.rev) + 1) review.title = "{} Review of {}-{}".format(assignment.review_request.type.name, assignment.review_request.doc.name, form.cleaned_data["reviewed_rev"]) - review.time = datetime.datetime.now() + review.time = timezone.now() if review_submission == "link": review.external_url = form.cleaned_data['review_url'] @@ -764,7 +766,7 @@ def complete_review(request, name, assignment_id=None, acronym=None): with io.open(filename, 'w', encoding='utf-8') as destination: destination.write(content) - completion_datetime = datetime.datetime.now() + completion_datetime = timezone.now() if "completion_date" in form.cleaned_data: completion_datetime = datetime.datetime.combine(form.cleaned_data["completion_date"], form.cleaned_data.get("completion_time") or datetime.time.min) @@ -799,7 +801,7 @@ def complete_review(request, name, assignment_id=None, acronym=None): close_event.by = request.user.person close_event.desc = desc close_event.state = assignment.state - close_event.time = datetime.datetime.now() + close_event.time = timezone.now() close_event.save() # If the completion date is different, record when the initial review was made too. diff --git a/ietf/doc/views_search.py b/ietf/doc/views_search.py index 057f568b3..74bb30587 100644 --- a/ietf/doc/views_search.py +++ b/ietf/doc/views_search.py @@ -44,6 +44,7 @@ from django.urls import reverse as urlreverse from django.db.models import Q from django.http import Http404, HttpResponseBadRequest, HttpResponse, HttpResponseRedirect, QueryDict from django.shortcuts import render +from django.utils import timezone from django.utils.cache import _generate_cache_key # type: ignore @@ -419,7 +420,7 @@ def ad_dashboard_sort_key(doc): ageseconds = 0 changetime= doc.latest_event(type='changed_document') if changetime: - ad = (datetime.datetime.now()-doc.latest_event(type='changed_document').time) + ad = (timezone.now()-doc.latest_event(type='changed_document').time) ageseconds = (ad.microseconds + (ad.seconds + ad.days * 24 * 3600) * 10**6) / 10**6 return "1%d%s%s%010d" % (state[0].order,seed,doc.type.slug,ageseconds) @@ -627,7 +628,7 @@ def recent_drafts(request, days=7): cache_key = f'recentdraftsview{days}' cached_val = slowcache.get(cache_key) if not cached_val: - since = datetime.datetime.now()-datetime.timedelta(days=days) + since = timezone.now()-datetime.timedelta(days=days) state = State.objects.get(type='draft', slug='active') events = NewRevisionDocEvent.objects.filter(time__gt=since) names = [ e.doc.name for e in events ] diff --git a/ietf/group/factories.py b/ietf/group/factories.py index d8d927d80..e7fbef59a 100644 --- a/ietf/group/factories.py +++ b/ietf/group/factories.py @@ -5,6 +5,8 @@ import factory from typing import List # pyflakes:ignore +from django.utils import timezone + from ietf.group.models import Group, Role, GroupEvent, GroupMilestone, \ GroupHistory, RoleHistory from ietf.review.factories import ReviewTeamSettingsFactory @@ -66,7 +68,7 @@ class BaseGroupMilestoneFactory(factory.django.DjangoModelFactory): class DatedGroupMilestoneFactory(BaseGroupMilestoneFactory): group = factory.SubFactory(GroupFactory, uses_milestone_dates=True) - due = datetime.datetime.today()+datetime.timedelta(days=180) + due = timezone.now()+datetime.timedelta(days=180) class DatelessGroupMilestoneFactory(BaseGroupMilestoneFactory): group = factory.SubFactory(GroupFactory, uses_milestone_dates=False) diff --git a/ietf/group/management/commands/generate_group_aliases.py b/ietf/group/management/commands/generate_group_aliases.py index 50802b3cf..132fef753 100755 --- a/ietf/group/management/commands/generate_group_aliases.py +++ b/ietf/group/management/commands/generate_group_aliases.py @@ -15,6 +15,7 @@ from tempfile import mkstemp from django.conf import settings from django.core.management.base import BaseCommand +from django.utils import timezone import debug # pyflakes:ignore @@ -39,7 +40,7 @@ class Command(BaseCommand): 'have seen activity in the last %s years.' % (DEFAULT_YEARS)) def handle(self, *args, **options): - show_since = datetime.datetime.now() - datetime.timedelta(DEFAULT_YEARS*365) + show_since = timezone.now() - datetime.timedelta(DEFAULT_YEARS*365) date = time.strftime("%Y-%m-%d_%H:%M:%S") signature = '# Generated by %s at %s\n' % (os.path.abspath(__file__), date) diff --git a/ietf/group/migrations/0059_use_timezone_now_for_group_models.py b/ietf/group/migrations/0059_use_timezone_now_for_group_models.py new file mode 100644 index 000000000..24c083855 --- /dev/null +++ b/ietf/group/migrations/0059_use_timezone_now_for_group_models.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0058_alter_has_default_chat'), + ] + + operations = [ + migrations.AlterField( + model_name='group', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='groupevent', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='When the event happened'), + ), + migrations.AlterField( + model_name='grouphistory', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/ietf/group/models.py b/ietf/group/models.py index 899c88241..fd665e6b3 100644 --- a/ietf/group/models.py +++ b/ietf/group/models.py @@ -13,6 +13,7 @@ from django.core.validators import RegexValidator from django.db import models from django.db.models.deletion import CASCADE, PROTECT from django.dispatch import receiver +from django.utils import timezone import debug # pyflakes:ignore @@ -27,7 +28,7 @@ from ietf.utils.validators import JSONForeignKeyListValidator class GroupInfo(models.Model): - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) name = models.CharField(max_length=80) state = ForeignKey(GroupStateName, null=True) type = ForeignKey(GroupTypeName, null=True) @@ -353,7 +354,7 @@ GROUP_EVENT_CHOICES = [ class GroupEvent(models.Model): """An occurrence for a group, used for tracking who, when and what.""" group = ForeignKey(Group) - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened") + time = models.DateTimeField(default=timezone.now, help_text="When the event happened") type = models.CharField(max_length=50, choices=GROUP_EVENT_CHOICES) by = ForeignKey(Person) desc = models.TextField() diff --git a/ietf/group/tests.py b/ietf/group/tests.py index b168e4d3b..2c63ff95d 100644 --- a/ietf/group/tests.py +++ b/ietf/group/tests.py @@ -13,6 +13,7 @@ from django.conf import settings from django.urls import reverse as urlreverse from django.db.models import Q from django.test import Client +from django.utils import timezone import debug # pyflakes:ignore @@ -115,8 +116,8 @@ class GenerateGroupAliasesTests(TestCase): super().tearDown() def testManagementCommand(self): - a_month_ago = datetime.datetime.now() - datetime.timedelta(30) - a_decade_ago = datetime.datetime.now() - datetime.timedelta(3650) + a_month_ago = timezone.now() - datetime.timedelta(30) + a_decade_ago = timezone.now() - datetime.timedelta(3650) role1 = RoleFactory(name_id='ad', group__type_id='area', group__acronym='myth', group__state_id='active') area = role1.group ad = role1.person diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py index 0b3ead2c7..932b0594e 100644 --- a/ietf/group/tests_info.py +++ b/ietf/group/tests_info.py @@ -1900,7 +1900,7 @@ class StatusUpdateTests(TestCase): def test_view_status_update_for_meeting(self): chair = RoleFactory(name_id='chair',group__type_id='wg') GroupEventFactory(type='status_update',group=chair.group) - sess = SessionFactory.create(meeting__type_id='ietf',group=chair.group,meeting__date=datetime.datetime.today()-datetime.timedelta(days=1)) + sess = SessionFactory.create(meeting__type_id='ietf',group=chair.group,meeting__date=timezone.now()-datetime.timedelta(days=1)) url = urlreverse('ietf.group.views.group_about_status_meeting',kwargs={'acronym':chair.group.acronym,'num':sess.meeting.number}) response = self.client.get(url) self.assertEqual(response.status_code,200) diff --git a/ietf/group/tests_review.py b/ietf/group/tests_review.py index ee4ae96fe..924f6fade 100644 --- a/ietf/group/tests_review.py +++ b/ietf/group/tests_review.py @@ -8,6 +8,7 @@ import debug # pyflakes:ignore from pyquery import PyQuery from django.urls import reverse as urlreverse +from django.utils import timezone from ietf.review.policies import get_reviewer_queue_policy from ietf.utils.test_utils import login_testing_unauthorized, TestCase, reload_db_objects @@ -131,7 +132,7 @@ class ReviewTests(TestCase): doc.states.add(State.objects.get(type="draft-iesg", slug="lc", used=True)) LastCallDocEvent.objects.create( doc=doc, - expires=datetime.datetime.now() + datetime.timedelta(days=365), + expires=timezone.now() + datetime.timedelta(days=365), by=Person.objects.get(name="(System)"), rev=doc.rev ) @@ -429,7 +430,7 @@ class ReviewTests(TestCase): doc.states.add(State.objects.get(type="draft-iesg", slug="lc", used=True)) LastCallDocEvent.objects.create( doc=doc, - expires=datetime.datetime.now() + datetime.timedelta(days=365), + expires=timezone.now() + datetime.timedelta(days=365), by=Person.objects.get(name="(System)"), rev=doc.rev ) diff --git a/ietf/group/views.py b/ietf/group/views.py index 3a4b9f3e0..338defe5e 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -53,6 +53,7 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404, JsonRespons from django.shortcuts import render, redirect, get_object_or_404 from django.template.loader import render_to_string from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.html import escape from django.views.decorators.cache import cache_page, cache_control @@ -566,7 +567,7 @@ def all_status(request): if e: wg_reports.append(e) - wg_reports.sort(key=lambda x: (x.group.parent.acronym,datetime.datetime.now()-x.time)) + wg_reports.sort(key=lambda x: (x.group.parent.acronym,timezone.now()-x.time)) rg_reports = [] for rg in rgs: @@ -808,7 +809,7 @@ def email_aliases(request, acronym=None, group_type=None): def meetings(request, acronym=None, group_type=None): group = get_group_or_404(acronym,group_type) if acronym else None - four_years_ago = datetime.datetime.now()-datetime.timedelta(days=4*365) + four_years_ago = timezone.now()-datetime.timedelta(days=4*365) sessions = add_event_info_to_session_qs( group.session_set.filter( @@ -972,7 +973,7 @@ def edit(request, group_type=None, acronym=None, action="edit", field=None): try: group = Group.objects.get(acronym=clean["acronym"]) save_group_in_history(group) - group.time = datetime.datetime.now() + group.time = timezone.now() group.save() except Group.DoesNotExist: group = Group.objects.create(name=clean["name"], @@ -1071,7 +1072,7 @@ def edit(request, group_type=None, acronym=None, action="edit", field=None): ) )) - group.time = datetime.datetime.now() + group.time = timezone.now() if changes and not new_group: for attr, new, desc in changes: @@ -1509,7 +1510,7 @@ def reviewer_overview(request, acronym, group_type=None): int(math.ceil(d.assignment_to_closure_days)) if d.assignment_to_closure_days is not None else None)) if d.state in ["completed", "completed_in_time", "completed_late"]: if d.assigned_time is not None: - delta = datetime.datetime.now() - d.assigned_time + delta = timezone.now() - d.assigned_time if d.assignment_to_closure_days is not None: days = int(delta.days - d.assignment_to_closure_days) if days_since > days: days_since = days diff --git a/ietf/idindex/index.py b/ietf/idindex/index.py index 3d17b197c..782e8912e 100644 --- a/ietf/idindex/index.py +++ b/ietf/idindex/index.py @@ -11,6 +11,7 @@ import pytz from django.conf import settings from django.template.loader import render_to_string +from django.utils import timezone import debug # pyflakes:ignore @@ -296,6 +297,6 @@ def id_index_txt(with_abstracts=False): return render_to_string("idindex/id_index.txt", { 'groups': groups, - 'time': datetime.datetime.now(pytz.UTC).strftime("%Y-%m-%d %H:%M:%S %Z"), + 'time': timezone.now().astimezone(pytz.utc).strftime("%Y-%m-%d %H:%M:%S %Z"), 'with_abstracts': with_abstracts, }) diff --git a/ietf/idindex/tests.py b/ietf/idindex/tests.py index 413e3a4ed..f207fa562 100644 --- a/ietf/idindex/tests.py +++ b/ietf/idindex/tests.py @@ -7,6 +7,7 @@ import datetime from pathlib import Path from django.conf import settings +from django.utils import timezone import debug # pyflakes:ignore @@ -120,7 +121,7 @@ class IndexTests(TestCase): draft.set_state(State.objects.get(type="draft", slug="active")) draft.set_state(State.objects.get(type="draft-iesg", slug="lc")) - e = LastCallDocEvent.objects.create(doc=draft, rev=draft.rev, type="sent_last_call", expires=datetime.datetime.now() + datetime.timedelta(days=14), by=draft.ad) + e = LastCallDocEvent.objects.create(doc=draft, rev=draft.rev, type="sent_last_call", expires=timezone.now() + datetime.timedelta(days=14), by=draft.ad) t = get_fields(all_id2_txt()) self.assertEqual(t[11], e.expires.strftime("%Y-%m-%d")) diff --git a/ietf/ietfauth/management/commands/send_apikey_usage_emails.py b/ietf/ietfauth/management/commands/send_apikey_usage_emails.py index 4aa4e5524..d3fce1bcc 100644 --- a/ietf/ietfauth/management/commands/send_apikey_usage_emails.py +++ b/ietf/ietfauth/management/commands/send_apikey_usage_emails.py @@ -8,6 +8,7 @@ from textwrap import dedent from django.conf import settings from django.core.management.base import BaseCommand +from django.utils import timezone import debug # pyflakes:ignore @@ -37,7 +38,7 @@ class Command(BaseCommand): keys = PersonalApiKey.objects.filter(valid=True) for key in keys: - earliest = datetime.datetime.now() - datetime.timedelta(days=days) + earliest = timezone.now() - datetime.timedelta(days=days) events = PersonApiKeyEvent.objects.filter(key=key, time__gt=earliest) count = events.count() events = events[:32] diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 254c6524a..f0e01f37b 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -28,6 +28,7 @@ from django.urls import reverse as urlreverse from django.contrib.auth.models import User from django.conf import settings from django.template.loader import render_to_string +from django.utils import timezone import debug # pyflakes:ignore @@ -750,11 +751,11 @@ class IetfAuthTests(TestCase): self.assertContains(r, 'Invalid apikey', status_code=403) # too long since regular login - person.user.last_login = datetime.datetime.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS+1) + person.user.last_login = timezone.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS+1) person.user.save() r = self.client.post(key.endpoint, {'apikey':key.hash(), 'dummy':'dummy',}) self.assertContains(r, 'Too long since last regular login', status_code=400) - person.user.last_login = datetime.datetime.now() + person.user.last_login = timezone.now() person.user.save() # endpoint mismatch @@ -783,7 +784,7 @@ class IetfAuthTests(TestCase): # apikey usage will be registered) count = 2 # avoid usage across dates - if datetime.datetime.now().time() > datetime.time(hour=23, minute=59, second=58): + if timezone.now().time() > datetime.time(hour=23, minute=59, second=58): time.sleep(2) for i in range(count): for key in person.apikeys.all(): diff --git a/ietf/ipr/factories.py b/ietf/ipr/factories.py index da1262912..e32090a36 100644 --- a/ietf/ipr/factories.py +++ b/ietf/ipr/factories.py @@ -5,6 +5,7 @@ import datetime import factory +from django.utils import timezone from ietf.ipr.models import ( IprDisclosureBase, HolderIprDisclosure, ThirdPartyIprDisclosure, NonDocSpecificIprDisclosure, @@ -13,7 +14,7 @@ from ietf.ipr.models import ( def _fake_patent_info(): return "Date: %s\nNotes: %s\nTitle: %s\nNumber: %s\nInventor: %s\n" % ( - (datetime.datetime.today()-datetime.timedelta(days=365)).strftime("%Y-%m-%d"), + (timezone.now()-datetime.timedelta(days=365)).strftime("%Y-%m-%d"), factory.Faker('paragraph'), factory.Faker('sentence', nb_words=8), 'US9999999', diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py index 282f33568..2eb588b8b 100644 --- a/ietf/ipr/models.py +++ b/ietf/ipr/models.py @@ -2,11 +2,10 @@ # -*- coding: utf-8 -*- -import datetime - from django.conf import settings from django.db import models from django.urls import reverse +from django.utils import timezone from ietf.doc.models import DocAlias, DocEvent from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName @@ -220,7 +219,7 @@ class IprEvent(models.Model): """Returns true if it's beyond the response_due date and no response has been received""" qs = IprEvent.objects.filter(disclosure=self.disclosure,in_reply_to=self.message) - if not qs and datetime.datetime.now().date() > self.response_due.date(): + if not qs and timezone.now().date() > self.response_due.date(): return True else: return False diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index 5b3896832..8fb11c39b 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -9,6 +9,7 @@ from pyquery import PyQuery from urllib.parse import quote, urlparse from django.urls import reverse as urlreverse +from django.utils import timezone import debug # pyflakes:ignore @@ -636,7 +637,7 @@ I would like to revoke this declaration. message_string.format( to=addrs.to, cc=addrs.cc, - date=datetime.datetime.now().ctime() + date=timezone.now().ctime() ) ) self.assertIsNone(result) @@ -646,7 +647,7 @@ I would like to revoke this declaration. From: joe@test.com Date: {} Subject: test -""".format(reply_to, datetime.datetime.now().ctime()) +""".format(reply_to, timezone.now().ctime()) result = process_response_email(message_string) self.assertIsInstance(result, Message) @@ -660,7 +661,7 @@ Subject: test From: joe@test.com Date: {} Subject: test -""".format(reply_to, datetime.datetime.now().ctime()) +""".format(reply_to, timezone.now().ctime()) message_bytes = message_string.encode('utf8') + b'\nInvalid stuff: \xfe\xff\n' result = process_response_email(message_bytes) self.assertIsInstance(result, Message) @@ -676,7 +677,7 @@ Subject: test message_bytes = message_string.format( to=addrs.to, cc=addrs.cc, - date=datetime.datetime.now().ctime(), + date=timezone.now().ctime(), ).encode('utf8') + b'\nInvalid stuff: \xfe\xff\n' result = process_response_email(message_bytes) self.assertIsNone(result) diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index e290bf14d..458186949 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -14,6 +14,7 @@ from django.http import HttpResponse, Http404, HttpResponseRedirect from django.shortcuts import render, get_object_or_404, redirect from django.template.loader import render_to_string from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.html import escape import debug # pyflakes:ignore @@ -587,7 +588,7 @@ def notify(request, id, type): type_id = form.cleaned_data['type'], by = request.user.person, disclosure = ipr, - response_due = datetime.datetime.now().date() + datetime.timedelta(days=30), + response_due = timezone.now().date() + datetime.timedelta(days=30), message = message, ) messages.success(request,'Notifications sent') diff --git a/ietf/liaisons/tests.py b/ietf/liaisons/tests.py index b08832ae5..0b3116fb4 100644 --- a/ietf/liaisons/tests.py +++ b/ietf/liaisons/tests.py @@ -14,6 +14,8 @@ from django.conf import settings from django.contrib.auth.models import User from django.urls import reverse as urlreverse from django.db.models import Q +from django.utils import timezone + from io import StringIO from pyquery import PyQuery @@ -50,7 +52,7 @@ def get_liaison_post_data(type='incoming'): to_contacts='to_contacts@example.com', purpose="info", title="title", - submitted_date=datetime.datetime.today().strftime("%Y-%m-%d"), + submitted_date=timezone.now().strftime("%Y-%m-%d"), body="body", send="1" ) @@ -385,7 +387,7 @@ class LiaisonManagementTests(TestCase): def test_edit_liaison(self): liaison = LiaisonStatementFactory(deadline=datetime.date.today()+datetime.timedelta(days=1)) - LiaisonStatementEventFactory(statement=liaison,type_id='submitted', time=datetime.datetime.now()-datetime.timedelta(days=1)) + LiaisonStatementEventFactory(statement=liaison,type_id='submitted', time=timezone.now()-datetime.timedelta(days=1)) LiaisonStatementEventFactory(statement=liaison,type_id='posted') from_group = liaison.from_groups.first() to_group = liaison.to_groups.first() diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 4fd4579c9..5f463b269 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -17,6 +17,7 @@ from django.contrib.auth.models import AnonymousUser from django.urls import reverse from django.shortcuts import get_object_or_404 from django.template.loader import render_to_string +from django.utils import timezone import debug # pyflakes:ignore @@ -42,7 +43,7 @@ def get_meeting(num=None,type_in=['ietf',],days=28): if type_in: meetings = meetings.filter(type__in=type_in) if num == None: - meetings = meetings.filter(date__gte=datetime.datetime.today()-datetime.timedelta(days=days)).order_by('date') + meetings = meetings.filter(date__gte=timezone.now()-datetime.timedelta(days=days)).order_by('date') else: meetings = meetings.filter(number=num) if meetings.exists(): @@ -51,7 +52,7 @@ def get_meeting(num=None,type_in=['ietf',],days=28): raise Http404("No such meeting found: %s" % num) def get_current_ietf_meeting(): - meetings = Meeting.objects.filter(type='ietf',date__gte=datetime.datetime.today()-datetime.timedelta(days=31)).order_by('date') + meetings = Meeting.objects.filter(type='ietf',date__gte=timezone.now()-datetime.timedelta(days=31)).order_by('date') return meetings.first() def get_current_ietf_meeting_num(): diff --git a/ietf/meeting/migrations/0056_use_timezone_now_for_meeting_models.py b/ietf/meeting/migrations/0056_use_timezone_now_for_meeting_models.py new file mode 100644 index 000000000..83d20fd57 --- /dev/null +++ b/ietf/meeting/migrations/0056_use_timezone_now_for_meeting_models.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0055_pytz_2022_2_1'), + ] + + operations = [ + migrations.AlterField( + model_name='schedulingevent', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='When the event happened'), + ), + ] diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 417a6ac9b..d7294f70a 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -24,6 +24,7 @@ from django.db.models import Max, Subquery, OuterRef, TextField, Value, Q from django.db.models.functions import Coalesce from django.conf import settings from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.text import slugify from django.utils.safestring import mark_safe @@ -176,7 +177,7 @@ class Meeting(models.Model): @classmethod def get_current_meeting(cls, type="ietf"): - return cls.objects.filter(type=type, date__gte=datetime.datetime.today()-datetime.timedelta(days=7) ).order_by('date').first() + return cls.objects.filter(type=type, date__gte=timezone.now()-datetime.timedelta(days=7) ).order_by('date').first() def get_first_cut_off(self): return self.get_00_cutoff() @@ -1280,7 +1281,7 @@ class Session(models.Model): class SchedulingEvent(models.Model): session = ForeignKey(Session) - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened") + time = models.DateTimeField(default=timezone.now, help_text="When the event happened") status = ForeignKey(SessionStatusName) by = ForeignKey(Person) diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py index 94e41f5ed..f62e41388 100644 --- a/ietf/meeting/tests_js.py +++ b/ietf/meeting/tests_js.py @@ -11,8 +11,8 @@ from unittest import skipIf import urllib.parse import django +from django.utils import timezone from django.utils.text import slugify -from django.utils.timezone import now from django.db.models import F import pytz @@ -307,7 +307,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase): room = RoomFactory(meeting=meeting) # get current time in meeting time zone - right_now = now().astimezone( + right_now = timezone.now().astimezone( pytz.timezone(meeting.time_zone) ) if not settings.USE_TZ: @@ -394,11 +394,11 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase): def test_past_swap_days_buttons(self): """Swap days buttons should be hidden for past items""" wait = WebDriverWait(self.driver, 2) - meeting = MeetingFactory(type_id='ietf', date=datetime.datetime.today() - datetime.timedelta(days=3), days=7) + meeting = MeetingFactory(type_id='ietf', date=timezone.now() - datetime.timedelta(days=3), days=7) room = RoomFactory(meeting=meeting) # get current time in meeting time zone - right_now = now().astimezone( + right_now = timezone.now().astimezone( pytz.timezone(meeting.time_zone) ) if not settings.USE_TZ: @@ -518,11 +518,11 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase): def test_past_swap_timeslot_col_buttons(self): """Swap timeslot column buttons should be hidden for past items""" wait = WebDriverWait(self.driver, 2) - meeting = MeetingFactory(type_id='ietf', date=datetime.datetime.today() - datetime.timedelta(days=3), days=7) + meeting = MeetingFactory(type_id='ietf', date=timezone.now() - datetime.timedelta(days=3), days=7) room = RoomFactory(meeting=meeting) # get current time in meeting time zone - right_now = now().astimezone( + right_now = timezone.now().astimezone( pytz.timezone(meeting.time_zone) ) if not settings.USE_TZ: @@ -2048,7 +2048,7 @@ class InterimTests(IetfSeleniumTestCase): Session.objects.filter( meeting__type_id='interim', timeslotassignments__schedule=F('meeting__schedule'), - timeslotassignments__timeslot__time__gte=datetime.datetime.today() + timeslotassignments__timeslot__time__gte=timezone.now() ) ).filter(current_status__in=('sched','canceled')) meetings = [] @@ -2061,7 +2061,7 @@ class InterimTests(IetfSeleniumTestCase): def all_ietf_meetings(self): meetings = Meeting.objects.filter( type_id='ietf', - date__gte=datetime.datetime.today()-datetime.timedelta(days=7) + date__gte=timezone.now()-datetime.timedelta(days=7) ) for m in meetings: m.calendar_label = 'IETF %s' % m.number @@ -2609,7 +2609,7 @@ class EditTimeslotsTests(IetfSeleniumTestCase): self.meeting: Meeting = MeetingFactory( type_id='ietf', number=120, - date=datetime.datetime.today() + datetime.timedelta(days=10), + date=timezone.now() + datetime.timedelta(days=10), populate_schedule=False, ) self.edit_timeslot_url = self.absreverse( diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index b5df0809b..2b6b20d1c 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -29,8 +29,8 @@ from django.test import Client, override_settings from django.db.models import F, Max from django.http import QueryDict, FileResponse from django.template import Context, Template +from django.utils import timezone from django.utils.text import slugify -from django.utils.timezone import now import debug # pyflakes:ignore @@ -604,7 +604,7 @@ class MeetingTests(BaseMeetingTestCase): def test_interim_materials(self): make_meeting_test_data() group = Group.objects.get(acronym='mars') - date = datetime.datetime.today() - datetime.timedelta(days=10) + date = timezone.now() - datetime.timedelta(days=10) meeting = make_interim_meeting(group=group, date=date, status='sched') session = meeting.session_set.first() @@ -1529,7 +1529,7 @@ class EditMeetingScheduleTests(TestCase): @staticmethod def _right_now_in(tzname): - right_now = now().astimezone(pytz.timezone(tzname)) + right_now = timezone.now().astimezone(pytz.timezone(tzname)) if not settings.USE_TZ: right_now = right_now.replace(tzinfo=None) return right_now @@ -1538,7 +1538,7 @@ class EditMeetingScheduleTests(TestCase): """Allow assignment to future timeslots only for official schedule""" meeting = MeetingFactory( type_id='ietf', - date=(datetime.datetime.today() - datetime.timedelta(days=1)).date(), + date=(timezone.now() - datetime.timedelta(days=1)).date(), days=3, ) right_now = self._right_now_in(meeting.time_zone) @@ -1598,7 +1598,7 @@ class EditMeetingScheduleTests(TestCase): """Do not allow assignment of past sessions for official schedule""" meeting = MeetingFactory( type_id='ietf', - date=(datetime.datetime.today() - datetime.timedelta(days=1)).date(), + date=(timezone.now() - datetime.timedelta(days=1)).date(), days=3, ) right_now = self._right_now_in(meeting.time_zone) @@ -1733,7 +1733,7 @@ class EditMeetingScheduleTests(TestCase): """Allow unassignment only of future timeslots for official schedule""" meeting = MeetingFactory( type_id='ietf', - date=(datetime.datetime.today() - datetime.timedelta(days=1)).date(), + date=(timezone.now() - datetime.timedelta(days=1)).date(), days=3, ) right_now = self._right_now_in(meeting.time_zone) @@ -1857,7 +1857,7 @@ class EditTimeslotsTests(TestCase): return MeetingFactory( type_id='ietf', number=number, - date=datetime.datetime.today() + datetime.timedelta(days=10), + date=timezone.now() + datetime.timedelta(days=10), populate_schedule=False, ) @@ -4680,7 +4680,7 @@ class InterimTests(TestCase): make_meeting_test_data() group = Group.objects.get(acronym='mars') date = datetime.date.today() + datetime.timedelta(days=30) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) dt = datetime.datetime.combine(date, time) duration = datetime.timedelta(hours=3) remote_instructions = 'Use webex' @@ -4751,7 +4751,7 @@ class InterimTests(TestCase): make_meeting_test_data() group = Group.objects.get(acronym='mars') date = datetime.date.today() + datetime.timedelta(days=30) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) dt = datetime.datetime.combine(date, time) duration = datetime.timedelta(hours=3) city = 'San Francisco' @@ -4799,7 +4799,7 @@ class InterimTests(TestCase): make_meeting_test_data() date = datetime.date.today() + datetime.timedelta(days=30) date2 = date + datetime.timedelta(days=1) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) dt = datetime.datetime.combine(date, time) dt2 = datetime.datetime.combine(date2, time) duration = datetime.timedelta(hours=3) @@ -4865,7 +4865,7 @@ class InterimTests(TestCase): make_meeting_test_data() date = datetime.date.today() + datetime.timedelta(days=30) date2 = date + datetime.timedelta(days=2) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) group = Group.objects.get(acronym='mars') city = 'San Francisco' country = 'US' @@ -4933,7 +4933,7 @@ class InterimTests(TestCase): if date.year != date2.year: date += datetime.timedelta(days=1) date2 += datetime.timedelta(days=1) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) dt = datetime.datetime.combine(date, time) dt2 = datetime.datetime.combine(date2, time) duration = datetime.timedelta(hours=3) @@ -5615,7 +5615,7 @@ class InterimTests(TestCase): def test_send_interim_minutes_reminder(self): make_meeting_test_data() group = Group.objects.get(acronym='mars') - date = datetime.datetime.today() - datetime.timedelta(days=10) + date = timezone.now() - datetime.timedelta(days=10) meeting = make_interim_meeting(group=group, date=date, status='sched') length_before = len(outbox) send_interim_minutes_reminder(meeting=meeting) @@ -6563,7 +6563,7 @@ class HasMeetingsTests(TestCase): q = PyQuery(r.content) self.assertTrue(q('#id_group option[value="%d"]'%group.pk)) date = datetime.date.today() + datetime.timedelta(days=30+meeting_count) - time = datetime.datetime.now().time().replace(microsecond=0,second=0) + time = timezone.now().time().replace(microsecond=0,second=0) remote_instructions = 'Use webex' agenda = 'Intro. Slides. Discuss.' agenda_note = 'On second level' @@ -6659,7 +6659,7 @@ class HasMeetingsTests(TestCase): session = SessionFactory( group__type_id = gf.type_id, meeting__type_id='interim', - meeting__date = datetime.datetime.today()+datetime.timedelta(days=30), + meeting__date = timezone.now()+datetime.timedelta(days=30), status_id='sched', ) sessions.append(session) @@ -6675,7 +6675,7 @@ class HasMeetingsTests(TestCase): sessions=[] for gf in GroupFeatures.objects.filter(has_meetings=True): group = GroupFactory(type_id=gf.type_id) - meeting_date = datetime.datetime.today() + datetime.timedelta(days=30) + meeting_date = timezone.now() + datetime.timedelta(days=30) session = SessionFactory( group=group, meeting__type_id='interim', @@ -6696,7 +6696,7 @@ class HasMeetingsTests(TestCase): sessions=[] for gf in GroupFeatures.objects.filter(has_meetings=True): group = GroupFactory(type_id=gf.type_id) - meeting_date = datetime.datetime.today() + datetime.timedelta(days=30) + meeting_date = timezone.now() + datetime.timedelta(days=30) session = SessionFactory( group=group, meeting__type_id='interim', diff --git a/ietf/meeting/utils.py b/ietf/meeting/utils.py index 0d1a56270..f6c1800f1 100644 --- a/ietf/meeting/utils.py +++ b/ietf/meeting/utils.py @@ -12,6 +12,7 @@ from urllib.error import HTTPError from django.conf import settings from django.contrib import messages from django.template.loader import render_to_string +from django.utils import timezone from django.utils.encoding import smart_text import debug # pyflakes:ignore @@ -511,7 +512,7 @@ def swap_meeting_schedule_timeslot_assignments(schedule, source_timeslots, targe if max_overlap > datetime.timedelta(minutes=5): for a in lts_assignments: a.timeslot = most_overlapping_rts - a.modified = datetime.datetime.now() + a.modified = timezone.now() a.save() swapped = True diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 0c054db97..e4fc9dc17 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -36,10 +36,10 @@ from django.db.models import F, Max, Q from django.forms.models import modelform_factory, inlineformset_factory from django.template import TemplateDoesNotExist from django.template.loader import render_to_string +from django.utils import timezone from django.utils.encoding import force_str from django.utils.functional import curry from django.utils.text import slugify -from django.utils.timezone import now from django.views.decorators.cache import cache_page from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt from django.views.generic import RedirectView @@ -128,7 +128,7 @@ def materials(request, num=None): cut_off_date = meeting.get_submission_cut_off_date() cor_cut_off_date = meeting.get_submission_correction_date() now = datetime.date.today() - old = datetime.datetime.now() - datetime.timedelta(days=1) + old = timezone.now() - datetime.timedelta(days=1) if settings.SERVER_MODE != 'production' and '_testoverride' in request.GET: pass elif now > cor_cut_off_date: @@ -442,7 +442,7 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None): lock_time = settings.MEETING_SESSION_LOCK_TIME def timeslot_locked(ts): - meeting_now = now().astimezone(pytz.timezone(meeting.time_zone)) + meeting_now = timezone.now().astimezone(pytz.timezone(meeting.time_zone)) if not settings.USE_TZ: meeting_now = meeting_now.replace(tzinfo=None) return schedule.is_official and (ts.time - meeting_now < lock_time) @@ -785,7 +785,7 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None): timeslot=old_timeslot, ) - existing_assignments.update(timeslot=timeslot, modified=datetime.datetime.now()) + existing_assignments.update(timeslot=timeslot, modified=timezone.now()) else: SchedTimeSessAssignment.objects.create( session=session, @@ -1560,7 +1560,7 @@ def agenda(request, num=None, name=None, base=None, ext=None, owner=None, utc="" "updated": updated, "filter_categories": filter_organizer.get_filter_categories(), "non_area_keywords": filter_organizer.get_non_area_keywords(), - "now": datetime.datetime.now().astimezone(pytz.UTC), + "now": timezone.now().astimezone(pytz.utc), "timezone": meeting.time_zone, "is_current_meeting": is_current_meeting, "use_codimd": True if meeting.date>=settings.MEETING_USES_CODIMD_DATE else False, @@ -2454,7 +2454,7 @@ def session_details(request, num, acronym): 'can_manage_materials' : can_manage, 'can_view_request': can_view_request, 'thisweek': datetime.date.today()-datetime.timedelta(days=7), - 'now': datetime.datetime.now(), + 'now': timezone.now(), 'use_codimd': True if meeting.date>=settings.MEETING_USES_CODIMD_DATE else False, }) @@ -3542,7 +3542,7 @@ def interim_request_edit(request, number): @cache_page(60*60) def past(request): '''List of past meetings''' - today = datetime.datetime.today() + today = timezone.now() meetings = data_for_meetings_overview(Meeting.objects.filter(date__lte=today).order_by('-date')) @@ -3615,7 +3615,7 @@ def upcoming(request): 'menu_actions': actions, 'menu_entries': menu_entries, 'selected_menu_entry': selected_menu_entry, - 'now': datetime.datetime.now(), + 'now': timezone.now(), 'use_codimd': True if datetime.date.today()>=settings.MEETING_USES_CODIMD_DATE else False, }) diff --git a/ietf/message/management/commands/show_messages.py b/ietf/message/management/commands/show_messages.py index b232da481..8741b2129 100644 --- a/ietf/message/management/commands/show_messages.py +++ b/ietf/message/management/commands/show_messages.py @@ -6,6 +6,7 @@ import email import datetime from django.core.management.base import BaseCommand +from django.utils import timezone import debug # pyflakes:ignore @@ -25,7 +26,7 @@ class Command(BaseCommand): """ def add_arguments(self, parser): - default_start = datetime.datetime.now() - datetime.timedelta(days=14) + default_start = timezone.now() - datetime.timedelta(days=14) parser.add_argument( '-t', '--start', '--from', type=str, default=default_start.strftime('%Y-%m-%d %H:%M'), help='Limit the list to messages saved after the given time (default %(default)s).', diff --git a/ietf/message/migrations/0012_use_timezone_now_for_message_models.py b/ietf/message/migrations/0012_use_timezone_now_for_message_models.py new file mode 100644 index 000000000..dbef893ea --- /dev/null +++ b/ietf/message/migrations/0012_use_timezone_now_for_message_models.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0011_auto_20201109_0439'), + ] + + operations = [ + migrations.AlterField( + model_name='message', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='sendqueue', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/ietf/message/models.py b/ietf/message/models.py index 01162a4b6..fe2c8d325 100644 --- a/ietf/message/models.py +++ b/ietf/message/models.py @@ -2,10 +2,10 @@ # -*- coding: utf-8 -*- -import datetime import email.utils from django.db import models +from django.utils import timezone import debug # pyflakes:ignore @@ -17,7 +17,7 @@ from ietf.utils.models import ForeignKey from ietf.utils.mail import get_email_addresses_from_text class Message(models.Model): - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) by = ForeignKey(Person) subject = models.CharField(max_length=255) @@ -62,7 +62,7 @@ class MessageAttachment(models.Model): class SendQueue(models.Model): - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) by = ForeignKey(Person) message = ForeignKey(Message) diff --git a/ietf/message/tests.py b/ietf/message/tests.py index 4ab790699..c1f22b3d0 100644 --- a/ietf/message/tests.py +++ b/ietf/message/tests.py @@ -5,6 +5,7 @@ import datetime from django.urls import reverse as urlreverse +from django.utils import timezone import debug # pyflakes:ignore @@ -87,7 +88,7 @@ class SendScheduledAnnouncementsTests(TestCase): q = SendQueue.objects.create( by=Person.objects.get(name="(System)"), message=msg, - send_at=datetime.datetime.now() + datetime.timedelta(hours=12) + send_at=timezone.now() + datetime.timedelta(hours=12) ) mailbox_before = len(outbox) @@ -113,7 +114,7 @@ class SendScheduledAnnouncementsTests(TestCase): q = SendQueue.objects.create( by=Person.objects.get(name="(System)"), message=msg, - send_at=datetime.datetime.now() + datetime.timedelta(hours=12) + send_at=timezone.now() + datetime.timedelta(hours=12) ) mailbox_before = len(outbox) diff --git a/ietf/message/utils.py b/ietf/message/utils.py index 65c018a39..2601eccab 100644 --- a/ietf/message/utils.py +++ b/ietf/message/utils.py @@ -2,8 +2,9 @@ # -*- coding: utf-8 -*- -import re, datetime, email +import re, email +from django.utils import timezone from django.utils.encoding import force_str from ietf.utils.mail import send_mail_text, send_mail_mime @@ -52,7 +53,7 @@ def send_scheduled_message_from_send_queue(queue_item): send_mail_mime(None, message.to, message.frm, message.subject, msg, cc=message.cc, bcc=message.bcc) - queue_item.sent_at = datetime.datetime.now() + queue_item.sent_at = timezone.now() queue_item.save() queue_item.message.sent = queue_item.sent_at diff --git a/ietf/nomcom/tests.py b/ietf/nomcom/tests.py index b8ffcf103..5c4e1ba2d 100644 --- a/ietf/nomcom/tests.py +++ b/ietf/nomcom/tests.py @@ -17,6 +17,7 @@ from django.conf import settings from django.core.files import File from django.contrib.auth.models import User from django.urls import reverse +from django.utils import timezone from django.utils.encoding import force_str import debug # pyflakes:ignore @@ -1389,7 +1390,7 @@ class FeedbackLastSeenTests(TestCase): f.nominees.add(self.nominee) f = FeedbackFactory.create(author=self.author,nomcom=self.nc,type_id='comment') f.topics.add(self.topic) - now = datetime.datetime.now() + now = timezone.now() self.hour_ago = now - datetime.timedelta(hours=1) self.half_hour_ago = now - datetime.timedelta(minutes=30) self.second_from_now = now + datetime.timedelta(seconds=1) diff --git a/ietf/person/management/commands/purge_old_personal_api_key_events.py b/ietf/person/management/commands/purge_old_personal_api_key_events.py index e60f784b5..47674e2d5 100644 --- a/ietf/person/management/commands/purge_old_personal_api_key_events.py +++ b/ietf/person/management/commands/purge_old_personal_api_key_events.py @@ -1,9 +1,10 @@ # Copyright The IETF Trust 2021, All Rights Reserved # -*- coding: utf-8 -*- -from datetime import datetime, timedelta +from datetime import timedelta from django.core.management.base import BaseCommand, CommandError from django.db.models import Max, Min +from django.utils import timezone from ietf.person.models import PersonApiKeyEvent @@ -33,7 +34,7 @@ class Command(BaseCommand): self.stdout.write('Finding events older than {}\n'.format(_format_count(keep_days))) self.stdout.flush() - now = datetime.now() + now = timezone.now() old_events = PersonApiKeyEvent.objects.filter( time__lt=now - timedelta(days=keep_days) ) diff --git a/ietf/person/management/commands/tests.py b/ietf/person/management/commands/tests.py index f30a80bf5..291a6ace5 100644 --- a/ietf/person/management/commands/tests.py +++ b/ietf/person/management/commands/tests.py @@ -5,6 +5,7 @@ import datetime from io import StringIO from django.core.management import call_command, CommandError +from django.utils import timezone from ietf.person.factories import PersonApiKeyEventFactory from ietf.person.models import PersonApiKeyEvent, PersonEvent @@ -51,7 +52,7 @@ class CommandTests(TestCase): # Remember how many PersonEvents were present so we can verify they're cleaned up properly. personevents_before = PersonEvent.objects.count() - now = datetime.datetime.now() + now = timezone.now() # The first of these events will be timestamped a fraction of a second more than keep_days # days ago by the time we call the management command, so will just barely chosen for purge. old_events = [ @@ -101,7 +102,7 @@ class CommandTests(TestCase): def test_purge_old_personal_api_key_events_rejects_invalid_arguments(self): """The purge_old_personal_api_key_events command should reject invalid arguments""" - event = PersonApiKeyEventFactory(time=datetime.datetime.now() - datetime.timedelta(days=30)) + event = PersonApiKeyEventFactory(time=timezone.now() - datetime.timedelta(days=30)) with self.assertRaises(CommandError): self._call_command('purge_old_personal_api_key_events') diff --git a/ietf/person/migrations/0025_use_timezone_now_for_person_models.py b/ietf/person/migrations/0025_use_timezone_now_for_person_models.py new file mode 100644 index 000000000..22dee042c --- /dev/null +++ b/ietf/person/migrations/0025_use_timezone_now_for_person_models.py @@ -0,0 +1,34 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('person', '0024_pronouns'), + ] + + operations = [ + migrations.AlterField( + model_name='historicalperson', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='person', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='personalapikey', + name='created', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='personevent', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='When the event happened'), + ), + ] diff --git a/ietf/person/models.py b/ietf/person/models.py index 143b8dd08..7fff66d9a 100644 --- a/ietf/person/models.py +++ b/ietf/person/models.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- -import datetime import email.utils import email.header import jsonfield @@ -18,6 +17,7 @@ from django.core.validators import validate_email from django.db import models from django.template.loader import render_to_string from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.encoding import smart_bytes from django.utils.text import slugify @@ -38,7 +38,7 @@ from ietf.utils.models import ForeignKey, OneToOneField class Person(models.Model): history = HistoricalRecords() user = OneToOneField(User, blank=True, null=True, on_delete=models.SET_NULL) - time = models.DateTimeField(default=datetime.datetime.now) # When this Person record entered the system + time = models.DateTimeField(default=timezone.now) # When this Person record entered the system # The normal unicode form of the name. This must be # set to the same value as the ascii-form if equal. name = models.CharField("Full Name (Unicode)", max_length=255, db_index=True, help_text="Preferred long form of name.") @@ -377,7 +377,7 @@ PERSON_API_KEY_ENDPOINTS = sorted(list(set([ (v, n) for (v, n, r) in PERSON_API_ class PersonalApiKey(models.Model): person = ForeignKey(Person, related_name='apikeys') endpoint = models.CharField(max_length=128, null=False, blank=False, choices=PERSON_API_KEY_ENDPOINTS) - created = models.DateTimeField(default=datetime.datetime.now, null=False) + created = models.DateTimeField(default=timezone.now, null=False) valid = models.BooleanField(default=True) salt = models.BinaryField(default=salt, max_length=12, null=False, blank=False) count = models.IntegerField(default=0, null=False, blank=False) @@ -427,7 +427,7 @@ PERSON_EVENT_CHOICES = [ class PersonEvent(models.Model): person = ForeignKey(Person) - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened") + time = models.DateTimeField(default=timezone.now, help_text="When the event happened") type = models.CharField(max_length=50, choices=PERSON_EVENT_CHOICES) desc = models.TextField() diff --git a/ietf/person/tests.py b/ietf/person/tests.py index 59228a795..16bcdf6da 100644 --- a/ietf/person/tests.py +++ b/ietf/person/tests.py @@ -13,6 +13,7 @@ from pyquery import PyQuery from django.http import HttpRequest from django.test import override_settings from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.encoding import iri_to_uri import debug # pyflakes:ignore @@ -211,7 +212,7 @@ class PersonUtilsTests(TestCase): self.assertEqual(results,(p1,p3)) # both have User - today = datetime.datetime.today() + today = timezone.now() p2.user.last_login = today p2.user.save() p4.user.last_login = today - datetime.timedelta(days=30) diff --git a/ietf/review/factories.py b/ietf/review/factories.py index cf66f1ed8..d6780fad8 100644 --- a/ietf/review/factories.py +++ b/ietf/review/factories.py @@ -2,6 +2,8 @@ import factory import datetime +from django.utils import timezone + from ietf.review.models import ReviewTeamSettings, ReviewRequest, ReviewAssignment, ReviewerSettings from ietf.name.models import ReviewTypeName, ReviewResultName @@ -39,7 +41,7 @@ class ReviewRequestFactory(factory.django.DjangoModelFactory): type_id = 'lc' doc = factory.SubFactory('ietf.doc.factories.DocumentFactory',type_id='draft') team = factory.SubFactory('ietf.group.factories.ReviewTeamFactory',type_id='review') - deadline = datetime.datetime.today()+datetime.timedelta(days=14) + deadline = timezone.now()+datetime.timedelta(days=14) requested_by = factory.SubFactory('ietf.person.factories.PersonFactory') class ReviewAssignmentFactory(factory.django.DjangoModelFactory): @@ -49,7 +51,7 @@ class ReviewAssignmentFactory(factory.django.DjangoModelFactory): review_request = factory.SubFactory('ietf.review.factories.ReviewRequestFactory') state_id = 'assigned' reviewer = factory.SubFactory('ietf.person.factories.EmailFactory') - assigned_on = datetime.datetime.now() + assigned_on = timezone.now() class ReviewerSettingsFactory(factory.django.DjangoModelFactory): class Meta: diff --git a/ietf/review/migrations/0029_use_timezone_now_for_review_models.py b/ietf/review/migrations/0029_use_timezone_now_for_review_models.py new file mode 100644 index 000000000..a8a0558d4 --- /dev/null +++ b/ietf/review/migrations/0029_use_timezone_now_for_review_models.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('review', '0028_auto_20220513_1456'), + ] + + operations = [ + migrations.AlterField( + model_name='historicalreviewrequest', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='reviewrequest', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='reviewwish', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/ietf/review/models.py b/ietf/review/models.py index 96355417d..0ec367819 100644 --- a/ietf/review/models.py +++ b/ietf/review/models.py @@ -7,6 +7,7 @@ import datetime from simple_history.models import HistoricalRecords from django.db import models +from django.utils import timezone import debug # pyflakes:ignore @@ -95,7 +96,7 @@ class UnavailablePeriod(models.Model): class ReviewWish(models.Model): """Reviewer wishes to review a document when it becomes available for review.""" - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None)) person = ForeignKey(Person) doc = ForeignKey(Document) @@ -125,7 +126,7 @@ class ReviewRequest(models.Model): # Fields filled in on the initial record creation - these # constitute the request part. - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) type = ForeignKey(ReviewTypeName) doc = ForeignKey(Document, related_name='reviewrequest_set') team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None)) diff --git a/ietf/review/utils.py b/ietf/review/utils.py index 3fec1b84f..f665ba06b 100644 --- a/ietf/review/utils.py +++ b/ietf/review/utils.py @@ -12,6 +12,8 @@ from django.template.defaultfilters import pluralize from django.template.loader import render_to_string from django.urls import reverse as urlreverse from django.contrib.sites.models import Site +from django.utils import timezone + from simple_history.utils import update_change_reason import debug # pyflakes:ignore @@ -119,7 +121,7 @@ def days_needed_to_fulfill_min_interval_for_reviewers(team): min_intervals = dict(ReviewerSettings.objects.filter(team=team).values_list("person_id", "min_interval")) - now = datetime.datetime.now() + now = timezone.now() res = {} for person_id, latest_assignment_time in latest_assignments.items(): @@ -495,7 +497,7 @@ def suggested_review_requests_for_team(team): requests = {} - now = datetime.datetime.now() + now = timezone.now() reviewable_docs_qs = Document.objects.filter(type="draft").exclude(stream="ise") diff --git a/ietf/secr/meetings/tests.py b/ietf/secr/meetings/tests.py index c6576a0cc..2e90a23dc 100644 --- a/ietf/secr/meetings/tests.py +++ b/ietf/secr/meetings/tests.py @@ -14,6 +14,7 @@ import debug # pyflakes:ignore from django.conf import settings from django.urls import reverse +from django.utils import timezone from ietf.group.models import Group, GroupEvent from ietf.meeting.factories import MeetingFactory @@ -212,8 +213,8 @@ class SecrMeetingTestCase(TestCase): self.assertEqual(q('#id_notification_list').html(),'ames, mars') # test that only changes since last notification show up - now = datetime.datetime.now() - then = datetime.datetime.now()+datetime.timedelta(hours=1) + now = timezone.now() + then = timezone.now()+datetime.timedelta(hours=1) person = Person.objects.get(name="(System)") GroupEvent.objects.create(group=mars_group,time=now,type='sent_notification', by=person,desc='sent scheduled notification for %s' % meeting) diff --git a/ietf/secr/meetings/views.py b/ietf/secr/meetings/views.py index 7d6a227dc..cf6252cc0 100644 --- a/ietf/secr/meetings/views.py +++ b/ietf/secr/meetings/views.py @@ -11,6 +11,7 @@ from django.db.models import IntegerField from django.db.models.functions import Cast from django.forms.models import inlineformset_factory from django.shortcuts import render, get_object_or_404, redirect +from django.utils import timezone from django.utils.text import slugify import debug # pyflakes:ignore @@ -121,7 +122,7 @@ def send_notifications(meeting, groups, person): Send session scheduled email notifications for each group in groups. Person is the user who initiated this action, request.uesr.get_profile(). ''' - now = datetime.datetime.now() + now = timezone.now() for group in groups: sessions = group.session_set.filter(meeting=meeting) addrs = gather_address_lists('session_scheduled',group=group,session=sessions[0]) diff --git a/ietf/secr/proceedings/reports.py b/ietf/secr/proceedings/reports.py index 115e4facd..49b632822 100644 --- a/ietf/secr/proceedings/reports.py +++ b/ietf/secr/proceedings/reports.py @@ -1,6 +1,7 @@ import datetime from django.template.loader import render_to_string +from django.utils import timezone from ietf.meeting.models import Meeting from ietf.doc.models import DocEvent, Document @@ -9,7 +10,7 @@ from ietf.secr.proceedings.proc_utils import get_progress_stats def report_id_activity(start,end): # get previous meeting - meeting = Meeting.objects.filter(date__lt=datetime.datetime.now(),type='ietf').order_by('-date')[0] + meeting = Meeting.objects.filter(date__lt=timezone.now(),type='ietf').order_by('-date')[0] syear,smonth,sday = start.split('-') eyear,emonth,eday = end.split('-') sdate = datetime.datetime(int(syear),int(smonth),int(sday)) diff --git a/ietf/secr/proceedings/tests_reports.py b/ietf/secr/proceedings/tests_reports.py index 6039cfced..034dbe5fa 100644 --- a/ietf/secr/proceedings/tests_reports.py +++ b/ietf/secr/proceedings/tests_reports.py @@ -1,6 +1,8 @@ import datetime import debug # pyflakes:ignore +from django.utils import timezone + from ietf.doc.factories import DocumentFactory,NewRevisionDocEventFactory from ietf.secr.proceedings.reports import report_id_activity, report_progress_report from ietf.utils.test_utils import TestCase @@ -10,7 +12,7 @@ class ReportsTestCase(TestCase): def test_report_id_activity(self): - today = datetime.datetime.today() + today = timezone.now() yesterday = today - datetime.timedelta(days=1) last_quarter = today - datetime.timedelta(days=3*30) next_week = today+datetime.timedelta(days=7) @@ -24,7 +26,7 @@ class ReportsTestCase(TestCase): self.assertTrue('IETF Activity since last IETF Meeting' in result) def test_report_progress_report(self): - today = datetime.datetime.today() + today = timezone.now() last_quarter = today - datetime.timedelta(days=3*30) next_week = today+datetime.timedelta(days=7) diff --git a/ietf/secr/telechat/tests.py b/ietf/secr/telechat/tests.py index f664745d7..7a65cb40d 100644 --- a/ietf/secr/telechat/tests.py +++ b/ietf/secr/telechat/tests.py @@ -8,6 +8,7 @@ from pyquery import PyQuery import debug # pyflakes:ignore from django.urls import reverse +from django.utils import timezone from ietf.doc.factories import (WgDraftFactory, IndividualRfcFactory, CharterFactory, IndividualDraftFactory, ConflictReviewFactory) @@ -22,7 +23,7 @@ from ietf.secr.telechat.views import get_next_telechat_date SECR_USER='secretary' def augment_data(): - TelechatDate.objects.create(date=datetime.datetime.today()) + TelechatDate.objects.create(date=timezone.now()) class SecrTelechatTestCase(TestCase): def test_main(self): @@ -138,7 +139,7 @@ class SecrTelechatTestCase(TestCase): self.assertEqual(q("#telechat-positions-table").find("th:contains('No Record')").length,1) def test_bash(self): - today = datetime.datetime.today() + today = timezone.now() TelechatDate.objects.create(date=today) url = reverse('ietf.secr.telechat.views.bash',kwargs={'date':today.strftime('%Y-%m-%d')}) self.client.login(username="secretary", password="secretary+password") diff --git a/ietf/stats/management/commands/fetch_meeting_attendance.py b/ietf/stats/management/commands/fetch_meeting_attendance.py index 5078c7cee..7f936531d 100644 --- a/ietf/stats/management/commands/fetch_meeting_attendance.py +++ b/ietf/stats/management/commands/fetch_meeting_attendance.py @@ -1,10 +1,10 @@ # Copyright The IETF Trust 2017-2019, All Rights Reserved # Copyright 2016 IETF Trust -import datetime import syslog from django.core.management.base import BaseCommand, CommandError +from django.utils import timezone import debug # pyflakes:ignore @@ -32,7 +32,7 @@ class Command(BaseCommand): elif options['all']: meetings = Meeting.objects.filter(type="ietf").order_by("date") elif options['latest']: - meetings = Meeting.objects.filter(type="ietf", date__lte=datetime.datetime.today()).order_by("-date")[:options['latest']] + meetings = Meeting.objects.filter(type="ietf", date__lte=timezone.now()).order_by("-date")[:options['latest']] else: raise CommandError("Please use one of --meeting, --all or --latest") diff --git a/ietf/stats/tests.py b/ietf/stats/tests.py index d34d7b11b..13b81d934 100644 --- a/ietf/stats/tests.py +++ b/ietf/stats/tests.py @@ -13,6 +13,7 @@ from requests import Response import debug # pyflakes:ignore from django.urls import reverse as urlreverse +from django.utils import timezone from ietf.utils.test_utils import login_testing_unauthorized, TestCase import ietf.stats.views @@ -63,7 +64,7 @@ class StatisticsTests(TestCase): Document.objects.filter(pk=draft.pk).update(words=4000) # move it back so it shows up in the yearly summaries NewRevisionDocEvent.objects.filter(doc=draft, rev=draft.rev).update( - time=datetime.datetime.now() - datetime.timedelta(days=500)) + time=timezone.now() - datetime.timedelta(days=500)) referencing_draft = Document.objects.create( name="draft-ietf-mars-referencing", @@ -88,7 +89,7 @@ class StatisticsTests(TestCase): doc=referencing_draft, desc="New revision available", rev=referencing_draft.rev, - time=datetime.datetime.now() - datetime.timedelta(days=1000) + time=timezone.now() - datetime.timedelta(days=1000) ) diff --git a/ietf/stats/views.py b/ietf/stats/views.py index 593fc1947..97cf1178a 100644 --- a/ietf/stats/views.py +++ b/ietf/stats/views.py @@ -18,6 +18,7 @@ from django.db.models import Count, Q from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.safestring import mark_safe from django.utils.text import slugify @@ -196,7 +197,7 @@ def document_stats(request, stats_type=None): if "y" in time_choice: try: y = int(time_choice.rstrip("y")) - from_time = datetime.datetime.today() - dateutil.relativedelta.relativedelta(years=y) + from_time = timezone.now() - dateutil.relativedelta.relativedelta(years=y) except ValueError: pass diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index 34f568d2e..857e6879c 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -21,6 +21,7 @@ from django import forms from django.conf import settings from django.utils.html import mark_safe, format_html # type:ignore from django.urls import reverse as urlreverse +from django.utils import timezone from django.utils.encoding import force_str import debug # pyflakes:ignore @@ -79,7 +80,7 @@ class SubmissionBaseUploadForm(forms.Form): self.base_formats = None # None will raise an exception in clean() if this isn't changed in a subclass def set_cutoff_warnings(self): - now = datetime.datetime.now(pytz.utc) + now = timezone.now().astimezone(pytz.utc) meeting = Meeting.get_current_meeting() if not meeting: return diff --git a/ietf/submit/migrations/0011_use_timezone_now_for_submit_models.py b/ietf/submit/migrations/0011_use_timezone_now_for_submit_models.py new file mode 100644 index 000000000..69d40bf8a --- /dev/null +++ b/ietf/submit/migrations/0011_use_timezone_now_for_submit_models.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.28 on 2022-07-12 11:24 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('submit', '0010_create_cancel_stale_submissions_task'), + ] + + operations = [ + migrations.AlterField( + model_name='preapproval', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='submissioncheck', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='submissionevent', + name='time', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/ietf/submit/models.py b/ietf/submit/models.py index 9f0e2fa33..629303296 100644 --- a/ietf/submit/models.py +++ b/ietf/submit/models.py @@ -7,6 +7,7 @@ import email import jsonfield from django.db import models +from django.utils import timezone import debug # pyflakes:ignore @@ -120,7 +121,7 @@ class Submission(models.Model): class SubmissionCheck(models.Model): - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) submission = ForeignKey(Submission, related_name='checks') checker = models.CharField(max_length=256, blank=True) passed = models.BooleanField(null=True, default=False) @@ -139,7 +140,7 @@ class SubmissionCheck(models.Model): class SubmissionEvent(models.Model): submission = ForeignKey(Submission) - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) by = ForeignKey(Person, null=True, blank=True) desc = models.TextField() @@ -157,7 +158,7 @@ class Preapproval(models.Model): """Pre-approved draft submission name.""" name = models.CharField(max_length=255, db_index=True) by = ForeignKey(Person) - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) def __str__(self): return self.name diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 70baff432..86815f59f 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -287,7 +287,7 @@ class SubmitTests(BaseSubmitTestCase): # prepare draft to suggest replace sug_replaced_draft = Document.objects.create( name="draft-ietf-ames-sug-replaced", - time=datetime.datetime.now(), + time=timezone.now(), type_id="draft", title="Draft to be suggested to be replaced", stream_id="ietf", @@ -298,7 +298,7 @@ class SubmitTests(BaseSubmitTestCase): words=100, intended_std_level_id="ps", ad=draft.ad, - expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + expires=timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), notify="aliens@example.mars", note="", ) @@ -357,7 +357,7 @@ class SubmitTests(BaseSubmitTestCase): self.assertTrue(os.path.exists(os.path.join(self.repository_dir, "%s-%s.txt" % (name, rev)))) self.assertEqual(draft.type_id, "draft") self.assertEqual(draft.stream_id, "ietf") - self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) + self.assertTrue(draft.expires >= timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) self.assertEqual(draft.get_state("draft-stream-%s" % draft.stream_id).slug, "wg-doc") authors = draft.documentauthor_set.all() self.assertEqual(len(authors), 1) @@ -2320,7 +2320,7 @@ Subject: test submission via email Please submit my draft at http://test.com/mydraft.txt Thank you -""".format(datetime.datetime.now().ctime()) +""".format(timezone.now().ctime()) message = email.message_from_string(force_str(message_string)) submission, submission_email_event = ( add_submission_email(request=None, @@ -2402,7 +2402,7 @@ Content-Disposition: attachment; filename="attach.txt" QW4gZXhhbXBsZSBhdHRhY2htZW50IHd0aG91dCB2ZXJ5IG11Y2ggaW4gaXQuCgpBIGNvdXBs ZSBvZiBsaW5lcyAtIGJ1dCBpdCBjb3VsZCBiZSBhIGRyYWZ0Cg== --------------090908050800030909090207-- -""".format(frm, datetime.datetime.now().ctime()) +""".format(frm, timezone.now().ctime()) message = email.message_from_string(force_str(message_string)) submission, submission_email_event = ( @@ -2458,7 +2458,7 @@ Content-Disposition: attachment; filename="attachment.txt" QW4gZXhhbXBsZSBhdHRhY2htZW50IHd0aG91dCB2ZXJ5IG11Y2ggaW4gaXQuCgpBIGNvdXBs ZSBvZiBsaW5lcyAtIGJ1dCBpdCBjb3VsZCBiZSBhIGRyYWZ0Cg== --------------090908050800030909090207-- -""".format(datetime.datetime.now().ctime()) +""".format(timezone.now().ctime()) # Back to secretariat self.client.login(username="secretary", password="secretary+password") @@ -2597,7 +2597,7 @@ Subject: Another message About my submission Thank you -""".format(datetime.datetime.now().ctime()) +""".format(timezone.now().ctime()) r = self.client.post(add_email_url, { "name": "{}-{}".format(submission.name, submission.rev), @@ -2664,7 +2664,7 @@ Thank you From: {} Date: {} Subject: test -""".format(reply_to, to, datetime.datetime.now().ctime()) +""".format(reply_to, to, timezone.now().ctime()) result = process_response_email(message_string) self.assertIsInstance(result, Message) diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index f0a78c5cf..ea51ab18f 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -22,6 +22,7 @@ from django.http import HttpRequest # pyflakes:ignore from django.utils.module_loading import import_string from django.template.loader import render_to_string from django.contrib.auth.models import AnonymousUser +from django.utils import timezone import debug # pyflakes:ignore @@ -338,7 +339,7 @@ def post_submission(request, submission, approved_doc_desc, approved_subm_desc): if stream_slug: draft.stream = StreamName.objects.get(slug=stream_slug) - draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) + draft.expires = timezone.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) log.log(f"{submission.name}: got draft details") events = [] @@ -616,7 +617,7 @@ def ensure_person_email_info_exists(name, email, docname): email.active = active email.person = person if email.time is None: - email.time = datetime.datetime.now() + email.time = timezone.now() email.origin = "author: %s" % docname email.save() diff --git a/ietf/sync/iana.py b/ietf/sync/iana.py index 9d0f66435..cf072d4c7 100644 --- a/ietf/sync/iana.py +++ b/ietf/sync/iana.py @@ -10,6 +10,7 @@ import re import requests from django.conf import settings +from django.utils import timezone from django.utils.encoding import smart_bytes, force_str from django.utils.http import urlquote @@ -241,7 +242,7 @@ def parse_review_email(text): doc_name = strip_version_extension(doc_name) # date - review_time = datetime.datetime.now() + review_time = timezone.now() if "Date" in msg: review_time = email_time_to_local_timezone(msg["Date"]) diff --git a/ietf/sync/rfceditor.py b/ietf/sync/rfceditor.py index c2264a0d3..6feb86308 100644 --- a/ietf/sync/rfceditor.py +++ b/ietf/sync/rfceditor.py @@ -11,6 +11,7 @@ from urllib.parse import urlencode from xml.dom import pulldom, Node from django.conf import settings +from django.utils import timezone from django.utils.encoding import smart_bytes, force_str, force_text import debug # pyflakes:ignore @@ -443,7 +444,7 @@ def update_docs_from_rfc_index(index_data, errata_data, skip_older_than_date=Non # at the moment because the data only has month/year, so # try to deduce it d = datetime.datetime.combine(rfc_published_date, datetime.time()) - synthesized = datetime.datetime.now() + synthesized = timezone.now() if abs(d - synthesized) > datetime.timedelta(days=60): synthesized = d else: diff --git a/ietf/sync/tests.py b/ietf/sync/tests.py index 61bab795c..6b8186d78 100644 --- a/ietf/sync/tests.py +++ b/ietf/sync/tests.py @@ -10,6 +10,7 @@ import quopri from django.conf import settings from django.urls import reverse as urlreverse +from django.utils import timezone import debug # pyflakes:ignore @@ -34,11 +35,11 @@ class IANASyncTests(TestCase): self.assertEqual(len(rfc_names), 1) self.assertEqual(rfc_names[0], "rfc1234") - iana.update_rfc_log_from_protocol_page(rfc_names, datetime.datetime.now() - datetime.timedelta(days=1)) + iana.update_rfc_log_from_protocol_page(rfc_names, timezone.now() - datetime.timedelta(days=1)) self.assertEqual(DocEvent.objects.filter(doc=draft, type="rfc_in_iana_registry").count(), 1) # make sure it doesn't create duplicates - iana.update_rfc_log_from_protocol_page(rfc_names, datetime.datetime.now() - datetime.timedelta(days=1)) + iana.update_rfc_log_from_protocol_page(rfc_names, timezone.now() - datetime.timedelta(days=1)) self.assertEqual(DocEvent.objects.filter(doc=draft, type="rfc_in_iana_registry").count(), 1) def test_changes_sync(self): diff --git a/ietf/sync/views.py b/ietf/sync/views.py index d6fc505c2..1d22c424c 100644 --- a/ietf/sync/views.py +++ b/ietf/sync/views.py @@ -12,6 +12,7 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.shortcuts import render +from django.utils import timezone from django.views.decorators.csrf import csrf_exempt from ietf.doc.models import DeletedEvent, StateDocEvent, DocEvent @@ -118,12 +119,12 @@ def rfceditor_undo(request): events = [] events.extend(StateDocEvent.objects.filter( state_type="draft-rfceditor", - time__gte=datetime.datetime.now() - datetime.timedelta(weeks=1) + time__gte=timezone.now() - datetime.timedelta(weeks=1) ).order_by("-time", "-id")) events.extend(DocEvent.objects.filter( type="sync_from_rfc_editor", - time__gte=datetime.datetime.now() - datetime.timedelta(weeks=1) + time__gte=timezone.now() - datetime.timedelta(weeks=1) ).order_by("-time", "-id")) events.sort(key=lambda e: (e.time, e.id), reverse=True) diff --git a/ietf/utils/decorators.py b/ietf/utils/decorators.py index 694e989f8..634724880 100644 --- a/ietf/utils/decorators.py +++ b/ietf/utils/decorators.py @@ -10,6 +10,7 @@ from django.conf import settings from django.contrib.auth import login from django.http import HttpResponse from django.shortcuts import render +from django.utils import timezone from django.utils.encoding import force_bytes import debug # pyflakes:ignore @@ -64,7 +65,7 @@ def require_api_key(f, request, *args, **kwargs): person = key.person last_login = person.user.last_login if not person.user.is_staff: - time_limit = (datetime.datetime.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS)) + time_limit = (timezone.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS)) if last_login == None or last_login < time_limit: return err(400, "Too long since last regular login") # Log in @@ -74,7 +75,7 @@ def require_api_key(f, request, *args, **kwargs): person.user.save() # Update stats key.count += 1 - key.latest = datetime.datetime.now() + key.latest = timezone.now() key.save() PersonApiKeyEvent.objects.create(person=person, type='apikey_login', key=key, desc="Logged in with key ID %s, endpoint %s" % (key.id, key.endpoint)) # Execute decorated function diff --git a/ietf/utils/mail.py b/ietf/utils/mail.py index 04c0ed916..3500d888e 100644 --- a/ietf/utils/mail.py +++ b/ietf/utils/mail.py @@ -3,7 +3,6 @@ import copy -import datetime #import logging import re import smtplib @@ -27,6 +26,7 @@ from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.validators import validate_email from django.template.loader import render_to_string from django.template import Context,RequestContext +from django.utils import timezone from django.utils.encoding import force_text, force_str, force_bytes import debug # pyflakes:ignore @@ -324,7 +324,7 @@ def show_that_mail_was_sent(request,leadline,msg,bcc): if request and request.user: from ietf.ietfauth.utils import has_role if has_role(request.user,['Area Director','Secretariat','IANA','RFC Editor','ISE','IAD','IRTF Chair','WG Chair','RG Chair','WG Secretary','RG Secretary']): - info = "%s at %s %s\n" % (leadline,datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE) + info = "%s at %s %s\n" % (leadline,timezone.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE) info += "Subject: %s\n" % force_text(msg.get('Subject','[no subject]')) info += "To: %s\n" % msg.get('To','[no to]') if msg.get('Cc'): @@ -378,7 +378,7 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=F try: send_smtp(msg, bcc) if save: - message.sent = datetime.datetime.now() + message.sent = timezone.now() message.save() if settings.SERVER_MODE != 'development': show_that_mail_was_sent(request,'Email was sent',msg,bcc) @@ -505,7 +505,7 @@ def send_mail_message(request, message, extra=None): # msg = send_mail_text(request, message.to, message.frm, message.subject, # message.body, cc=message.cc, bcc=message.bcc, extra=e, save=False) - message.sent = datetime.datetime.now() + message.sent = timezone.now() message.save() return msg diff --git a/ietf/utils/management/commands/check_draft_event_revision_integrity.py b/ietf/utils/management/commands/check_draft_event_revision_integrity.py index a4c38bd1c..c8d2cbd21 100644 --- a/ietf/utils/management/commands/check_draft_event_revision_integrity.py +++ b/ietf/utils/management/commands/check_draft_event_revision_integrity.py @@ -13,6 +13,7 @@ import django django.setup() from django.core.management.base import BaseCommand #, CommandError +from django.utils import timezone import debug # pyflakes:ignore @@ -29,7 +30,7 @@ class Command(BaseCommand): """ def add_arguments(self, parser): - default_start = datetime.datetime.now() - datetime.timedelta(days=60) + default_start = timezone.now() - datetime.timedelta(days=60) parser.add_argument( '-d', '--from', type=str, default=default_start.strftime('%Y-%m-%d'), help='Limit the list to messages saved after the given date (default %(default)s).', diff --git a/ietf/utils/management/commands/fix_ambiguous_timestamps.py b/ietf/utils/management/commands/fix_ambiguous_timestamps.py index fc872f458..84a82bb30 100644 --- a/ietf/utils/management/commands/fix_ambiguous_timestamps.py +++ b/ietf/utils/management/commands/fix_ambiguous_timestamps.py @@ -10,6 +10,7 @@ from django.apps import apps from django.conf import settings from django.core.management.base import BaseCommand from django.db import models +from django.utils import timezone import debug # pyflakes:ignore @@ -53,7 +54,7 @@ class Command(BaseCommand): def handle(self, *app_labels, **options): self.verbosity = options['verbosity'] self.quiet = self.verbosity < 1 - stop = datetime.datetime.now() + stop = timezone.now() start = stop - datetime.timedelta(days=14) for name, appconf in apps.app_configs.items(): diff --git a/ietf/utils/management/commands/send_gdpr_consent_request.py b/ietf/utils/management/commands/send_gdpr_consent_request.py index 2bb08eed1..152fc83fe 100644 --- a/ietf/utils/management/commands/send_gdpr_consent_request.py +++ b/ietf/utils/management/commands/send_gdpr_consent_request.py @@ -7,6 +7,7 @@ import time from django.conf import settings from django.core.management.base import BaseCommand, CommandError +from django.utils import timezone import debug # pyflakes:ignore @@ -65,7 +66,7 @@ class Command(BaseCommand): delay = 1.0/options['rate'] # --minimum_interval minimum_interval = options['minimum_interval'] - latest_previous = datetime.datetime.now() - datetime.timedelta(days=minimum_interval) + latest_previous = timezone.now() - datetime.timedelta(days=minimum_interval) # user self.stdout.write('Querying the database for matching person records ...') if 'user' in options and options['user']: diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 7a7a77af4..cd5a06e83 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -6,6 +6,7 @@ import datetime from django.conf import settings from django.contrib.auth.models import User +from django.utils import timezone from django.utils.encoding import smart_text import debug # pyflakes:ignore @@ -271,14 +272,14 @@ def make_test_data(): # old draft old_draft = Document.objects.create( name="draft-foo-mars-test", - time=datetime.datetime.now() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + time=timezone.now() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), type_id="draft", title="Optimizing Martian Network Topologies", stream_id="ietf", abstract="Techniques for achieving near-optimal Martian networks.", rev="00", pages=2, - expires=datetime.datetime.now(), + expires=timezone.now(), ) old_draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) old_alias = DocAlias.objects.create(name=old_draft.name) @@ -287,7 +288,7 @@ def make_test_data(): # draft draft = Document.objects.create( name="draft-ietf-mars-test", - time=datetime.datetime.now(), + time=timezone.now(), type_id="draft", title="Optimizing Martian Network Topologies", stream_id="ietf", @@ -298,7 +299,7 @@ def make_test_data(): intended_std_level_id="ps", shepherd=email, ad=ad, - expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + expires=timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), notify="aliens@example.mars", note="", ) @@ -458,7 +459,7 @@ def make_review_data(doc): doc=doc, team=team1, type_id="early", - deadline=datetime.datetime.now() + datetime.timedelta(days=20), + deadline=timezone.now() + datetime.timedelta(days=20), state_id="accepted", requested_by=reviewer, reviewer=email, diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index 129b2e842..ae6db8bd6 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -43,7 +43,6 @@ import json import pytz import importlib import socket -import datetime import gzip import unittest import pathlib @@ -76,6 +75,7 @@ from django.core.management import call_command from django.urls import URLResolver # type: ignore from django.template.backends.django import DjangoTemplates from django.template.backends.django import Template # type: ignore[attr-defined] +from django.utils import timezone # from django.utils.safestring import mark_safe import debug # pyflakes:ignore @@ -570,7 +570,7 @@ class CoverageTest(unittest.TestCase): checker.stop() # Save to the .coverage file checker.save() - # Apply the configured and requested omit and include data + # Apply the configured and requested omit and include data checker.config.from_args(ignore_errors=None, omit=settings.TEST_CODE_COVERAGE_EXCLUDE_FILES, include=include, file=None) for pattern in settings.TEST_CODE_COVERAGE_EXCLUDE_LINES: @@ -739,7 +739,7 @@ class IetfTestRunner(DiscoverRunner): print(" Datatracker %s test suite, %s:" % (ietf.__version__, time.strftime("%d %B %Y %H:%M:%S %Z"))) print(" Python %s." % sys.version.replace('\n', ' ')) print(" Django %s, settings '%s'" % (django.get_version(), settings.SETTINGS_MODULE)) - + settings.TEMPLATES[0]['BACKEND'] = 'ietf.utils.test_runner.ValidatingTemplates' if self.check_coverage: if self.coverage_file.endswith('.gz'): @@ -749,19 +749,19 @@ class IetfTestRunner(DiscoverRunner): with io.open(self.coverage_file, encoding='utf-8') as file: self.coverage_master = json.load(file) self.coverage_data = { - "time": datetime.datetime.now(pytz.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "time": timezone.now().astimezone(pytz.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), "template": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 1, # default format, coverage data in 'covered' are just fractions }, "url": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 4, }, "code": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 1, }, @@ -808,8 +808,8 @@ class IetfTestRunner(DiscoverRunner): for offset in range(10): try: # remember the value so ietf.utils.mail.send_smtp() will use the same - ietf.utils.mail.SMTP_ADDR['port'] = base + offset - self.smtpd_driver = SMTPTestServerDriver((ietf.utils.mail.SMTP_ADDR['ip4'],ietf.utils.mail.SMTP_ADDR['port']),None) + ietf.utils.mail.SMTP_ADDR['port'] = base + offset + self.smtpd_driver = SMTPTestServerDriver((ietf.utils.mail.SMTP_ADDR['ip4'],ietf.utils.mail.SMTP_ADDR['port']),None) self.smtpd_driver.start() print((" Running an SMTP test server on %(ip4)s:%(port)s to catch outgoing email." % ietf.utils.mail.SMTP_ADDR)) break diff --git a/ietf/utils/tests_meetecho.py b/ietf/utils/tests_meetecho.py index d40e013f8..db3d36f40 100644 --- a/ietf/utils/tests_meetecho.py +++ b/ietf/utils/tests_meetecho.py @@ -1,15 +1,16 @@ # Copyright The IETF Trust 2021, All Rights Reserved # -*- coding: utf-8 -*- import datetime +import pytz import requests import requests_mock -from pytz import timezone, utc from unittest.mock import patch from urllib.parse import urljoin from django.conf import settings from django.test import override_settings +from django.utils import timezone from ietf.utils.tests import TestCase from .meetecho import Conference, ConferenceManager, MeetechoAPI, MeetechoAPIError @@ -92,7 +93,7 @@ class APITests(TestCase): api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) api_response = api.schedule_meeting( wg_token='my-token', - start_time=utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), + start_time=pytz.utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), duration=datetime.timedelta(minutes=130), description='interim-2021-wgname-01', extrainfo='message for staff', @@ -120,11 +121,11 @@ class APITests(TestCase): ) # same time in different time zones for start_time in [ - utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), - timezone('america/halifax').localize(datetime.datetime(2021, 9, 14, 7, 0, 0)), - timezone('europe/kiev').localize(datetime.datetime(2021, 9, 14, 13, 0, 0)), - timezone('pacific/easter').localize(datetime.datetime(2021, 9, 14, 5, 0, 0)), - timezone('africa/porto-novo').localize(datetime.datetime(2021, 9, 14, 11, 0, 0)), + pytz.utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), + pytz.timezone('america/halifax').localize(datetime.datetime(2021, 9, 14, 7, 0, 0)), + pytz.timezone('europe/kiev').localize(datetime.datetime(2021, 9, 14, 13, 0, 0)), + pytz.timezone('pacific/easter').localize(datetime.datetime(2021, 9, 14, 5, 0, 0)), + pytz.timezone('africa/porto-novo').localize(datetime.datetime(2021, 9, 14, 11, 0, 0)), ]: self.assertEqual( api_response, @@ -191,7 +192,7 @@ class APITests(TestCase): '3d55bce0-535e-4ba8-bb8e-734911cf3c32': { 'room': { 'id': 18, - 'start_time': utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), + 'start_time': pytz.utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), 'duration': datetime.timedelta(minutes=130), 'description': 'interim-2021-wgname-01', }, @@ -201,7 +202,7 @@ class APITests(TestCase): 'e68e96d4-d38f-475b-9073-ecab46ca96a5': { 'room': { 'id': 23, - 'start_time': utc.localize(datetime.datetime(2021, 9, 15, 14, 30, 0)), + 'start_time': pytz.utc.localize(datetime.datetime(2021, 9, 15, 14, 30, 0)), 'duration': datetime.timedelta(minutes=30), 'description': 'interim-2021-wgname-02', }, @@ -249,7 +250,7 @@ class APITests(TestCase): def test_time_serialization(self): """Time de/serialization should be consistent""" - time = datetime.datetime.now(utc).replace(microsecond=0) # cut off to 0 microseconds + time = timezone.now().astimezone(pytz.utc).replace(microsecond=0) # cut off to 0 microseconds api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) self.assertEqual(api._deserialize_time(api._serialize_time(time)), time) @@ -263,7 +264,7 @@ class ConferenceManagerTests(TestCase): 'session-1-uuid': { 'room': { 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'start_time': pytz.utc.localize(datetime.datetime(2022,2,4,1,2,3)), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -273,7 +274,7 @@ class ConferenceManagerTests(TestCase): 'session-2-uuid': { 'room': { 'id': 2, - 'start_time': utc.localize(datetime.datetime(2022,2,5,4,5,6)), + 'start_time': pytz.utc.localize(datetime.datetime(2022,2,5,4,5,6)), 'duration': datetime.timedelta(minutes=90), 'description': 'another-description', }, @@ -290,7 +291,7 @@ class ConferenceManagerTests(TestCase): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022, 2, 4, 1, 2, 3)), + start_time=pytz.utc.localize(datetime.datetime(2022, 2, 4, 1, 2, 3)), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me', @@ -300,7 +301,7 @@ class ConferenceManagerTests(TestCase): id=2, public_id='session-2-uuid', description='another-description', - start_time=utc.localize(datetime.datetime(2022, 2, 5, 4, 5, 6)), + start_time=pytz.utc.localize(datetime.datetime(2022, 2, 5, 4, 5, 6)), duration=datetime.timedelta(minutes=90), url='https://example.com/another/url', deletion_token='delete-me-too', @@ -316,7 +317,7 @@ class ConferenceManagerTests(TestCase): 'session-1-uuid': { 'room': { 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'start_time': pytz.utc.localize(datetime.datetime(2022,2,4,1,2,3)), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -335,7 +336,7 @@ class ConferenceManagerTests(TestCase): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022,2,4,1,2,3)), + start_time=pytz.utc.localize(datetime.datetime(2022,2,4,1,2,3)), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me', @@ -351,7 +352,7 @@ class ConferenceManagerTests(TestCase): 'session-1-uuid': { 'room': { 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'start_time': pytz.utc.localize(datetime.datetime(2022,2,4,1,2,3)), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -369,7 +370,7 @@ class ConferenceManagerTests(TestCase): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022,2,4,1,2,3)), + start_time=pytz.utc.localize(datetime.datetime(2022,2,4,1,2,3)), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me',