time range form field
authorgrzegorz.prokopczyk@gmail.com <grzegorz.prokopczyk@gmail.com>
Mon, 2 Mar 2015 12:12:39 +0000 (13:12 +0100)
committergrzegorz.prokopczyk@gmail.com <grzegorz.prokopczyk@gmail.com>
Mon, 2 Mar 2015 12:12:39 +0000 (13:12 +0100)
qcg/fields.py
qcg/forms.py
qcg/templates/qcg/job_new.html
qcg/templates/qcg/time_range_field.html [new file with mode: 0644]

index 3702aad..3e5ec44 100644 (file)
@@ -1,11 +1,65 @@
-from django.forms import ChoiceField, MultipleChoiceField
+# coding=utf-8
+from datetime import timedelta
+from django import forms
+from django.core.exceptions import ValidationError
 
 
-class PredefinedChoiceField(ChoiceField):
+class PredefinedChoiceField(forms.ChoiceField):
     def valid_value(self, value):
         # any value is valid
         return True
 
 
-class MultiplePredefinedChoiceField(MultipleChoiceField, PredefinedChoiceField):
+class MultiplePredefinedChoiceField(forms.MultipleChoiceField, PredefinedChoiceField):
     pass
+
+
+class TimeRangeWidget(forms.MultiWidget):
+    def decompress(self, value):
+        if not value:
+            return [0, TimeRangeField.SECONDS]
+
+        seconds = value.seconds + 86400 * value.days
+
+        if seconds % 60 != 0:
+            return [seconds, TimeRangeField.SECONDS]
+        elif seconds % 3600 != 0:
+            return [seconds / 60, TimeRangeField.MINUTES]
+        elif seconds % 86400 != 0:
+            return [seconds / 3600, TimeRangeField.HOURS]
+        else:
+            return [seconds / 86400, TimeRangeField.DAYS]
+
+
+class TimeRangeField(forms.MultiValueField):
+    SECONDS, MINUTES, HOURS, DAYS = range(4)
+    UNIT_CHOICES = (
+        (SECONDS, u"Sekund"),
+        (MINUTES, u"Minut"),
+        (HOURS, u"Godzin"),
+        (DAYS, u"Dni"),
+    )
+
+    value = forms.IntegerField(min_value=0)
+    unit = forms.ChoiceField(choices=UNIT_CHOICES)
+
+    widget = TimeRangeWidget(widgets=(value.widget, unit.widget))
+
+    def __init__(self, *args, **kwargs):
+        super(TimeRangeField, self).__init__((self.value, self.unit), *args, **kwargs)
+
+    def compress(self, data_list):
+        try:
+            unit = int(data_list[1])
+            if unit == self.SECONDS:
+                return timedelta(seconds=data_list[0])
+            elif unit == self.MINUTES:
+                return timedelta(minutes=data_list[0])
+            elif unit == self.HOURS:
+                return timedelta(hours=data_list[0])
+            elif unit == self.DAYS:
+                return timedelta(days=data_list[0])
+            else:
+                raise ValidationError(u"Nieprawidłowa jednostka")
+        except ValueError:
+            raise ValidationError(u"Nieprawidłowa jednostka")
index 83a053a..7b11d13 100644 (file)
@@ -4,7 +4,7 @@ from django.core.validators import RegexValidator
 from django.template.defaultfilters import capfirst
 from pyqcg.utils import TaskStatus
 
-from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField
+from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField, TimeRangeField
 from qcg.models import Task, Allocation
 
 
@@ -120,7 +120,7 @@ class JobDescriptionForm(forms.Form):
     queue = PredefinedChoiceField(choices=QUEUE_CHOICES, label=u"Kolejka", required=False)
     procs = forms.IntegerField(label=u"Liczba procesów", min_value=0, required=False)
     nodes = forms.CharField(label=u"Topologia węzłów", max_length=10, validators=[nodes_validator], required=False)
-    wall_time = forms.IntegerField(label=u"Wall time (s)", min_value=0, required=False)  # TODO duration field
+    wall_time = TimeRangeField(label=u"Wall time", required=False)
     memory = forms.IntegerField(label=u"Pamięć (MB)", min_value=0, required=False)
     memory_per_slot = forms.IntegerField(label=u"Pamięci per proces (MB)", min_value=0, required=False)
 
@@ -136,7 +136,7 @@ class JobDescriptionForm(forms.Form):
 
     not_after = forms.DateTimeField(label=u"Nie później niż", required=False)
     not_before = forms.DateTimeField(label=u"Nie wcześniej niż", required=False)
-    deadline = forms.IntegerField(label=u"Deadline (s)", min_value=0, required=False)  # TODO duration field
+    deadline = TimeRangeField(label=u"Deadline", required=False)
     reservation = forms.CharField(label=u"Rezerwacja", max_length=100, required=False)
 
     monitoring = forms.BooleanField(label=u"Portal QCG-Monitoring", required=False)
index d1e5de6..37a4fc5 100644 (file)
                 {% bootstrap_field form.queue layout="horizontal" %}
                 {% bootstrap_field form.procs layout="horizontal" %}
                 {% bootstrap_field form.nodes layout="horizontal" form_group_class="form-group collapse" %}
-                {% bootstrap_field form.wall_time layout="horizontal" %}
+                {% include 'qcg/time_range_field.html' with field_name='wall_time' field=form.wall_time %}
                 {% bootstrap_field form.memory layout="horizontal" %}
                 {% bootstrap_field form.memory_per_slot layout="horizontal" %}
             </fieldset>
             <fieldset id="reservation" class="tab-pane" role="tabpanel">
                 {% bootstrap_field form.not_before layout="horizontal" %}
                 {% bootstrap_field form.not_after layout="horizontal" %}
-                {% bootstrap_field form.deadline layout="horizontal" %}
+                {% include 'qcg/time_range_field.html' with field_name='deadline' field=form.deadline %}
                 {% bootstrap_field form.reservation layout="horizontal" form_group_class="form-group collapse" %}
             </fieldset>
 
diff --git a/qcg/templates/qcg/time_range_field.html b/qcg/templates/qcg/time_range_field.html
new file mode 100644 (file)
index 0000000..c9570c5
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="form-group">
+    <label class="col-sm-3 col-md-4 control-label" for="id_{{ field_name }}_0">{{ field.label }}</label>
+    <div class="col-sm-7 col-md-4">
+        <input class="form-control" id="id_{{ field_name }}_0" min="0" name="{{ field_name }}_0" value="{{ field.value.0 }}" type="number">
+    </div>
+    <div class="col-sm-2">
+        <select class="form-control" id="id_{{ field_name }}_1" name="{{ field_name }}_1">
+            <option value="0"{% if field.value.1 == 0 %} selected{% endif %}>Sekund</option>
+            <option value="1"{% if field.value.1 == 1 %} selected{% endif %}>Minut</option>
+            <option value="2"{% if field.value.1 == 2 %} selected{% endif %}>Godzin</option>
+            <option value="3"{% if field.value.1 == 3 %} selected{% endif %}>Dni</option>
+        </select>
+    </div>
+</div>
\ No newline at end of file