--- /dev/null
+ # coding=utf-8
+ from datetime import timedelta
+ from django import forms
+ from django.core.exceptions import ValidationError
+
+
-class PredefinedChoiceField(forms.ChoiceField):
- def valid_value(self, value):
- # any value is valid
- return True
-
-
-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")
from django.template.defaultfilters import capfirst
from pyqcg.utils import TaskStatus
-from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField, TimeRangeField
++from qcg.fields import TimeRangeField
from qcg.models import Task, Allocation
APPLICATION_CHOICES = (
CHOICES_PLACEHOLDER,
('bash', 'BASH'),
- ('python', 'Python'),
+ ('gromacs/4.6.3', 'GROMACS 4.6.3'),
('matlab', 'MATLAB'),
+ ('python', 'Python'),
)
QUEUE_CHOICES = (
CHOICES_PLACEHOLDER,
)
application = forms.ChoiceField(choices=APPLICATION_CHOICES, label=u"Aplikacja", required=False) # TODO choices
- executable = forms.CharField(label=u"Polecenie", max_length=500, required=False) # TODO grid ftp
- arguments = forms.CharField(label=u"Argumenty", max_length=1000, required=False)
-
- name = forms.CharField(label=u"Nazwa", max_length=100, required=False)
- note = forms.CharField(label=u"Notatka", widget=forms.Textarea(attrs={'rows': 2, 'cols': 40}), required=False)
+ executable = forms.CharField(label=u"Plik wykonywalny", max_length=500, required=False) # TODO grid ftp
+ script = forms.CharField(label=u"Skrypt", widget=forms.Textarea(attrs={'rows': 2, 'cols': 40}), required=False) # TODO saving to grid ftp
+ arguments = forms.MultipleChoiceField(label=u"Argumenty", required=False)
+ note = forms.CharField(label=u"Opis", widget=forms.Textarea(attrs={'rows': 2, 'cols': 40}), required=False)
grant = forms.CharField(label=u"Grant", max_length=100, required=False)
host = forms.ChoiceField(label=u"Host", choices=Host.CHOICES, required=False)
- queue = PredefinedChoiceField(choices=QUEUE_CHOICES, label=u"Kolejka", required=False)
+ properties = forms.MultipleChoiceField(label=u"Właściwości węzłów", required=False)
+ queue = forms.ChoiceField(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 = TimeRangeField(label=u"Wall time", required=False)
+ wall_time = forms.IntegerField(label=u"Wall time (s)", min_value=0, required=False) # TODO duration field
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)
+ modules = forms.MultipleChoiceField(label=u"Moduły", choices=MODULES_CHOICES, required=False) # TODO choices
+ reservation = forms.CharField(label=u"Rezerwacja", max_length=100, required=False)
# TODO grid ftp
input = forms.CharField(label=u"Standardowe wejście", max_length=500, required=False)
stage_in = forms.CharField(label=u"Stage in", max_length=500, required=False)
stage_out = forms.CharField(label=u"Stage out", max_length=500, required=False)
- properties = MultiplePredefinedChoiceField(label=u"Właściwości węzłów", required=False)
- modules = forms.MultipleChoiceField(label=u"Moduły", choices=MODULES_CHOICES, required=False) # TODO choices
-
- 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 = 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)
notify_type = forms.ChoiceField(label=u"Monitorowanie stanu", choices=NOTIFY_CHOICES, required=False, initial=0,
widget=forms.RadioSelect)
widget=forms.RadioSelect)
postprocess_cmd = forms.CharField(label=u"Polecenie", max_length=1000, required=False)
postprocess_script = forms.CharField(label=u"Skrypt", max_length=500, required=False) # TODO grid ftp
- native = MultiplePredefinedChoiceField(label=u"Parametry natywne", required=False)
+ native = forms.MultipleChoiceField(label=u"Opcje systemu kolejkowego", required=False)
persistent = forms.BooleanField(label=u"Trwałe", required=False)
- use_scratch = forms.BooleanField(label=u"Scratch", required=False)
+
+ def __init__(self, data=None, *args, **kwargs):
+ super(JobDescriptionForm, self).__init__(data, *args, **kwargs)
+
+ if data is not None:
+ # accept user defined choices
+ self.fields['queue'].choices += ((data.get('queue'), data.get('queue')), )
+ self.fields['arguments'].choices += ((v, v) for v in data.getlist('arguments'))
+ self.fields['properties'].choices += ((v, v) for v in data.getlist('properties'))
+ self.fields['native'].choices += ((v, v) for v in data.getlist('native'))
class EnvForm(forms.Form):
(HOST, u"Host"),
)
- columns = forms.MultipleChoiceField(choices=COLUMNS_CHOICES, label=u"Kolumny", required=False,
- widget=forms.CheckboxSelectMultiple)
+ columns = forms.MultipleChoiceField(choices=COLUMNS_CHOICES, initial=[k for k, v in COLUMNS_CHOICES[1:]],
+ label=u"Kolumny", required=False, widget=forms.CheckboxSelectMultiple)
<li role="presentation"><a href="#resources" data-toggle="tab">Zasoby</a></li>
<li role="presentation"><a href="#files" data-toggle="tab">Pliki</a></li>
<li role="presentation"><a href="#environment" data-toggle="tab">Środowisko</a></li>
- <li role="presentation"><a href="#reservation" data-toggle="tab">Rezerwacja</a></li>
<li role="presentation"><a href="#monitoring" data-toggle="tab">Powiadomienia</a></li>
<li role="presentation"><a href="#other" data-toggle="tab">Inne</a></li>
</ul>
</div>
</div>
- {% bootstrap_field form.executable layout="horizontal" form_group_class="form-group collapse" %}
+ {% bootstrap_field form.executable layout="horizontal" form_group_class="form-group collapse" %}
+ {% bootstrap_field form.script layout="horizontal" form_group_class="form-group collapse" %}
{% bootstrap_field form.arguments layout="horizontal" %}
- {% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.note layout="horizontal" %}
{% bootstrap_field form.grant layout="horizontal" %}
</fieldset>
<fieldset id="resources" class="tab-pane" role="tabpanel">
{% bootstrap_field form.host layout="horizontal" %}
{% bootstrap_field form.queue layout="horizontal" %}
+ {% bootstrap_field form.properties layout="horizontal" form_group_class="form-group collapse" %}
+ {% bootstrap_field form.modules layout="horizontal" form_group_class="form-group collapse" %}
{% 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" %}
+ {% bootstrap_field form.memory layout="horizontal" form_group_class="form-group collapse" %}
+ {% bootstrap_field form.memory_per_slot layout="horizontal" form_group_class="form-group collapse" %}
+ {% bootstrap_field form.reservation layout="horizontal" form_group_class="form-group collapse" %}
</fieldset>
<fieldset id="files" class="tab-pane" role="tabpanel">
{% bootstrap_field form.input layout="horizontal" %}
- {% bootstrap_field form.output layout="horizontal" %}
- {% bootstrap_field form.error layout="horizontal" %}
{% bootstrap_field form.stage_in layout="horizontal" %}
- {% bootstrap_field form.stage_out layout="horizontal" %}
+ {% bootstrap_field form.stage_out layout="horizontal" form_group_class="form-group collapse" %}
</fieldset>
<fieldset id="environment" class="tab-pane" role="tabpanel">
- {% bootstrap_field form.properties layout="horizontal" %}
{{ env_formset.management_form }}
<div class="form-group">
</div>
</div>
</div>
-
- {% bootstrap_field form.modules 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" %}
- {% 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>
<fieldset id="monitoring" class="tab-pane" role="tabpanel">
</div>
</div>
- <div class="form-group">
- <label class="col-sm-3 col-md-4 control-label">Monitorowanie wyjścia</label>
- <div class="col-sm-9 col-md-6">
- <div class="btn-group" data-toggle="buttons">
- {% for option in form.watch_output_type %}
- <label class="btn btn-default">
- <input type="radio" autocomplete="off" name="{{ option.name }}" value="{{ option.choice_value }}"
- {% if option.is_checked %}checked{% endif %}
- data-target=".watch-output-type-{{ option.choice_value }}"> {{ option.choice_label }}
- </label>
- {% endfor %}
+ <div class="collapse">
+ <div class="form-group">
+ <label class="col-sm-3 col-md-4 control-label">Monitorowanie wyjścia</label>
+ <div class="col-sm-9 col-md-6">
+ <div class="btn-group" data-toggle="buttons">
+ {% for option in form.watch_output_type %}
+ <label class="btn btn-default">
+ <input type="radio" autocomplete="off" name="{{ option.name }}" value="{{ option.choice_value }}"
+ {% if option.is_checked %}checked{% endif %}
+ data-target=".watch-output-type-{{ option.choice_value }}"> {{ option.choice_label }}
+ </label>
+ {% endfor %}
+ </div>
</div>
</div>
- </div>
- <div class="tab-content">
- <div class="tab-pane watch-output-type-0"></div>
+ <div class="tab-content">
+ <div class="tab-pane watch-output-type-0"></div>
- <div class="tab-pane watch-output-type-1 watch-output-type-2" style="margin-top: 15px">
- {% bootstrap_field form.watch_output_address layout="horizontal" %}
- {% bootstrap_field form.watch_output_pattern layout="horizontal" %}
+ <div class="tab-pane watch-output-type-1 watch-output-type-2" style="margin-top: 15px">
+ {% bootstrap_field form.watch_output_address layout="horizontal" %}
+ {% bootstrap_field form.watch_output_pattern layout="horizontal" %}
+ </div>
</div>
</div>
</fieldset>
{% bootstrap_field form.native layout="horizontal" %}
{% bootstrap_checkbox form.persistent %}
- {% bootstrap_checkbox form.use_scratch %}
</fieldset>
</div>