------
Responses are returned as JSON. Blank fields are returned as ``null``, rather
-than being omitted. Timestamps use the ISO 8601 format::
+than being omitted. Timestamps use the ISO 8601 format, times are by default
+in UTC::
YYYY-MM-DDTHH:MM:SSZ
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.8 on 2018-02-22 23:11
+from __future__ import unicode_literals
+
+import datetime
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('patchwork', '0022_add_subject_match_to_project'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='check',
+ name='date',
+ field=models.DateTimeField(default=datetime.datetime.utcnow),
+ ),
+ migrations.AlterField(
+ model_name='comment',
+ name='date',
+ field=models.DateTimeField(default=datetime.datetime.utcnow),
+ ),
+ migrations.AlterField(
+ model_name='emailconfirmation',
+ name='date',
+ field=models.DateTimeField(default=datetime.datetime.utcnow),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='date',
+ field=models.DateTimeField(default=datetime.datetime.utcnow, help_text=b'The time this event was created.'),
+ ),
+ migrations.AlterField(
+ model_name='patchchangenotification',
+ name='last_modified',
+ field=models.DateTimeField(default=datetime.datetime.utcnow),
+ ),
+ migrations.AlterField(
+ model_name='submission',
+ name='date',
+ field=models.DateTimeField(default=datetime.datetime.utcnow),
+ ),
+ ]
# email metadata
msgid = models.CharField(max_length=255)
- date = models.DateTimeField(default=datetime.datetime.now)
+ date = models.DateTimeField(default=datetime.datetime.utcnow)
headers = models.TextField(blank=True)
# content
patch = models.ForeignKey(Patch, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
- date = models.DateTimeField(default=datetime.datetime.now)
+ date = models.DateTimeField(default=datetime.datetime.utcnow)
state = models.SmallIntegerField(
choices=STATE_CHOICES, default=STATE_PENDING,
db_index=True,
help_text='The category of the event.')
date = models.DateTimeField(
- default=datetime.datetime.now,
+ default=datetime.datetime.utcnow,
help_text='The time this event was created.')
# event object
email = models.CharField(max_length=200)
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
key = HashField()
- date = models.DateTimeField(default=datetime.datetime.now)
+ date = models.DateTimeField(default=datetime.datetime.utcnow)
active = models.BooleanField(default=True)
def deactivate(self):
self.save()
def is_valid(self):
- return self.date + self.validity > datetime.datetime.now()
+ return self.date + self.validity > datetime.datetime.utcnow()
def save(self, *args, **kwargs):
limit = 1 << 32
class PatchChangeNotification(models.Model):
patch = models.OneToOneField(Patch, primary_key=True,
on_delete=models.CASCADE)
- last_modified = models.DateTimeField(default=datetime.datetime.now)
+ last_modified = models.DateTimeField(default=datetime.datetime.utcnow)
orig_state = models.ForeignKey(State, on_delete=models.CASCADE)
def send_notifications():
- date_limit = datetime.datetime.now() - datetime.timedelta(
+ date_limit = datetime.datetime.utcnow() - datetime.timedelta(
minutes=settings.NOTIFICATION_DELAY_MINUTES)
# We delay sending notifications to a user if they have other
Users whose registration confirmation has expired are removed.
"""
# expire any invalid confirmations
- q = (Q(date__lt=datetime.datetime.now() - EmailConfirmation.validity) |
+ q = (Q(date__lt=datetime.datetime.utcnow() - EmailConfirmation.validity) |
Q(active=False))
EmailConfirmation.objects.filter(q).delete()
notification.delete()
return
- notification.last_modified = dt.now()
+ notification.last_modified = dt.utcnow()
notification.save()
<div class="comment">
<div class="meta">
<span>{{ submission.submitter|personify:project }}</span>
- <span class="pull-right">{{ submission.date }}</span>
+ <span class="pull-right">{{ submission.date }} UTC</span>
</div>
<pre class="content">
{{ submission|commentsyntax }}
<div class="comment">
<div class="meta">
<span>{{ item.submitter|personify:project }}</span>
- <span class="pull-right">{{ item.date }} | <a href="{% url 'comment-redirect' comment_id=item.id %}"
+ <span class="pull-right">{{ item.date }} UTC | <a href="{% url 'comment-redirect' comment_id=item.id %}"
>#{{ forloop.counter }}</a></span>
</div>
<pre class="content">
self.assertChecksEqual(self.patch, [check_a, check_b])
def test_checks__duplicate_checks(self):
- self._create_check(date=(dt.now() - timedelta(days=1)))
+ self._create_check(date=(dt.utcnow() - timedelta(days=1)))
check = self._create_check()
# this isn't a realistic scenario (dates shouldn't be set by user so
# they will always increment), but it's useful to verify the removal
# of older duplicates by the function
- self._create_check(date=(dt.now() - timedelta(days=2)))
+ self._create_check(date=(dt.utcnow() - timedelta(days=2)))
self.assertChecksEqual(self.patch, [check])
def test_checks__nultiple_users(self):
self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})
def test_check_count__multiple_checks(self):
- self._create_check(date=(dt.now() - timedelta(days=1)))
+ self._create_check(date=(dt.utcnow() - timedelta(days=1)))
self._create_check(context='new/test1')
self.assertCheckCountEqual(self.patch, 2, {Check.STATE_SUCCESS: 2})
self.assertCheckCountEqual(self.patch, 2, {Check.STATE_SUCCESS: 2})
def test_check_count__duplicate_check_same_state(self):
- self._create_check(date=(dt.now() - timedelta(days=1)))
+ self._create_check(date=(dt.utcnow() - timedelta(days=1)))
self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})
self._create_check()
self.assertCheckCountEqual(self.patch, 2, {Check.STATE_SUCCESS: 1})
def test_check_count__duplicate_check_new_state(self):
- self._create_check(date=(dt.now() - timedelta(days=1)))
+ self._create_check(date=(dt.utcnow() - timedelta(days=1)))
self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})
self._create_check(state=Check.STATE_FAIL)
return (user, conf)
def test_old_registration_expiry(self):
- date = ((datetime.datetime.now() - EmailConfirmation.validity) -
+ date = ((datetime.datetime.utcnow() - EmailConfirmation.validity) -
datetime.timedelta(hours=1))
user, conf = self.register(date)
EmailConfirmation.objects.filter(pk=conf.pk).exists())
def test_recent_registration_expiry(self):
- date = ((datetime.datetime.now() - EmailConfirmation.validity) +
+ date = ((datetime.datetime.utcnow() - EmailConfirmation.validity) +
datetime.timedelta(hours=1))
user, conf = self.register(date)
EmailConfirmation.objects.filter(pk=conf.pk).exists())
def test_inactive_registration_expiry(self):
- user, conf = self.register(datetime.datetime.now())
+ user, conf = self.register(datetime.datetime.utcnow())
# confirm registration
conf.user.is_active = True
submitter = patch.submitter
# ... then starts registration...
- date = ((datetime.datetime.now() - EmailConfirmation.validity) -
+ date = ((datetime.datetime.utcnow() - EmailConfirmation.validity) -
datetime.timedelta(hours=1))
user = create_user(link_person=False, email=submitter.email)
user.is_active = False
self.project = create_project(send_notifications=True)
def _expire_notifications(self, **kwargs):
- timestamp = datetime.datetime.now() - \
+ timestamp = datetime.datetime.utcnow() - \
datetime.timedelta(minutes=settings.NOTIFICATION_DELAY_MINUTES + 1)
qs = PatchChangeNotification.objects.all()
values = {
'patch': create_patch() if 'patch' not in kwargs else None,
'user': create_user() if 'user' not in kwargs else None,
- 'date': dt.now(),
+ 'date': dt.utcnow(),
'state': Check.STATE_SUCCESS,
'target_url': 'http://example.com/',
'description': '',
"""Create 'Series' object."""
values = {
'project': create_project() if 'project' not in kwargs else None,
- 'date': dt.now(),
+ 'date': dt.utcnow(),
'submitter': create_person() if 'submitter' not in kwargs else None,
'total': 1,
}
'submitter': create_person() if 'submitter' not in kwargs else None,
}
values.update(kwargs)
- date = dt.now()
+ date = dt.utcnow()
objects = []
for i in range(0, count):
--- /dev/null
+---
+other:
+ - |
+ Unify timezones used -- use UTC for both email submissions and internal
+ events. Please note that this change doesn't modify already existing data
+ so in case the instance's timezone is UTC+XX, events will appear out of
+ order (as if they happened earlier) for XX hours in the events API feed.