Skip to content

Commit 3d6b370

Browse files
committed
Upgraded custom TimedeltaFields to use the builtin DurationField from Django 1.8, and adjusted forms and initialization values accordingly.
- Legacy-Id: 12597
1 parent d401e6b commit 3d6b370

10 files changed

Lines changed: 179 additions & 32 deletions

ietf/meeting/factories.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Meta:
2020
idsubmit_cutoff_day_offset_00 = 13
2121
idsubmit_cutoff_day_offset_01 = 13
2222
idsubmit_cutoff_time_utc = datetime.timedelta(0, 86399)
23-
idsubmit_cutoff_warning_days = 21
23+
idsubmit_cutoff_warning_days = datetime.timedelta(days=21)
2424
venue_name = factory.Faker('sentence')
2525
venue_addr = factory.Faker('address')
2626
break_area = factory.Faker('sentence')
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
import datetime
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('meeting', '0042_auto_20161207_1137'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='meeting',
17+
name='xidsubmit_cutoff_time_utc',
18+
field=models.DurationField(default=datetime.timedelta(0, 86399), help_text=b'The time of day (UTC) after which submission will be closed. Use for example 23 hours, 59 minutes, 59 seconds.', blank=True),
19+
),
20+
migrations.AddField(
21+
model_name='meeting',
22+
name='xidsubmit_cutoff_warning_days',
23+
field=models.DurationField(default=datetime.timedelta(21), help_text=b'How long before the 00 cutoff to start showing cutoff warnings. Use for example 21 days or 3 weeks.', blank=True),
24+
),
25+
migrations.AddField(
26+
model_name='session',
27+
name='xrequested_duration',
28+
field=models.DurationField(default=datetime.timedelta(0)),
29+
),
30+
migrations.AddField(
31+
model_name='timeslot',
32+
name='xduration',
33+
field=models.DurationField(default=datetime.timedelta(0)),
34+
),
35+
]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations
5+
6+
def forward(apps, schema_editor):
7+
Meeting = apps.get_model('meeting', 'Meeting')
8+
TimeSlot = apps.get_model('meeting', 'TimeSlot')
9+
Session = apps.get_model('meeting', 'Session')
10+
import sys
11+
sys.stderr.write("\n")
12+
sys.stderr.write("Setting duration fields in Meeting objects...\n")
13+
for m in Meeting.objects.all():
14+
if m.xidsubmit_cutoff_time_utc != m.idsubmit_cutoff_time_utc:
15+
m.xidsubmit_cutoff_time_utc = m.idsubmit_cutoff_time_utc
16+
m.xidsubmit_cutoff_warning_days = m.idsubmit_cutoff_warning_days
17+
m.save()
18+
sys.stderr.write("Setting duration fields in TimeSlot objects...\n")
19+
for t in TimeSlot.objects.all():
20+
if t.xduration != t.duration:
21+
t.xduration = t.duration
22+
t.save()
23+
sys.stderr.write("Setting duration fields in Session objects...\n")
24+
for s in Session.objects.all():
25+
if s.xrequested_duration != s.requested_duration:
26+
s.xrequested_duration = s.requested_duration
27+
s.save()
28+
29+
def backward(apps, schema_editor):
30+
Meeting = apps.get_model('meeting', 'Meeting')
31+
TimeSlot = apps.get_model('meeting', 'TimeSlot')
32+
Session = apps.get_model('meeting', 'Session')
33+
import sys
34+
sys.stderr.write("\n")
35+
sys.stderr.write("Setting timedelta fields in Meeting objects...\n")
36+
for m in Meeting.objects.all():
37+
if m.idsubmit_cutoff_time_utc != m.xidsubmit_cutoff_time_utc:
38+
m.idsubmit_cutoff_time_utc = m.xidsubmit_cutoff_time_utc
39+
m.idsubmit_cutoff_warning_days = m.xidsubmit_cutoff_warning_days
40+
m.save()
41+
sys.stderr.write("Setting timedelta fields in TimeSlot objects...\n")
42+
for t in TimeSlot.objects.all():
43+
if t.duration != t.xduration:
44+
t.duration = t.xduration
45+
t.save()
46+
sys.stderr.write("Setting timedelta fields in Session objects...\n")
47+
for s in Session.objects.all():
48+
if s.requested_duration != s.xrequested_duration:
49+
s.requested_duration = s.xrequested_duration
50+
s.save()
51+
52+
class Migration(migrations.Migration):
53+
54+
dependencies = [
55+
('meeting', '0043_auto_20161219_1345'),
56+
]
57+
58+
operations = [
59+
migrations.RunPython(forward, backward)
60+
]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('meeting', '0044_convert_timedelta_data_to_duration'),
11+
]
12+
13+
operations = [
14+
migrations.RemoveField(
15+
model_name='meeting',
16+
name='idsubmit_cutoff_time_utc',
17+
),
18+
migrations.RenameField(
19+
model_name='meeting',
20+
old_name='xidsubmit_cutoff_time_utc',
21+
new_name='idsubmit_cutoff_time_utc',
22+
),
23+
#
24+
migrations.RemoveField(
25+
model_name='meeting',
26+
name='idsubmit_cutoff_warning_days',
27+
),
28+
migrations.RenameField(
29+
model_name='meeting',
30+
old_name='xidsubmit_cutoff_warning_days',
31+
new_name='idsubmit_cutoff_warning_days',
32+
),
33+
#
34+
migrations.RemoveField(
35+
model_name='timeslot',
36+
name='duration',
37+
),
38+
migrations.RenameField(
39+
model_name='timeslot',
40+
old_name='xduration',
41+
new_name='duration',
42+
),
43+
#
44+
migrations.RemoveField(
45+
model_name='session',
46+
name='requested_duration',
47+
),
48+
migrations.RenameField(
49+
model_name='session',
50+
old_name='xrequested_duration',
51+
new_name='requested_duration',
52+
),
53+
]

ietf/meeting/models.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import sys
99
import re
1010
import string
11-
import timedelta
12-
from timedeltafield import TimedeltaField
1311

1412
import debug # pyflakes:ignore
1513

@@ -68,10 +66,10 @@ class Meeting(models.Model):
6866
idsubmit_cutoff_day_offset_01 = models.IntegerField(blank=True,
6967
default=settings.IDSUBMIT_DEFAULT_CUTOFF_DAY_OFFSET_01,
7068
help_text = "The number of days before the meeting start date when the submission of -01 drafts etc. will be closed.")
71-
idsubmit_cutoff_time_utc = timedelta.fields.TimedeltaField(blank=True,
69+
idsubmit_cutoff_time_utc = models.DurationField(blank=True,
7270
default=settings.IDSUBMIT_DEFAULT_CUTOFF_TIME_UTC,
7371
help_text = "The time of day (UTC) after which submission will be closed. Use for example 23 hours, 59 minutes, 59 seconds.")
74-
idsubmit_cutoff_warning_days = timedelta.fields.TimedeltaField(blank=True,
72+
idsubmit_cutoff_warning_days = models.DurationField(blank=True,
7573
default=settings.IDSUBMIT_DEFAULT_CUTOFF_WARNING_DAYS,
7674
help_text = "How long before the 00 cutoff to start showing cutoff warnings. Use for example 21 days or 3 weeks.")
7775
submission_start_day_offset = models.IntegerField(blank=True,
@@ -415,7 +413,7 @@ class TimeSlot(models.Model):
415413
type = models.ForeignKey(TimeSlotTypeName)
416414
name = models.CharField(max_length=255)
417415
time = models.DateTimeField()
418-
duration = TimedeltaField()
416+
duration = models.DurationField(default=datetime.timedelta(0))
419417
location = models.ForeignKey(Room, blank=True, null=True)
420418
show_location = models.BooleanField(default=True, help_text="Show location in agenda.")
421419
sessions = models.ManyToManyField('Session', related_name='slots', through='SchedTimeSessAssignment', blank=True, help_text=u"Scheduled session, if any.")
@@ -986,7 +984,7 @@ class Session(models.Model):
986984
agenda_note = models.CharField(blank=True, max_length=255)
987985
requested = models.DateTimeField(default=datetime.datetime.now)
988986
requested_by = models.ForeignKey(Person)
989-
requested_duration = TimedeltaField(default=0)
987+
requested_duration = models.DurationField(default=datetime.timedelta(0))
990988
comments = models.TextField(blank=True)
991989
status = models.ForeignKey(SessionStatusName)
992990
scheduled = models.DateTimeField(null=True, blank=True)

ietf/meeting/test_data.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ def make_interim_meeting(group,date,status='sched'):
1414
time = datetime.datetime.combine(date, datetime.time(9))
1515
meeting = create_interim_meeting(group=group,date=date)
1616
session = Session.objects.create(meeting=meeting, group=group,
17-
attendees=10, requested_by=system_person,
18-
requested_duration=20, status_id=status,
17+
attendees=10, requested_by=system_person, status_id=status,
18+
requested_duration=datetime.timedelta(minutes=20),
1919
remote_instructions='http://webex.com',
2020
scheduled=datetime.datetime.now(),type_id="session")
2121
slot = TimeSlot.objects.create(
@@ -56,35 +56,37 @@ def make_meeting_test_data(meeting=None):
5656

5757
# slots
5858
session_date = meeting.date + datetime.timedelta(days=1)
59-
slot1 = TimeSlot.objects.create(meeting=meeting, type_id="session", duration=30 * 60, location=room,
59+
slot1 = TimeSlot.objects.create(meeting=meeting, type_id="session", location=room,
60+
duration=datetime.timedelta(minutes=30),
6061
time=datetime.datetime.combine(session_date, datetime.time(9, 30)))
61-
slot2 = TimeSlot.objects.create(meeting=meeting, type_id="session", duration=30 * 60, location=room,
62+
slot2 = TimeSlot.objects.create(meeting=meeting, type_id="session", location=room,
63+
duration=datetime.timedelta(minutes=30),
6264
time=datetime.datetime.combine(session_date, datetime.time(10, 30)))
63-
breakfast_slot = TimeSlot.objects.create(meeting=meeting, type_id="lead", duration=90 * 60,
64-
location=breakfast_room,
65-
time=datetime.datetime.combine(session_date, datetime.time(7,0)))
65+
breakfast_slot = TimeSlot.objects.create(meeting=meeting, type_id="lead", location=breakfast_room,
66+
duration=datetime.timedelta(minutes=90),
67+
time=datetime.datetime.combine(session_date, datetime.time(7,0)))
6668
# mars WG
6769
mars = Group.objects.get(acronym='mars')
6870
mars_session = Session.objects.create(meeting=meeting, group=mars,
69-
attendees=10, requested_by=system_person,
70-
requested_duration=20, status_id="schedw",
71+
attendees=10, requested_by=system_person, status_id="schedw",
72+
requested_duration=datetime.timedelta(minutes=20),
7173
scheduled=datetime.datetime.now(),type_id="session")
7274
SchedTimeSessAssignment.objects.create(timeslot=slot1, session=mars_session, schedule=schedule)
7375
SchedTimeSessAssignment.objects.create(timeslot=slot2, session=mars_session, schedule=unofficial_schedule)
7476

7577
# ames WG
7678
ames_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="ames"),
77-
attendees=10, requested_by=system_person,
78-
requested_duration=20, status_id="schedw",
79+
attendees=10, requested_by=system_person, status_id="schedw",
80+
requested_duration=datetime.timedelta(minutes=20),
7981
scheduled=datetime.datetime.now(),type_id="session")
8082
SchedTimeSessAssignment.objects.create(timeslot=slot2, session=ames_session, schedule=schedule)
8183
SchedTimeSessAssignment.objects.create(timeslot=slot1, session=ames_session, schedule=unofficial_schedule)
8284

8385
# IESG breakfast
8486
iesg_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="iesg"),
85-
name="IESG Breakfast",
86-
attendees=25, requested_by=system_person,
87-
requested_duration=20, status_id="schedw",
87+
name="IESG Breakfast", attendees=25,
88+
requested_by=system_person, status_id="schedw",
89+
requested_duration=datetime.timedelta(minutes=20),
8890
scheduled=datetime.datetime.now(),type_id="lead")
8991
SchedTimeSessAssignment.objects.create(timeslot=breakfast_slot, session=iesg_session, schedule=schedule)
9092
# No breakfast on unofficial schedule

ietf/secr/meetings/forms.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from ietf.group.models import Group
77
from ietf.meeting.models import Meeting, Room, TimeSlot, Session, SchedTimeSessAssignment
8-
from ietf.meeting.timedeltafield import TimedeltaFormField, TimedeltaWidget
98
from ietf.name.models import TimeSlotTypeName
109

1110

@@ -175,7 +174,7 @@ def clean_group(self):
175174
class TimeSlotForm(forms.Form):
176175
day = forms.ChoiceField(choices=DAYS_CHOICES)
177176
time = forms.TimeField()
178-
duration = TimedeltaFormField(widget=TimedeltaWidget(attrs={'inputs':['hours','minutes']}))
177+
duration = forms.DurationField(help_text="Enter duration as 'DD HH:MM:SS', or parts thereof. '3:42' means 3 minutes, 42 seconds, not 3 hours 42 minutes.")
179178
name = forms.CharField(help_text='Name that appears on the agenda')
180179

181180
class NonSessionForm(TimeSlotForm):

ietf/secr/meetings/tests.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def test_meetings_times_delete(self):
229229
def test_meetings_times_edit(self):
230230
meeting = make_meeting_test_data()
231231
timeslot = TimeSlot.objects.filter(meeting=meeting,type='session').first()
232-
url = reverse('meetings_times_edit',kwargs={
232+
url = reverse('ietf.secr.meetings.views.times_edit',kwargs={
233233
'meeting_id':42,
234234
'schedule_name':'test-agenda',
235235
'time':timeslot.time.strftime("%Y:%m:%d:%H:%M")
@@ -238,8 +238,7 @@ def test_meetings_times_edit(self):
238238
response = self.client.post(url, {
239239
'day':'1',
240240
'time':'08:00',
241-
'duration_hours':'1',
242-
'duration_minutes':'0',
241+
'duration':'1 0:0:0',
243242
'name':'Testing'
244243
})
245244
self.assertEqual(response.status_code, 302)

ietf/secr/sreq/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ def no_session(request, acronym):
616616
meeting=meeting,
617617
requested=datetime.datetime.now(),
618618
requested_by=login,
619-
requested_duration=0,
619+
requested_duration=datetime.timedelta(0),
620620
status=SessionStatusName.objects.get(slug='notmeet'),
621621
type_id='session',
622622
)

ietf/settings.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,13 +398,14 @@ def skip_unreadable_post(record):
398398
"idindex/generate_all_id_txt.py",
399399
"idindex/generate_id_abstracts_txt.py",
400400
"idindex/generate_id_index_txt.py",
401-
"name/generate_fixtures.py",
402-
"review/import_from_review_tool.py",
403-
"ietf/settings*",
404-
"ietf/utils/test_runner.py",
405401
"ietf/checks.py",
406-
"ietf/utils/templatetags/debug_filters.py",
402+
"ietf/meeting/timedeltafield.py", # Dead code, kept for a migration include
407403
"ietf/review/import_from_review_tool.py",
404+
"ietf/settings*",
405+
"ietf/utils/templatetags/debug_filters.py",
406+
"ietf/utils/test_runner.py",
407+
"name/generate_fixtures.py",
408+
"review/import_from_review_tool.py",
408409
]
409410

410411
# These are filename globs. They are used by test_parse_templates() and

0 commit comments

Comments
 (0)