+++ /dev/null
-from django.forms import ChoiceField, MultipleChoiceField
-
-
-class PredefinedChoiceField(ChoiceField):
- def valid_value(self, value):
- # any value is valid
- return True
-
-
-class MultiplePredefinedChoiceField(MultipleChoiceField, PredefinedChoiceField):
- pass
from django.template.defaultfilters import capfirst
from pyqcg.utils import TaskStatus
-from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField
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 = 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)
- output = forms.CharField(label=u"Standardowe wyjście", max_length=500, required=False)
- error = forms.CharField(label=u"Standardowe wyjście błędów", 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 = forms.IntegerField(label=u"Deadline (s)", min_value=0, required=False) # TODO duration field
- 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):
@staticmethod
def qcg_map(qcg_node):
- return {'name': qcg_node.name,
- # FIXME
- 'count': qcg_node.slots_count.intValue() if qcg_node.slots_count is not None else None}
+ return {'name': qcg_node.name, 'count': qcg_node.slots_count}
textarea {
resize: vertical;
+ min-height: 34px;
}
<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" %}
- {% 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" %}
- {% bootstrap_field form.deadline layout="horizontal" %}
- {% 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>
from django_openid_auth.views import make_consumer
from openid.extensions import ax
from pyqcg import QCG
+from pyqcg.description import JobDescription
+from pyqcg.utils import Credential
from qcg.forms import FiltersForm, ColumnsForm, JobDescriptionForm, EnvFormSet
from qcg.utils import update_user_data, paginator_context
return render(request, 'qcg/job.html', {'job': job})
+@login_required
def task_details(request, job_id, task_id):
task = get_object_or_404(request.user.tasks.select_related('job').prefetch_related('allocations'),
job__job_id=job_id, task_id=task_id)
return render(request, 'qcg/task.html', {'task': task})
+@login_required
def job_new(request):
- return render(request, 'qcg/job_new.html', {'form': JobDescriptionForm(), 'env_formset': EnvFormSet()})
+ if request.method == 'POST':
+ QCG.start()
+
+ form = JobDescriptionForm(request.POST)
+ env_formset = EnvFormSet(request.POST)
+
+ if form.is_valid() and env_formset.is_valid():
+ print form.cleaned_data
+
+ desc = JobDescription(Credential(request.session['proxy']))
+
+ application = form.cleaned_data['application']
+ if '/' in application:
+ app, ver = application.split('1', 1)
+ desc.application.set_name(app)
+ desc.application.set_version(ver)
+ else:
+ desc.application.set_name(application)
+
+ # TODO script
+ # TODO executable
+ desc.arguments = form.cleaned_data['arguments']
+ desc.note = form.cleaned_data['note']
+ desc.grant = form.cleaned_data['grant']
+ desc.host_candidates = [(form.cleaned_data['host'], 'type?')] # FIXME WTF ?!?
+ desc.properties = form.cleaned_data['properties']
+ # TODO queue
+ # TODO procs
+ # TODO nodes
+ desc.wall_time = timedelta(seconds=form.cleaned_data['wall_time']) # FIXME odpowiedni typ pola
+ desc.memory = form.cleaned_data['memory']
+ desc.memory_per_slot = form.cleaned_data['memory_per_slot']
+ desc.variable = [(env['name'], env['value']) for env in env_formset.cleaned_data if not env['DELETE']]
+ desc.modules = form.cleaned_data['modules']
+ desc.natives = form.cleaned_data['native']
+ desc.reservation = ("LOCAL", form.cleaned_data['reservation'])
+ # TODO input
+ # TODO stage_in
+ # TODO stage_out
+ # TODO monitoring
+ # TODO notify_type
+ # TODO notify_address
+ # TODO watch_output_type
+ # TODO watch_output_address
+ # TODO watch_output_pattern
+ # TODO preprocess_type
+ # TODO preprocess_cmd
+ # TODO preprocess_script
+ # TODO postprocess_type
+ # TODO postprocess_cmd
+ # TODO postprocess_script
+ desc.persistent = form.cleaned_data['persistent']
+
+ for prop in ('arguments', 'note', 'grant', 'host_candidates', 'wall_time', 'memory',
+ 'memory_per_slot', 'properties', 'variable', 'modules', 'natives', 'persistent', 'reservation'):
+ print prop, type(getattr(desc, prop)), repr(getattr(desc, prop))
+
+ print desc.xml_description
+
+ else:
+ form = JobDescriptionForm()
+ env_formset = EnvFormSet()
+
+ return render(request, 'qcg/job_new.html', {'form': form, 'env_formset': env_formset})