PageRenderTime 28ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/templates/workflow/run.mako

https://bitbucket.org/cistrome/cistrome-harvard/
Mako | 420 lines | 392 code | 14 blank | 14 comment | 9 complexity | d0b36065cdd079619cf6b03330aa8a17 MD5 | raw file
  1<%inherit file="/base.mako"/>
  2
  3<%def name="javascripts()">
  4    ${parent.javascripts()}
  5    ${h.js( "jquery.autocomplete", "jquery.tipsy" )}
  6    <script type="text/javascript">
  7        $( function() {
  8            function show_tool_body(title){
  9                title.parent().css('border-bottom-width', '1px');
 10                title.next().show('fast');
 11            }
 12            function hide_tool_body(title){
 13                title.parent().css('border-bottom-width', '0px');
 14                title.next().hide('fast');
 15            }
 16            function toggle_tool_body(title) {
 17                if (title.next().is(':visible')){
 18                    hide_tool_body(title);
 19                }else{
 20                    show_tool_body(title);
 21                }
 22            }
 23            function toggle_multiinput(select) {
 24                var placeholder;
 25                if (select.attr('multiple')) {
 26                    $('.multiinput').removeClass('disabled');
 27                    if (select.val()) {
 28                        select.val(select.val()[0]);
 29                    } else {
 30                        select.val($('option:last', select).val());
 31                    }
 32                    select.removeAttr('multiple').removeAttr('size');
 33                    placeholder = 'type to filter';
 34                } else {
 35                    $('.multiinput').addClass('disabled');
 36                    $('.multiinput', select.parent().prev()).removeClass('disabled');
 37                    select.attr('multiple', 'multiple').attr('size', 8);
 38                    placeholder = 'type to filter, [enter] to select all';
 39                }
 40                $('input.multiinput-filter', select.parent()).attr(
 41                    'placeholder', placeholder);
 42            }
 43            $( "select[refresh_on_change='true']").change( function() {
 44                $( "#tool_form" ).submit();
 45            });
 46            $("div.toolFormTitle").click(function(){
 47                toggle_tool_body($(this));
 48            });
 49            // Collapse non-interactive run-workflow panels by default.
 50            $("div.toolFormBody:not(:has(select, textarea, input[type!=hidden], .wfpspan))").hide().parent().css('border-bottom-width', '0px');
 51            $("#show_all_tool_body").click(function(){
 52                $("div.toolFormTitle").each(function(){
 53                    show_tool_body($(this));
 54                });
 55            });
 56            $("#hide_all_tool_body").click(function(){
 57                $("div.toolFormTitle").each(function(){
 58                    hide_tool_body($(this));
 59                });
 60            });
 61            $("#new_history_cbx").click(function(){
 62                $("#new_history_input").toggle(this.checked);
 63            });
 64            $('select[name*="|input"]').removeAttr('multiple').each(function(i, s) {
 65                var select = $(s);
 66                var new_width = Math.max(200, select.width()) + 20;
 67                select.parent().prev().append(
 68                    $('<span class="icon-button multiinput"></span>').click(function() {
 69                        if ($(this).hasClass('disabled')) return;
 70                        toggle_multiinput(select);
 71                        select.focus();
 72                    }).attr('original-title',
 73                            'Enable/disable selection of multiple input ' +
 74                            'files. Each selected file will have an ' +
 75                            'instance of the workflow.').tipsy({gravity:'s'})
 76                );
 77                var filter = $('<input type="text" class="multiinput-filter" ' +
 78                               'placeholder="type to filter">');
 79                var filter_timeout = false;
 80                var original_rows = select.find('option');
 81                var previous_filter = '';
 82                // Todo: might have to choose keypress, depending on browser
 83                filter.keydown(function(e) {
 84                    var filter_select = function() {
 85                        var f = $.trim(filter.val());
 86                        var filtered_rows = original_rows;
 87                        if (f.length >= 1) {
 88                            filtered_rows = original_rows.filter(function() {
 89                                return new RegExp(f, 'ig').test($(this).text());
 90                            });
 91                        }
 92                        select.html('');
 93                        select.html(filtered_rows);
 94                    };
 95                    if (e.which == 13) { // 13 = enter key
 96                        e.preventDefault();
 97                        multi = select.attr('multiple');
 98                        if (typeof multi !== 'undefined' && multi !== false) {
 99                            if (!select.find('option:not(:selected)').length) {
100                                select.find('option').removeAttr('selected');
101                            } else {
102                                select.find('option').attr('selected', 'selected');
103                            }
104                        }
105                        return;
106                    }
107                    if (filter.val() != previous_filter) {
108                        if (filter_timeout) clearTimeout(filter_timeout);
109                        timeout = setTimeout(filter_select, 300);
110                        previous_filter = filter.val();
111                    }
112                }).width(new_width).css('display', 'block');
113                select.after(filter);
114                select.width(new_width);
115            });
116        });
117    </script>
118</%def>
119
120<%def name="stylesheets()">
121    ${parent.stylesheets()}
122    ${h.css( "autocomplete_tagging" )}
123    <style type="text/css">
124    #new_history_p{
125        line-height:2.5em;
126        margin:0em 0em .5em 0em;
127    }
128    #new_history_cbx{
129        margin-right:.5em;
130    }
131    #new_history_input{
132        display:none;
133        line-height:1em;
134    }
135    #ec_button_container{
136        float:right;
137    }
138    div.toolForm{
139        margin-top: 10px;
140        margin-bottom: 10px;
141    }
142    div.toolFormTitle{
143        cursor:pointer;
144    }
145    .title_ul_text{
146        text-decoration:underline;
147    }
148    .step-annotation {
149        margin-top: 0.25em;
150        font-weight: normal;
151        font-size: 97%;
152    }
153    .workflow-annotation {
154        margin-bottom: 1em;
155    }
156    </style>
157</%def>
158
159<%
160from galaxy.tools.parameters import DataToolParameter, RuntimeValue
161from galaxy.jobs.actions.post import ActionBox
162import re
163import colorsys
164import random
165
166wf_parms = {}
167for step in steps:
168    for v in [ActionBox.get_short_str(pja) for pja in step.post_job_actions] + step.state.inputs.values():
169        if isinstance(v, basestring):
170            for rematch in re.findall('\$\{.+?\}', v):
171                if rematch[2:-1] not in wf_parms:
172                    wf_parms[rematch[2:-1]] = ""
173if wf_parms:
174    hue_offset = 1.0 / len(wf_parms)
175    hue = 0.0
176    for k in wf_parms.iterkeys():
177        wf_parms[k] = "#%X%X%X" % tuple([int(x * 255) for x in colorsys.hsv_to_rgb(hue, .1, .9)])
178        hue += hue_offset
179%>
180
181<%def name="do_inputs( inputs, values, errors, prefix, step, other_values = None )">
182  %if other_values is None:
183      <% other_values = values %>
184  %endif
185  %for input_index, input in enumerate( inputs.itervalues() ):
186    %if input.type == "repeat":
187      <div class="repeat-group">
188          <div class="form-title-row"><b>${input.title_plural}</b></div>
189          <% repeat_values = values[input.name] %>
190          %for i in range( len( repeat_values ) ):
191            %if input.name in errors:
192                <% rep_errors = errors[input.name][i] %>
193            %else:
194                <% rep_errors = dict() %>
195            %endif
196            <div class="repeat-group-item">
197            <% index = repeat_values[i]['__index__'] %>
198            <div class="form-title-row"><b>${input.title} ${i + 1}</b></div>
199            ${do_inputs( input.inputs, repeat_values[ i ], rep_errors,  prefix + input.name + "_" + str(index) + "|", step, other_values )}
200            ## <div class="form-row"><input type="submit" name="${step.id}|${prefix}${input.name}_${i}_remove" value="Remove ${input.title} ${i+1}" /></div>
201            </div>
202          %endfor
203          ## <div class="form-row"><input type="submit" name="${step.id}|${prefix}${input.name}_add" value="Add new ${input.title}" /></div>
204      </div>
205    %elif input.type == "conditional":
206      <% group_values = values[input.name] %>
207      <% current_case = group_values['__current_case__'] %>
208      <% new_prefix = prefix + input.name + "|" %>
209      <% group_errors = errors.get( input.name, {} ) %>
210      ${row_for_param( input.test_param, group_values[ input.test_param.name ], other_values, group_errors, prefix, step )}
211      ${do_inputs( input.cases[ current_case ].inputs, group_values, group_errors, new_prefix, step, other_values )}
212    %else:
213      ${row_for_param( input, values[ input.name ], other_values, errors, prefix, step )}
214    %endif
215  %endfor
216</%def>
217
218<%def name="row_for_param( param, value, other_values, error_dict, prefix, step )">
219    ## -- ${param.name} -- ${step.state.inputs} --
220    %if error_dict.has_key( param.name ):
221        <% cls = "form-row form-row-error" %>
222    %else:
223        <% cls = "form-row" %>
224    %endif
225    <div class="${cls}">
226        <label>${param.get_label()}</label>
227        <div>
228            %if isinstance( param, DataToolParameter ):
229                %if ( prefix + param.name ) in step.input_connections_by_name:
230                    <%
231                        conn = step.input_connections_by_name[ prefix + param.name ]
232                    %>
233                    Output dataset '${conn.output_name}' from step ${int(conn.output_step.order_index)+1}
234                %else:
235                    ## FIXME: Initialize in the controller
236                    <%
237                    if value is None:
238                        value = other_values[ param.name ] = param.get_initial_value( t, other_values )
239                    %>
240                    ${param.get_html_field( t, value, other_values ).get_html( str(step.id) + "|" + prefix )}
241                    <input type="hidden" name="${step.id}|__force_update__${prefix}${param.name}" value="true" />
242                %endif
243            %elif isinstance( value, RuntimeValue ) or ( str(step.id) + '|__runtime__' + prefix + param.name ) in incoming:
244                ## On the first load we may see a RuntimeValue, so we write
245                ## an input field using the initial value for the param.
246                ## Subsequents posts will no longer have the runtime value
247                ## (since an actualy value will be posted) so we add a hidden
248                ## field so we know to continue drawing form for this param.
249                ## FIXME: This logic shouldn't be in the template. The
250                ## controller should go through the inputs on the first
251                ## load, fill in initial values where needed, and mark
252                ## all that are runtime modifiable in some way.
253                <% value = other_values[ param.name ] = param.get_initial_value( t, other_values ) %>
254                ${param.get_html_field( t, value, other_values ).get_html( str(step.id) + "|" + prefix )}
255                <input type="hidden" name="${step.id}|__runtime__${prefix}${param.name}" value="true" />
256            %else:
257                <%
258                p_text = param.value_to_display_text( value, app )
259                replacements = []
260                if isinstance(p_text, basestring):
261                    for rematch in re.findall('\$\{.+?\}', p_text):
262                        replacements.append('wf_parm__%s' % rematch[2:-1])
263                        p_text = p_text.replace(rematch, '<span style="background-color:%s" class="wfpspan wf_parm__%s">%s</span>' % (wf_parms[rematch[2:-1]], rematch[2:-1], rematch[2:-1]))
264                %>
265                %if replacements:
266                    <span style="display:none" class="parm_wrap ${' '.join(replacements)}">
267                    ${param.get_html_field( t, value, other_values ).get_html( str(step.id) + "|" + prefix )}
268                    </span>
269                    <span class="p_text_wrapper">${p_text}</span>
270                    <input type="hidden" name="${step.id}|__runtime__${prefix}${param.name}" value="true" />
271                %else:
272                    ${param.value_to_display_text( value, app )}
273                %endif
274            %endif
275        </div>
276        %if step.upgrade_messages and param.name in step.upgrade_messages:
277        <div class="warningmark">${step.upgrade_messages[param.name]}</div>
278        %endif
279        %if error_dict.has_key( param.name ):
280        <div style="color: red; font-weight: bold; padding-top: 1px; padding-bottom: 3px;">
281            <div style="width: 300px;"><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}">&nbsp;<span style="vertical-align: middle;">${error_dict[param.name]}</span></div>
282        </div>
283        %endif
284        <div style="clear: both"></div>
285    </div>
286</%def>
287
288<div id='ec_button_container'>
289    <span class="action-button" id="show_all_tool_body">Expand All</span>
290    <span class="action-button" id="hide_all_tool_body">Collapse</span>
291</div>
292
293<h2>Running workflow "${h.to_unicode( workflow.name )}"</h2>
294
295%if has_upgrade_messages:
296<div class="warningmessage">
297    Problems were encountered when loading this workflow, likely due to tool
298    version changes. Missing parameter values have been replaced with default.
299    Please review the parameter values below.
300</div>
301%endif
302
303%if workflow.annotation:
304    <div class="workflow-annotation">${workflow.annotation}</div>
305    <hr/>
306%endif
307
308<form id="tool_form" name="tool_form" method="POST">
309## <input type="hidden" name="workflow_name" value="${h.to_unicode( workflow.name ) | h}" />
310
311
312%if wf_parms:
313<div class="metadataForm">
314    <div class="metadataFormTitle">Workflow Parameters</div>
315    <div class="metadataFormBody">
316    %for parm in wf_parms:
317        <div class='form-row'><label style='width:100px;'>${parm}<input style="border:2px solid ${wf_parms[parm]};border-left-width:8px;" type="text" class='wf_parm_input ptag_${parm}' name="wf_parm|${parm}" value=""/></label></div>
318    %endfor
319    </div>
320</div>
321    <script type="text/javascript">
322    // Set the change hooks for workflow parameters.
323    $(document).ready(function () {
324        $('.wf_parm_input').bind('change keypress keyup', function(event){
325            // DBTODO This is probably not reliable.  Ensure we have the right class.
326            var new_text = $(this).val();
327            if (new_text === ''){
328                var tag_id = $(this).attr("class").split(' ')[1].substring(5);
329                // Set text properly.
330                $('.wfpspan.wf_parm__'+tag_id).text(tag_id);
331            }else{
332                var tag_id = $(this).attr("class").split(' ')[1].substring(5);
333                // Set text properly.
334                $('.wfpspan.wf_parm__'+tag_id).text(new_text);
335                // Now set the hidden input to the generated text.
336                $('.wfpspan.wf_parm__'+tag_id).not('.pja_wfp').each(function(){
337                    var new_text = $(this).parent().text();
338                    $(this).parent().siblings().children().val(new_text);
339                });
340            }
341        });
342    });
343    </script>
344%endif
345
346%for i, step in enumerate( steps ):
347    %if step.type == 'tool' or step.type is None:
348      <% tool = app.toolbox.tools_by_id[step.tool_id] %>
349      <input type="hidden" name="${step.id}|tool_state" value="${step.state.encode( tool, app )}">
350      <div class="toolForm">
351          <div class="toolFormTitle">
352              <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${tool.name}</span>
353              % if step.annotations:
354                <div class="step-annotation">${h.to_unicode( step.annotations[0].annotation )}</div>
355              % endif
356          </div>
357          <div class="toolFormBody">
358            ${do_inputs( tool.inputs, step.state.inputs, errors.get( step.id, dict() ), "", step )}
359            % if step.post_job_actions:
360                <hr/>
361                <div class='form-row'>
362                % if len(step.post_job_actions) > 1:
363                    <label>Actions:</label>
364                % else:
365                    <label>Action:</label>
366                % endif
367                <%
368                pja_ss_all = []
369                for pja_ss in [ActionBox.get_short_str(pja) for pja in step.post_job_actions]:
370                    for rematch in re.findall('\$\{.+?\}', pja_ss):
371                        pja_ss = pja_ss.replace(rematch, '<span style="background-color:%s" class="wfpspan wf_parm__%s pja_wfp">%s</span>' % (wf_parms[rematch[2:-1]], rematch[2:-1], rematch[2:-1]))
372                    pja_ss_all.append(pja_ss)
373                %>
374                ${'<br/>'.join(pja_ss_all)}
375                </div>
376            % endif
377          </div>
378      </div>
379    %else:
380    <% module = step.module %>
381      <input type="hidden" name="${step.id}|tool_state" value="${module.encode_runtime_state( t, step.state )}">
382      <div class="toolForm">
383          <div class="toolFormTitle">
384              <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${module.name}</span>
385              % if step.annotations:
386                <div class="step-annotation">${step.annotations[0].annotation}</div>
387              % endif
388          </div>
389          <div class="toolFormBody">
390              <%
391              # Filter possible inputs to data types that are valid for subsequent steps
392              type_filter = []
393              for oc in step.output_connections:
394                  for ic in oc.input_step.module.get_data_inputs():
395                      if 'extensions' in ic and ic['name'] == oc.input_name:
396                          type_filter += ic['extensions']
397              if not type_filter:
398                  type_filter = ['data']
399              %>
400              ${do_inputs( module.get_runtime_inputs(type_filter), step.state.inputs, errors.get( step.id, dict() ), "", step )}
401          </div>
402      </div>
403    %endif
404%endfor
405%if missing_tools:
406    <div class='errormessage'>
407    <strong>This workflow utilizes tools which are unavailable, and cannot be run.  Enable the tools listed below, or <a href="${h.url_for( action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">edit the workflow</a> to correct these errors.</strong><br/>
408    <ul>
409    %for i, tool in enumerate( missing_tools ):
410        <li>${tool}</li>
411    %endfor
412    </ul>
413%else:
414<p id='new_history_p'>
415    <input type="checkbox" name='new_history' value="true" id='new_history_cbx'/><label for='new_history_cbx'>Send results to a new history </label>
416    <span id="new_history_input">named: <input type='text' name='new_history_name' value='${h.to_unicode( workflow.name )}'/></span>
417</p>
418<input type="submit" name="run_workflow" value="Run workflow" />
419</form>
420%endif