From: Maciej Tronowski Date: Thu, 5 Mar 2015 19:51:35 +0000 (+0100) Subject: fixes for updated api X-Git-Tag: v1.0~136 X-Git-Url: http://mmka.chem.univ.gda.pl/gitweb/?a=commitdiff_plain;h=82dc969d31d8b805718f81ca470263b9b63fc883;p=qcg-portal.git fixes for updated api --- diff --git a/qcg/forms.py b/qcg/forms.py index a3524d5..3450783 100644 --- a/qcg/forms.py +++ b/qcg/forms.py @@ -9,7 +9,7 @@ from qcg.models import Task, Allocation date_range_validator = RegexValidator(r'[0-9]{2}\.[0-9]{2}\.[0-9]{4} - [0-9]{2}\.[0-9]{2}\.[0-9]{4}') -nodes_validator = RegexValidator(r'^[0-9]{1,3}(:[0-9]{1,2}){0,2}$') +nodes_validator = RegexValidator(r'^[0-9]{1,3}:[0-9]{1,2}(:[0-9]{1,2})?$') env_name_validator = RegexValidator(r'^[a-zA-Z_][a-zA-Z0-9_]*$') CHOICES_PLACEHOLDER = (None, '') @@ -81,6 +81,18 @@ class JobDescriptionForm(forms.Form): (REEF, u'Reef'), (ZEUS, u'Zeus'), ) + + class Process(object): + NONE = '' + CMD = 'c' + SCRIPT = 's' + + CHOICES = ( + (NONE, u'Brak'), + (CMD, u'Polecenie'), + (SCRIPT, u'Skrypt'), + ) + APPLICATION_CHOICES = ( CHOICES_PLACEHOLDER, ('bash', 'BASH'), @@ -98,15 +110,10 @@ class JobDescriptionForm(forms.Form): ('plgrid/apps/python', 'plgrid/apps/python'), ('plgrid/apps/matlab', 'plgrid/apps/matlab'), ) - NOTIFY_CHOICES = ( - (0, u'Brak'), - (1, u'E-mail'), - (2, u'XMPP'), - ) - PROCESS_CHOICES = ( - (0, u'Brak'), - (1, u'Polecenie'), - (2, u'Skrypt'), + PROTOCOL_CHOICES = ( + ('', u'Brak'), + ('mailto', u'E-mail'), + ('xmpp', u'XMPP'), ) application = forms.ChoiceField(choices=APPLICATION_CHOICES, label=u"Aplikacja", required=False) # TODO choices @@ -116,7 +123,7 @@ class JobDescriptionForm(forms.Form): 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.MultipleChoiceField(label=u"Host", choices=Host.CHOICES, required=False) + hosts = forms.MultipleChoiceField(label=u"Host", choices=Host.CHOICES, 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) @@ -133,20 +140,20 @@ class JobDescriptionForm(forms.Form): stage_out = forms.CharField(label=u"Stage out", max_length=500, 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, + notify_type = forms.ChoiceField(label=u"Monitorowanie stanu", choices=PROTOCOL_CHOICES, required=False, initial='', widget=forms.RadioSelect) notify_address = forms.EmailField(label=u"Adres", required=False) - watch_output_type = forms.ChoiceField(label=u"Monitorowanie wyjścia", choices=NOTIFY_CHOICES, required=False, - initial=0, widget=forms.RadioSelect) + watch_output_type = forms.ChoiceField(label=u"Monitorowanie wyjścia", choices=PROTOCOL_CHOICES, required=False, + initial='', widget=forms.RadioSelect) watch_output_address = forms.EmailField(label=u"Adres", required=False) watch_output_pattern = forms.CharField(label=u"Wzorzec", max_length=500, required=False) - preprocess_type = forms.ChoiceField(label=u"Preprocessing", choices=PROCESS_CHOICES, required=False, initial=0, - widget=forms.RadioSelect) + preprocess_type = forms.ChoiceField(label=u"Preprocessing", choices=Process.CHOICES, required=False, + initial=Process.NONE, widget=forms.RadioSelect) preprocess_cmd = forms.CharField(label=u"Polecenie", max_length=1000, required=False) preprocess_script = forms.CharField(label=u"Skrypt", max_length=500, required=False) # TODO grid ftp - postprocess_type = forms.ChoiceField(label=u"Postprocessing", choices=PROCESS_CHOICES, required=False, initial=0, - widget=forms.RadioSelect) + postprocess_type = forms.ChoiceField(label=u"Postprocessing", choices=Process.CHOICES, required=False, + initial=Process.CHOICES, 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 = forms.MultipleChoiceField(label=u"Opcje systemu kolejkowego", required=False) @@ -162,6 +169,48 @@ class JobDescriptionForm(forms.Form): self.fields['properties'].choices += ((v, v) for v in data.getlist('properties')) self.fields['native'].choices += ((v, v) for v in data.getlist('native')) + def clean(self): + data = super(JobDescriptionForm, self).clean() + + notify_type = data.get('notify_type') + data['notify'] = u'{}:{}'.format(notify_type, data['notify_address']) if notify_type else '' + + wo_type = data.get('watch_output_type') + data['watch_output'] = u'{}:{}'.format(wo_type, data['watch_output_address']) if wo_type else '' + + preprocess_type = data.get('preprocess_type') + if preprocess_type == self.Process.CMD: + data['preprocess'] = data['preprocess_cmd'] + elif preprocess_type == self.Process.SCRIPT: + data['preprocess'] = data['preprocess_script'] + else: + data['preprocess'] = '' + + postprocess_type = data.get('postprocess_type') + if postprocess_type == self.Process.CMD: + data['postprocess'] = data['postprocess_cmd'] + elif postprocess_type == self.Process.SCRIPT: + data['postprocess'] = data['postprocess_script'] + else: + data['postprocess'] = '' + + def clean_application(self): + value = self.cleaned_data['application'] + + if '/' in value: + return value.split('/', 1) + + return value, None + + def clean_nodes(self): + value = map(int, self.cleaned_data['nodes'].split(':', 2)) + + if len(value) == 3: + return tuple(value) + + nodes, slots = value + return nodes, slots, slots + class EnvForm(forms.Form): name = forms.CharField(label=u"Nazwa", max_length=100, validators=[env_name_validator], diff --git a/qcg/templates/qcg/job_new.html b/qcg/templates/qcg/job_new.html index 7929749..8cf2bbe 100644 --- a/qcg/templates/qcg/job_new.html +++ b/qcg/templates/qcg/job_new.html @@ -29,7 +29,7 @@ } } }); - $('#id_modules, #id_host').selectize({ + $('#id_modules, #id_hosts').selectize({ plugins: ['remove_button'] }); @@ -78,6 +78,14 @@ {% block container %}

{% block title %}Zleć zadanie{% endblock %}

+ {% if errors %} +
+ Uwaga! Formularz zawiera błędy. + {{ form.non_field_errors }} + {{ env_formset.non_field_errors }} +
+ {% endif %} +
{% csrf_token %} @@ -109,7 +117,7 @@
- {% bootstrap_field form.host layout="horizontal" %} + {% bootstrap_field form.hosts 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" %} @@ -157,7 +165,7 @@ {% endfor %} @@ -181,7 +189,7 @@ {% endfor %} @@ -208,7 +216,7 @@ {% endfor %} @@ -235,7 +243,7 @@ {% endfor %} diff --git a/qcg/views.py b/qcg/views.py index aaa0bdc..0be3d73 100644 --- a/qcg/views.py +++ b/qcg/views.py @@ -163,56 +163,35 @@ def job_new(request): desc = JobDescription(Credential(request.session['proxy'])) - application = form.cleaned_data['application'] - if '/' in application: - app_tuple = application.split('/', 1) - else: - app_tuple = (application, None) - desc.application = app_tuple + direct_map = ('application', 'arguments', 'note', 'grant', 'hosts', 'properties', 'queue', 'procs', 'nodes', + 'wall_time', 'memory', 'memory_per_slot', 'modules', 'native', 'notify', 'preprocess', + 'postprocess', 'persistent') + for name in direct_map: + if form.cleaned_data[name]: + setattr(desc, name, form.cleaned_data[name]) + + desc.reservation = ('LOCAL', form.cleaned_data['reservation']) + desc.watch_output = (form.cleaned_data['watch_output'], form.cleaned_data['watch_output_pattern']) + desc.env_variables += [(env['name'], env['value']) for env in env_formset.cleaned_data if not env['DELETE']] # TODO script # TODO executable - desc.arguments = form.cleaned_data['arguments'] - desc.note = form.cleaned_data['note'] - desc.grant = form.cleaned_data['grant'] - desc.hosts = form.cleaned_data['host'] - desc.properties = form.cleaned_data['properties'] - # TODO queue - # TODO procs - # TODO nodes - if form.cleaned_data['wall_time'] is not None: - desc.wall_time = form.cleaned_data['wall_time'] - desc.memory = form.cleaned_data['memory'] - desc.memory_per_slot = form.cleaned_data['memory_per_slot'] - desc.env_variables = [(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 ('application', 'arguments', 'note', 'grant', 'hosts', 'wall_time', 'memory', 'memory_per_slot', - 'properties', 'env_variables', 'modules', 'natives', 'persistent', 'reservation'): + + for prop in direct_map + ('env_variables', 'reservation', 'watch_output'): print prop, type(getattr(desc, prop)), repr(getattr(desc, prop)) print desc.xml_description + print repr(form.errors) + print repr(env_formset.errors) else: form = JobDescriptionForm() env_formset = EnvFormSet() - return render(request, 'qcg/job_new.html', {'form': form, 'env_formset': env_formset}) + errors = form.errors or (env_formset.is_bound and not env_formset.is_valid) + + return render(request, 'qcg/job_new.html', {'form': form, 'env_formset': env_formset, 'errors': errors})