Extended the form fields used for duration to accept additional formats, including formats the secretariat are currently using, in order to avoid trouble with the TimedeltaField --> DurationField transition.

- Legacy-Id: 12598
This commit is contained in:
Henrik Levkowetz 2016-12-21 15:26:32 +00:00
parent 3d6b370c59
commit 67b2fc1107
4 changed files with 68 additions and 6 deletions

View file

@ -15,12 +15,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='meeting',
name='xidsubmit_cutoff_time_utc',
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),
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:59:59.", blank=True),
),
migrations.AddField(
model_name='meeting',
name='xidsubmit_cutoff_warning_days',
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),
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' or '21 days'.", blank=True),
),
migrations.AddField(
model_name='session',

View file

@ -68,10 +68,10 @@ class Meeting(models.Model):
help_text = "The number of days before the meeting start date when the submission of -01 drafts etc. will be closed.")
idsubmit_cutoff_time_utc = models.DurationField(blank=True,
default=settings.IDSUBMIT_DEFAULT_CUTOFF_TIME_UTC,
help_text = "The time of day (UTC) after which submission will be closed. Use for example 23 hours, 59 minutes, 59 seconds.")
help_text = "The time of day (UTC) after which submission will be closed. Use for example 23:59:59.")
idsubmit_cutoff_warning_days = models.DurationField(blank=True,
default=settings.IDSUBMIT_DEFAULT_CUTOFF_WARNING_DAYS,
help_text = "How long before the 00 cutoff to start showing cutoff warnings. Use for example 21 days or 3 weeks.")
help_text = "How long before the 00 cutoff to start showing cutoff warnings. Use for example '21' or '21 days'.")
submission_start_day_offset = models.IntegerField(blank=True,
default=settings.MEETING_MATERIALS_DEFAULT_SUBMISSION_START_DAYS,
help_text = "The number of days before the meeting start date after which meeting materials will be accepted.")

View file

@ -6,7 +6,7 @@ from django import forms
from ietf.group.models import Group
from ietf.meeting.models import Meeting, Room, TimeSlot, Session, SchedTimeSessAssignment
from ietf.name.models import TimeSlotTypeName
import ietf.utils.fields
DAYS_CHOICES = ((-1,'Saturday'),
(0,'Sunday'),
@ -87,10 +87,18 @@ class TimeChoiceField(forms.ChoiceField):
# Forms
#----------------------------------------------------------
class MeetingModelForm(forms.ModelForm):
idsubmit_cutoff_time_utc = ietf.utils.fields.DurationField()
idsubmit_cutoff_warning_days = ietf.utils.fields.DurationField()
class Meta:
model = Meeting
exclude = ('type', 'agenda', 'session_request_lock_message')
def __init__(self,*args,**kwargs):
super(MeetingModelForm, self).__init__(*args,**kwargs)
for f in [ 'idsubmit_cutoff_warning_days', 'idsubmit_cutoff_time_utc', ]:
self.fields[f].help_text = kwargs['instance']._meta.get_field(f).help_text
def clean_number(self):
number = self.cleaned_data['number']
if not number.isdigit():
@ -174,7 +182,7 @@ class NonSessionEditForm(forms.Form):
class TimeSlotForm(forms.Form):
day = forms.ChoiceField(choices=DAYS_CHOICES)
time = forms.TimeField()
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.")
duration = ietf.utils.fields.DurationField()
name = forms.CharField(help_text='Name that appears on the agenda')
class NonSessionForm(TimeSlotForm):

View file

@ -1,5 +1,15 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import re
import six
import datetime
import debug
from django import forms
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django.utils.dateparse import parse_duration
class MultiEmailField(forms.Field):
def to_python(self, value):
@ -64,3 +74,47 @@ class DatepickerDateField(forms.DateField):
self.widget.attrs["placeholder"] = date_format
for k, v in picker_settings.iteritems():
self.widget.attrs["data-date-%s" % k] = v
# This accepts any ordered combination of labelled days, hours, minutes, seconds
ext_duration_re = re.compile(
r'^'
r'(?:(?P<days>-?\d+) ?(?:d|days))?'
r'(?:[, ]*(?P<hours>-?\d+) ?(?:h|hours))?'
r'(?:[, ]*(?P<minutes>-?\d+) ?(?:m|minutes))?'
r'(?:[, ]*(?P<seconds>-?\d+) ?(?:s|seconds))?'
r'$'
)
# This requires hours and minutes, and accepts optional X days and :SS
mix_duration_re = re.compile(
r'^'
r'(?:(?P<days>-?\d+) ?(?:d|days)[, ]*)?'
r'(?:(?P<hours>-?\d+))'
r'(?::(?P<minutes>-?\d+))'
r'(?::(?P<seconds>-?\d+))?'
r'$'
)
def parse_duration_ext(value):
if value.strip() != '':
match = ext_duration_re.match(value)
if not match:
match = mix_duration_re.match(value)
if not match:
return parse_duration(value)
else:
kw = match.groupdict()
kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None}
return datetime.timedelta(**kw)
class DurationField(forms.DurationField):
def to_python(self, value):
if value in self.empty_values:
return None
if isinstance(value, datetime.timedelta):
return value
value = parse_duration_ext(value)
if value is None:
raise ValidationError(self.error_messages['invalid'], code='invalid')
return value