Exemple #1
0
def main(client_id, user_arguments_dict):
    """Main function used by front end"""

    (configuration, logger, output_objects, op_name) = \
            initialize_main_variables(client_id, op_header=False)
    client_dir = client_id_dir(client_id)
    defaults = signature()[1]
    (validate_status, accepted) = validate_input_and_cert(
      user_arguments_dict,
      defaults,
      output_objects,
      client_id,
      configuration,
      allow_rejects=False,
      )
    
    if not validate_status:
        return (accepted, returnvalues.CLIENT_ERROR)
    
    status = returnvalues.OK

    all_paths = accepted['path']
    entry_path = all_paths[-1]
    title_entry = find_entry(output_objects, 'title')
    title_entry['text'] = 'File Manager'
    title_entry['style'] = css_tmpl(configuration)
    if 'submitjob' in extract_menu(configuration, title_entry):
        enable_submit = 'true'
    else:
        enable_submit = 'false'
    title_entry['javascript'] = js_tmpl(entry_path, enable_submit,
                                        str(configuration.site_enable_preview))
    
    output_objects.append({'object_type': 'header', 'text': 'File Manager' })
    output_objects.append({'object_type': 'html_form', 'text':
                           html_tmpl(configuration, title_entry)})

    if len(all_paths) > 1:
        output_objects.append({'object_type': 'sectionheader', 'text':
                               'All requested paths:'})
        for path in all_paths:
            output_objects.append({'object_type': 'link', 'text': path,
                                   'destination': 'fileman.py?path=%s' % path})
            output_objects.append({'object_type': 'text', 'text': ''})

    return (output_objects, status)
Exemple #2
0
def html_tmpl(configuration, title_entry):
    """HTML page base: some upload and menu entries depend on configuration"""

    edit_includes = ['switcher']
    fill_entries = {}
    if 'submitjob' in extract_menu(configuration, title_entry):
        fill_entries["upload_submit_entry"] = '''
            <label for="submitmrsl_0">Submit mRSL files (also .mRSL files included in packages):</label>
            <input id="submitmrsl_0" type="checkbox" checked="" name="submitmrsl_0"/>
            '''
        edit_includes.append('submit')
    else:
        fill_entries["upload_submit_entry"] = '''
            <input id="submitmrsl_0" type="hidden" value="0" name="submitmrsl_0"/>
        '''
    html = '''
    <div id="fm_debug"></div>
    <div id="fm_filemanager">
        <div class="fm_path_breadcrumbs">
            <ul id="fm_xbreadcrumbs" class="xbreadcrumbs">
            </ul>
        </div>
        <div class="fm_addressbar">
            <input type="hidden" value="/" name="fm_current_path" />
        </div>
        <div class="fm_previews">       
            <input type="hidden" value="" name="fm_preview_base_path" />
            <input type="hidden" value="" name="fm_preview_path" />
            <input type="hidden" value="" name="fm_preview_filename" />
            <input type="hidden" value="" name="fm_preview_extension" />
            <div id="fm_preview_menubar" class="fm_preview_menubar">
                <div id="fm_preview_menubar_refresh" class="fm_preview_menubar_entry" title="Refresh Preview">
                    <img src="/images/icons/arrow_refresh.png">
                </div>
                <div id="fm_preview_menubar_zoom_in" class="fm_preview_menubar_entry" title="Zoom In">
                    <img src="/images/icons/add.png">
                </div>
                <div id="fm_preview_menubar_zoom_out" class="fm_preview_menubar_entry" title="Zoom Out">
                    <img src="/images/icons/delete.png">
                </div>                  
            </div>
            <div id="fm_preview_left_tile" class="fm_preview_left_tile">
                <div id="fm_preview_left_tile_histogram">
                    <canvas id="fm_preview_histogram_image"></canvas>
                </div>
                <div id="fm_preview_left_tile_histogram_actions">
                    <input type="hidden" value="" name="fm_preview_histogram_scale" />
                    <input type="hidden" value="" name="fm_preview_histogram_scale" />
                    <div id="fm_preview_histogram_min_max_slider"></div>   
                    <br>
                    <button id="preview_histogram_reset_button" title="Reset sliders">Reset</button>
                    <button id="preview_histogram_set_cutoff_button" title="Set preview cutoff based on sliders">Set Cutoff</button>
                    <!-- <button id="preview_histogram_auto_button">Auto</button> -->
                </div>
                <div id="fm_preview_left_output">
                <!-- this is a placeholder for contents: do not remove! -->
                </div>
            </div>
            <div id="fm_preview_center_tile" class="fm_preview_center_tile">
                <canvas id="fm_preview_image"></canvas>
            </div>
            <div id="fm_preview_right_tile" class="fm_preview_right_tile"> 
                <div id="fm_preview_right_output">
                <!-- this is a placeholder for contents: do not remove! -->
                </div>
            </div>
        </div>

        <div class="fm_folders">
            <ul class="jqueryFileTree">
                <li class="directory expanded">
                    <a href="#">...</a>
                </li>
            </ul>
        </div>
        
        <div class="fm_files">
        
            <table id="fm_filelisting" style="border-spacing=0;" >
            <thead>
                <tr>
                    <th>Name</th>
                    <th style="width: 80px;">Size</th>
                    <th style="width: 50px;">Type</th>
                    <th style="width: 120px;">Date Modified</th>
                </tr>
            </thead>
            <tbody id=fm_filelistbody>
            <!-- this is a placeholder for contents: do not remove! -->
            </tbody>
            </table>
        
        </div>                
        <div id="fm_statusbar">
            <div id="fm_statusprogress"><div class="progress-label">Loading...</div></div>
            <div id="fm_statusinfo">&nbsp;</div>
        </div>
    </div>
    <div id="fm_options"><input id="fm_touchscreen" type="checkbox">
        Enable touch screen interface (all clicks trigger menu)
        <input id="fm_dotfiles" type="checkbox">
        Show hidden files and dirs
    </div>
    
    <div id="cmd_dialog" title="Command output" style="display: none;"></div>

    <div id="upload_dialog" title="Upload File" style="display: none;">

      <div id="upload_tabs">
        <ul>
              <li><a href="#fancyuploadtab">Fancy Upload</a></li>
              <li><a href="#legacyuploadtab">Legacy Upload</a></li>
        </ul>
        <div id="fancyuploadtab">
            <!-- The file upload form used as target for the file upload widget -->
            <form id="fancyfileupload" action="uploadchunked.py?output_format=json;action=put"
                method="POST" enctype="multipart/form-data">
                <fieldset id="fancyfileuploaddestbox">
                    <label id="fancyfileuploaddestlabel" for="fancyfileuploaddest">
                        Optional final destination dir:
                    </label>
                    <input id="fancyfileuploaddest" type="text" size=60 value="">
                </fieldset>
    
                <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
                <div class="fileupload-buttonbar">
                    <div class="fileupload-buttons">
                        <!-- The fileinput-button span is used to style the file input field as button -->
                        <span class="fileinput-button">
                            <span>Add files...</span>
                            <input type="file" name="files[]" multiple>
                        </span>
                        <button type="submit" class="start">Start upload</button>
                        <button type="reset" class="cancel">Cancel upload</button>
                        <button type="button" class="delete">Delete</button>
                        <input type="checkbox" class="toggle">
                        <!-- The global file processing state -->
                        <span class="fileupload-process"></span>
                    </div>
                    <!-- The global progress state -->
                    <div class="fileupload-progress fade" style="display:none">
                        <!-- The global progress bar -->
                        <div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
                        <!-- The extended global progress state -->
                        <div class="progress-extended">&nbsp;</div>
                    </div>
                </div>
                <!-- The table listing the files available for upload/download -->
                <table role="presentation" class="table table-striped"><tbody class="uploadfileslist">
                </tbody></table>
            </form>
            <!-- For status and error output messages -->
            <div id="fancyuploadchunked_output"></div>
        </div>
        <div id="legacyuploadtab">
            <form id="upload_form" enctype="multipart/form-data" method="post" action="textarea.py">
                <fieldset>
                    <input type="hidden" name="output_format" value="json"/>
                    <input type="hidden" name="max_file_size" value="100000"/>

                    %(upload_submit_entry)s
                    <br />
            
                    <label for="remotefilename_0">Optional remote filename (extra useful in windows):</label>
                    <input id="remotefilename_0" type="text" value="./" size="50" name="remotefilename_0" />
                    <br />
            
                    <label for="extract_0">Extract package files (.zip, .tar.gz, .tar.bz2)</label>
                    <input id="extract_0" type="checkbox" name="extract_0"/>
                    <br />
            
                    <label for="fileupload_0_0_0">File:</label>
                    <input id="fileupload_0_0_0" type="file" name="fileupload_0_0_0"/>
                    <input type="submit" value="Upload" onClick="$(\'#upload_output\').html(\'<div><span class=\\\'iconspace info spinner\\\'>uploading ... please wait</span></div>\')" />
                </fieldset>
            </form>
            <div id="upload_output"></div>
        </div>
      </div>
    </div>
    
    <div id="mkdir_dialog" title="Create New Folder" style="display: none;">
    
        <form id="mkdir_form" method="post" action="mkdir.py">
        <fieldset>
            <input type="hidden" name="output_format" value="json" />
            <input type="hidden" name="current_dir" value="./" />
            <label for="path">Enter the new name:</label>
            <input id="path" type="text" name="path"/>            
        </fieldset>
        </form>
        <div id="mkdir_output"></div>
    </div>
    
    <div id="rename_dialog" title="Rename" style="display: none;">
    <form id="rename_form" method="post" action="mv.py">
    <fieldset>    
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="r" />
        <input type="hidden" name="src" value="" />
        <input type="hidden" name="dst" value="" />
        
        <label for="name">Enter the new name:</label>
        <input id="name" type="text" name="name" value="" />
    </fieldset>
    </form>
    <div id="rename_output"></div>
    </div>

    <div id="pack_dialog" title="Pack" style="display: none;">
    <form id="pack_form" method="post" action="pack.py">
    <fieldset>
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="src" value="" />
        <input type="hidden" name="current_dir" value="" />
        
        <label for="dst">Enter the archive file name:</label>
        <input id="dst" type="text" name="dst" size=50  value="" />
        <p>The provided file extension decides the archive type.
        Use .e.g. .zip for a zip archive or .tgz for compressed tarball.
        </p>
    </fieldset>
    </form>
    <div id="pack_output"></div>
    </div>

    <div id="grep_dialog" title="Text search in file" style="display: none;">
    
        <form id="grep_form" method="post" action="grep.py">
        <fieldset>
            <input type="hidden" name="output_format" value="json" />
            <p>
            <label for="path">Path to search:</label>
            <input id="path" type="text" name="path"/>
            </p>
            <p>
            <label for="pattern">Search word or pattern:</label>
            <input id="pattern" type="text" name="pattern"/>
            </p>
        </fieldset>
        </form>
        <div id="grep_output"></div>
    </div>
    
    <div id="imagesettings_dialog" title="Image Settings" style="display: none;">
    <form id="imagesettings_form" method="post" action="filemetaio.py">
    <fieldset>
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="action" value="" />
        <input type="hidden" name="path" value="" />
        <input type="hidden" name="settings_status" value="" />
        <div id="imagesettings_list" class="fm_metaio_list"></div>
        <div id="imagesettings_edit">
            <label for="extension">Image extension:</label>
            <br>
            <input type="text" name="extension" value="" />
            <br>
            <label for="setting_recursive">Apply to sub-folders:</label>
            <br>
            <input type="checkbox" name="settings_recursive" value="False" />
            <br>
            <label for="image_type">Image type:</label>
            <br>
            <select name="image_type">
                <option value="raw">Raw</option>
                <option value="tiff">Tiff</option>
            </select>
            <br>
            <div id="imagesettings_edit_image_type_raw">
                <label for="data_type">Image data type:</label>
                <br>
                <select name="data_type">
                    <option value="float32">float32</option>
                    <option value="float64">float64</option>
                    <option value="uint8">uint8</option>
                    <option value="uint16">uint16</option>
                    <option value="uint32">uint32</option>
                    <option value="uint64">uint64</option>
                    <option value="int8">int8</option>
                    <option value="int16">int16</option>
                    <option value="int32">int32</option>
                    <option value="int64">int64</option>
                </select>
                <br>
                <label for="offset">Image offset:</label>
                <br>
                <input type="text" name="offset" value="" />
                <br>
                <label for="x_dimension">Image width:</label>
                <br>
                <input type="text" name="x_dimension" value="" />
                <br>
                <label for="y_dimension">Image height:</label>
                <br>
                <input type="text" name="y_dimension" value="" />
                <br>
            </div>
            <label for="preview_cutoff_min">Preview image cutoff min value:</label>
            <br>
            <input type="text" name="preview_cutoff_min" value="" />
            <br>
            <label for="preview_cutoff_max">Preview image cutoff max value:</label>
            <br>
            <input type="text" name="preview_cutoff_max" value="" />
        </div>    
    </fieldset>
    </form>                
    <div id="imagesettings_output"></div>
    </div>
    ''' % fill_entries
    html += '''
    <div id="editor_dialog" title="Editor" style="display: none;">
    <div class="iconspace spinner"></div>
    %s
''' % edit_file('', '', output_format='json', includes=edit_includes)
    html += '''
    <div id="editor_output"></div>
    </div>
    '''
    return html
Exemple #3
0
def main(client_id, user_arguments_dict):
    """Main function used by front end"""

    (configuration, logger, output_objects, op_name) = \
        initialize_main_variables(client_id, op_header=False)
    client_dir = client_id_dir(client_id)
    defaults = signature()[1]
    (validate_status, accepted) = validate_input_and_cert(
        user_arguments_dict,
        defaults,
        output_objects,
        client_id,
        configuration,
        allow_rejects=False,
        )
    if not validate_status:
        return (accepted, returnvalues.CLIENT_ERROR)

    # Please note that base_dir must end in slash to avoid access to other
    # user dirs when own name is a prefix of another user name

    base_dir = os.path.abspath(os.path.join(configuration.user_home,
                               client_dir)) + os.sep

    title_entry = find_entry(output_objects, 'title')
    title_entry['text'] = 'Settings'
    
    # prepare support for toggling the views (by css/jquery)

    title_entry['style'] = themed_styles(configuration)
    title_entry['style']['skin'] += '''
%s
''' % cm_css
    title_entry['javascript'] = '''
<script type="text/javascript" src="/images/js/jquery.js"></script>
<script type="text/javascript" src="/images/js/jquery-ui.js"></script>

%s

<script type="text/javascript" >

    var toggleHidden = function(classname) {
        // classname supposed to have a leading dot 
        $(classname).toggleClass("hidden");
    }

$(document).ready(function() {
     }
);
</script>
''' % cm_javascript

    valid_topics = ['general', 'style']
    active_menu = extract_menu(configuration, title_entry)
    if 'submitjob' in active_menu:
        valid_topics.append('job')
    if 'people' in active_menu:
        valid_topics.append('profile')
    if configuration.site_script_deps:
        valid_topics.append('widgets')
    if configuration.arc_clusters:
        valid_topics.append('arc')
    if configuration.site_enable_sftp:
        valid_topics.append('sftp')
    if configuration.site_enable_davs:
        valid_topics.append('webdavs')
    if configuration.site_enable_ftps:
        valid_topics.append('ftps')
    topics = accepted['topic']
    # Backwards compatibility
    if topics and topics[0] == 'ssh':
        topics[0] = 'sftp'
    topics = [i for i in topics if i in valid_topics]
    # Default to general if no valid topics given
    if not topics:
        topics.append(valid_topics[0])
    topic_titles = dict([(i, i.title()) for i in valid_topics])
    for (key, val) in [('sftp', 'SFTP'), ('webdavs', 'WebDAVS'),
                       ('ftps', 'FTPS')]:
        if key in valid_topics:
            topic_titles[key] = val
    output_objects.append({'object_type': 'header', 'text'
                          : 'Settings'})

    links = []
    for name in valid_topics:
        active_menu = ''
        if topics[0]  == name:
            active_menu = 'activebutton'
        links.append({'object_type': 'link', 
                      'destination': "settings.py?topic=%s" % name,
                      'class': '%ssettingslink settingsbutton %s' % \
                      (name, active_menu),
                      'title': 'Switch to %s settings' % topic_titles[name],
                      'text' : '%s' % topic_titles[name],
                      })

    output_objects.append({'object_type': 'multilinkline', 'links': links,
                           'sep': '  '})
    output_objects.append({'object_type': 'text', 'text': ''})

    # load current settings

    current_settings_dict = load_settings(client_id, configuration)
    if not current_settings_dict:

        # no current settings found

        current_settings_dict = {}

    if not topics:
        output_objects.append({'object_type': 'error_text', 'text':
                               'No valid topics!'})
        return (output_objects, returnvalues.CLIENT_ERROR)

    if 'general' in topics:
        html = \
             '''
        <div id="settings">
        <form method="post" action="settingsaction.py">
        <table class="settings fixedlayout">
        <tr class="title"><td class="centertext">
        Select your %s settings
        </td></tr>
        <tr><td>
        </td></tr>
        <tr><td>
        <input type="hidden" name="topic" value="general" />
        Please note that if you want to set multiple values (e.g. addresses)
        in the same field, you must write each value on a separate line but
        without blank lines.
        </td></tr>
        <tr><td>
        </td></tr>
        ''' % configuration.short_title
        settings_entries = get_settings_specs()
        for (keyword, val) in settings_entries:
            if 'SUBMITUI' == keyword and \
                   'job' not in valid_topics:
                continue
            if 'notify' == val['Context'] and \
                   keyword.lower() not in configuration.notify_protocols:
                continue
            entry = \
                """
            <tr class='title'><td>
            %s
            </td></tr>
            <tr><td>
            %s
            </td></tr>
            <tr><td>
            """\
                 % (keyword.replace('_', ' ').title(), val['Description'])
            if val['Type'] == 'multiplestrings':
                try:

                    # get valid choices from conf. multiple selections

                    valid_choices = eval('configuration.%s' % keyword.lower())
                    current_choice = []
                    if current_settings_dict.has_key(keyword):
                        current_choice = current_settings_dict[keyword]

                    if len(valid_choices) > 0:
                        entry += '<div class="scrollselect">'
                        for choice in valid_choices:
                            selected = ''
                            if choice in current_choice:
                                selected = 'checked'
                            entry += '''
                <input type="checkbox" name="%s" %s value="%s">%s<br />''' % \
                            (keyword, selected, choice, choice)
                        entry += '</div>'
                    else:
                        entry = ''
                except:
                    # failed on evaluating configuration.%s

                    area = '''
                <textarea id="%s" cols=40 rows=1 name="%s">''' % \
                    (keyword, keyword)
                    if current_settings_dict.has_key(keyword):
                        area += '\n'.join(current_settings_dict[keyword])
                    area += '</textarea>'
                    entry += wrap_edit_area(keyword, area, general_edit,
                                            'BASIC')

            elif val['Type'] == 'string':

                # get valid choices from conf

                valid_choices = eval('configuration.%s' % keyword.lower())
                current_choice = ''
                if current_settings_dict.has_key(keyword):
                    current_choice = current_settings_dict[keyword]

                if len(valid_choices) > 0:
                    entry += '<select name="%s">' % keyword
                    for choice in valid_choices:
                        selected = ''
                        if choice == current_choice:
                            selected = 'selected'
                        entry += '<option %s value="%s">%s</option>'\
                             % (selected, choice, choice)
                    entry += '</select><br />'
                else:
                    entry = ''
            elif val['Type'] == 'boolean':
                current_choice = ''
                if current_settings_dict.has_key(keyword):
                    current_choice = current_settings_dict[keyword]
                entry += '<select name="%s">' % keyword
                for choice in (True, False):
                    selected = ''
                    if choice == current_choice:
                        selected = 'selected'
                    entry += '<option %s value="%s">%s</option>'\
                             % (selected, choice, choice)
                entry += '</select><br />'
            html += """%s
            </td></tr>
            """ % entry

        html += \
            """
        <tr><td>
        <input type="submit" value="Save General Settings" />
        </td></tr>
        </table>
        </form>
        </div>
        """
        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'job' in topics:
        mrsl_path = os.path.join(base_dir, default_mrsl_filename)

        default_mrsl = get_default_mrsl(mrsl_path)
        html = \
        '''
<div id="defaultmrsl">
<form method="post" action="editfile.py">
<table class="defaultjob fixedlayout">
<tr class="title"><td class="centertext">
Default job on submit page
</td></tr>
<tr><td>
</td></tr>
<tr><td>
If you use the same fields and values in many of your jobs, you can save your
preferred job description here to always start out with that description on
your submit job page.
</td></tr>
<tr><td>
</td></tr>
<tr><td>
<input type="hidden" name="path" value="%(mrsl_template)s" />
<input type="hidden" name="newline" value="unix" />
'''
        keyword = "defaultjob"
        area = '''
<textarea id="%(keyword)s" cols=82 rows=25 name="editarea">
%(default_mrsl)s
</textarea>
'''
        html += wrap_edit_area(keyword, area, cm_options, 'BASIC')
        
        html += '''
</td></tr>
<tr><td>
<input type="submit" value="Save Job Template" />
</td></tr>
</table>
</form>
</div>
'''
        html = html % {
            'default_mrsl': default_mrsl,
            'mrsl_template': default_mrsl_filename,
            'site': configuration.short_title,
            'keyword': keyword
            }

        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'style' in topics:
        css_path = os.path.join(base_dir, default_css_filename)
        default_css = get_default_css(css_path)
        html = \
             '''
<div id="defaultcss">
<form method="post" action="editfile.py">
<table class="defaultstyle fixedlayout">
<tr class="title"><td class="centertext">
Default CSS (style) for all pages
</td></tr>
<tr><td>
</td></tr>
<tr><td>
If you want to customize the look and feel of the %(site)s web interfaces you
can override default values here. If you leave the style file blank you will
just use the default style.<br />
You can copy paste from the available style file links below if you want to
override specific parts.<br />
<div class="warningtext">Please note that you can not save an empty style
file, but must at least leave a blank line to use defaults. Additionally some
errors in your style code may potentially cause severe corruption in your page
layouts, so it may be a good idea to keep another browser tab/window ready to
(re)move your .default.css file to restore the defaults while experimenting
here.
</div>
</td></tr>
<tr><td>
<a class="urllink" href="/images/default.css">default</a> ,
<a class="urllink" href="/images/bluesky.css">bluesky</a>
</td></tr>
<tr><td>
</td></tr>
<tr><td>
<input type="hidden" name="path" value="%(css_template)s" />
<input type="hidden" name="newline" value="unix" />
'''
        keyword = "defaultstyle"
        area = '''
<textarea id="%(keyword)s" cols=82 rows=25 min_len=1 name="editarea">
%(default_css)s
</textarea>
'''
        html += wrap_edit_area(keyword, area, style_edit)
        html += '''
</td></tr>
<tr><td>
<input type="submit" value="Save Style Settings" />
</td></tr>
</table>
</form>
</div>
'''
        html = html % {
            'default_css': default_css,
            'css_template': default_css_filename,
            'site': configuration.short_title,
            'keyword': keyword
            }

        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'widgets' in topics:

        # load current widgets

        current_widgets_dict = load_widgets(client_id, configuration)
        if not current_widgets_dict:
            
            # no current widgets found
            
            current_widgets_dict = {}

        show_widgets = current_settings_dict.get('ENABLE_WIDGETS', True)
        if show_widgets:
            edit_widgets = '''You can simply copy/paste from the available
widget file links below if you want to reuse existing widgets.<br />
</td></tr>
<tr><td>
<a class="urllink" href="/images/widgets/hello-grid.app">hello grid</a>,
<a class="urllink" href="/images/widgets/simple-calendar.app">simple calendar</a>,
<a class="urllink" href="/images/widgets/calendar.app">calendar</a>,
<a class="urllink" href="/images/widgets/gcal.app">google calendar</a>,
<a class="urllink" href="/images/widgets/calculator.app">calculator</a>,
<a class="urllink" href="/images/widgets/localrss.app">local rss reader</a>,
<a class="urllink" href="/images/widgets/rss.app">rss reader</a>,
<a class="urllink" href="/images/widgets/clock.app">clock</a>,
<a class="urllink" href="/images/widgets/weather.app">weather</a>,
<a class="urllink" href="/images/widgets/progressbar.app">progress bar</a>,
<a class="urllink" href="/images/widgets/simple-move.app">simple-move</a>,
<a class="urllink" href="/images/widgets/portlets.app">portlets</a>,
<a class="urllink" href="/images/widgets/countdown.app">countdown</a>,
<a class="urllink" href="/images/widgets/sparkline.app">mini chart</a>,
<a class="urllink" href="/images/widgets/piechart.app">pie chart</a>,
<a class="urllink" href="/images/widgets/simple-jobmon.app">simple-jobmon</a>,
<a class="urllink" href="/images/widgets/cert-countdown.app">certificate countdown</a>,
<a class="urllink" href="/images/widgets/disk-use.app">disk use progress bar</a>,
<a class="urllink" href="/images/widgets/jobs-stats.app">jobs stats table</a>,
<a class="urllink" href="/images/widgets/jobs-stats-chart.app">jobs stats chart</a>,
<a class="urllink" href="/images/widgets/daily-wm-comic.app">Daily WulffMorgenthaler comic</a>,
<a class="urllink" href="/images/widgets/kunet-login.app">KUnet login</a>
<a class="urllink" href="/images/widgets/tdchotspot-login.app">TDC Hotspot login</a>
</td></tr>
<tr><td>
<div class="warningtext">Please note that the widgets parser is rather grumpy
so you may have to avoid blank lines in your widget code below. Additionally
any errors in your widgets code may cause severe corruption in your pages, so
it may be a good idea to keep another browser tab/window ready for emergency
disabling of widgets while experimenting here.</div> 
</td></tr>
<tr><td>
<input type="hidden" name="topic" value="widgets" />
</td></tr>
<tr><td>
'''
            
        html = \
             '''<div id="widgets">
<form method="post" action="settingsaction.py">
<table class="widgets fixedlayout">
<tr class="title"><td class="centertext">
Default user defined widgets for all pages
</td></tr>
<tr><td>
</td></tr>
<tr><td>
If you want to customize the look and feel of the %s web interfaces you can
add your own widgets here. If you leave the widgets blank you will just get
the default empty widget spaces.<br />
''' % configuration.short_title

        widgets_entries = get_widgets_specs()
        widgets_html = ''
        for (keyword, val) in widgets_entries:
            widgets_html += \
                """
            <tr class=title><td>
            %s
            </td></tr>
            <tr><td>
            %s
            </td></tr>
            <tr><td>
            """\
                 % (keyword.replace('_', ' ').title(), val['Description'])
            if val['Type'] == 'multiplestrings':
                try:

                    # get valid choices from conf. multiple selections

                    valid_choices = eval('configuration.%s' % keyword.lower())
                    current_choice = []
                    if current_widgets_dict.has_key(keyword):
                        current_choice = current_widgets_dict[keyword]

                    if len(valid_choices) > 0:
                        widgets_html += '<div class="scrollselect">'
                        for choice in valid_choices:
                            selected = ''
                            if choice in current_choice:
                                selected = 'checked'
                            widgets_html += '''
                    <input type="checkbox" name="%s" %s value="%s">%s<br />'''\
                            % (keyword, selected, choice, choice)
                        widgets_html += '</div>'
                except:
                    area = \
                         """<textarea id='%s' cols=78 rows=10 name='%s'>""" % \
                         (keyword, keyword)
                    if current_widgets_dict.has_key(keyword):
                        area += '\n'.join(current_widgets_dict[keyword])
                    area += '</textarea>'
                    widgets_html += wrap_edit_area(keyword, area, widgets_edit)

        if show_widgets:
            edit_widgets += '''
        %s
        <tr><td>
        <input type="submit" value="Save Widgets Settings" />
</td></tr>
''' % widgets_html
        else:
            edit_widgets = '''
<br/>
<div class="warningtext">
Widgets are disabled on your <em>General</em> settings page. Please enable
them there first if you want to customize your grid pages.
</div>
'''            
        html += \
             '''
%s
</table>
</form>
</div>
''' % edit_widgets
        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'profile' in topics:

        # load current profile

        current_profile_dict = load_profile(client_id, configuration)
        if not current_profile_dict:
            
            # no current profile found
            
            current_profile_dict = {}

        (got_list, all_vgrids) = vgrid_list_vgrids(configuration)
        if not got_list:
            all_vgrids = []
        all_vgrids.append(any_vgrid)
        all_vgrids.sort()
        configuration.vgrids_allow_email = all_vgrids
        configuration.vgrids_allow_im = all_vgrids
        images = []
        for path in os.listdir(base_dir):
            real_path = os.path.join(base_dir, path)
            if os.path.splitext(path)[1].strip('.') in profile_img_extensions \
                   and os.path.getsize(real_path) < profile_img_max_kb*1024:
                images.append(path)
        configuration.public_image = images
        html = \
             '''
<div id="profile">
<form method="post" action="settingsaction.py">
<table class="profile fixedlayout">
<tr class="title"><td class="centertext">
Public profile information visible to other users.
</td></tr>
<tr><td>
</td></tr>
<tr><td>
If you want to let other users know more about you can add your own text here.
If you leave the text area blank you will just get the default empty profile
information.<br />
</td></tr>
<tr><td>
<div class="warningtext">Please note that the profile parser is rather grumpy
so you may have to avoid blank lines in your text below.
</div> 
</td></tr>
<tr><td>
<input type="hidden" name="topic" value="profile" />
</td></tr>
<tr><td>
'''

        profile_entries = get_profile_specs()
        for (keyword, val) in profile_entries:
            # Mask VGrid name if configured
            mask_title = keyword.replace(
                'VGRID', configuration.site_vgrid_label.upper())
            mask_desc = val['Description'].replace(
                'VGrid', configuration.site_vgrid_label)
            html += \
                """
            <tr class=title><td>
            %s
            </td></tr>
            <tr><td>
            %s
            </td></tr>
            <tr><td>
            """ % (mask_title.replace('_', ' ').title(),
                   html_escape(mask_desc))
            if val['Type'] == 'multiplestrings':
                try:

                    # get valid choices from conf. multiple selections

                    valid_choices = eval('configuration.%s' % keyword.lower())
                    current_choice = []
                    if current_profile_dict.has_key(keyword):
                        current_choice = current_profile_dict[keyword]

                    if len(valid_choices) > 0:
                        html += '<div class="scrollselect">'
                        for choice in valid_choices:
                            selected = ''
                            if choice in current_choice:
                                selected = 'checked'
                            html += '''
                <input type="checkbox" name="%s" %s value="%s">%s<br />''' % \
                            (keyword, selected, choice, choice)
                        html += '</div>'
                except:
                    area = \
                         """<textarea id='%s' cols=78 rows=10 name='%s'>""" % \
                         (keyword, keyword)
                    if current_profile_dict.has_key(keyword):
                        area += '\n'.join(current_profile_dict[keyword])
                    area += '</textarea>'
                    html += wrap_edit_area(keyword, area, profile_edit)
            elif val['Type'] == 'boolean':
                valid_choices = [True, False]
                current_choice = ''
                if current_profile_dict.has_key(keyword):
                    current_choice = current_profile_dict[keyword]

                if len(valid_choices) > 0:
                    html += '<select name="%s">' % keyword
                    for choice in valid_choices:
                        selected = ''
                        if choice == current_choice:
                            selected = 'selected'
                        html += '<option %s value="%s">%s</option>'\
                             % (selected, choice, choice)
                    html += '</select><br />'

        html += '''
        <tr><td>
        <input type="submit" value="Save Profile Settings" />
</td></tr>
</table>
</form>
</div>
'''
        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'sftp' in topics:

        # load current ssh/sftp

        current_ssh_dict = load_ssh(client_id, configuration)
        if not current_ssh_dict:
            
            # no current ssh found
            
            current_ssh_dict = {}

        default_authkeys = current_ssh_dict.get('authkeys', '')
        default_authpassword = current_ssh_dict.get('authpassword', '')
        username = client_alias(client_id)
        if configuration.user_sftp_alias:
            username = extract_field(client_id, configuration.user_sftp_alias)
            create_alias_link(username, client_id, configuration.user_home)
        sftp_server = configuration.user_sftp_show_address
        sftp_port = configuration.user_sftp_show_port
        html = \
        '''
<div id="sshaccess">
<form method="post" action="settingsaction.py">
<table class="sshsettings fixedlayout">
<tr class="title"><td class="centertext">
SFTP access to your %(site)s account
</td></tr>
<tr><td>
</td></tr>
<tr><td>
You can configure SFTP login to your %(site)s account for efficient file
access. On Linux/UN*X it also allows transparent access through SSHFS.
<br/>
<h3>Login Details</h3>
<ul>
<li>Host <em>%(sftp_server)s</em></li>
<li>Port <em>%(sftp_port)s</em></li>
<li>Username <em>%(username)s</em></li>
<li>%(auth_methods)s <em>as you choose below</em></li>
</ul>
</td></tr>
<tr><td>
<input type="hidden" name="topic" value="sftp" />
<div class="div-sftp-client-notes hidden">
<a href="javascript:toggleHidden('.div-sftp-client-notes');"
    class="removeitemlink" title="Toggle view">
    Show less SFTP client details...</a>
<h3>Graphical SFTP access</h3>
The FireFTP plugin for Firefox is known to generally work for graphical
access to your %(site)s home over SFTP.
Enter the following values in the FireFTP Account Manager:
<pre>
Host %(sftp_server)s
Login %(username)s
Password YOUR_PASSWORD_HERE (passphrase if you configured public key access)
Security SFTP
Port %(sftp_port)s
Private Key ~/.mig/key.pem (if you configured public key access)
</pre>
other graphical clients may work as well.
<h3>Command line SFTP/SSHFS access on Linux/UN*X</h3>
Save something like the following lines in your local ~/.ssh/config
to avoid typing the full login details every time:<br />
<pre>
Host %(sftp_server)s
Hostname %(sftp_server)s
User %(username)s
Port %(sftp_port)s
IdentityFile ~/.mig/key.pem
</pre>
From then on you can use sftp and sshfs to access your %(site)s home:
<pre>
sftp %(sftp_server)s
</pre>
<pre>
sshfs %(sftp_server)s: mig-home -o uid=$(id -u) -o gid=$(id -g)
</pre>
You can also integrate with ordinary mounts by adding a line like:
<pre>
sshfs#%(username)s@%(sftp_server)s: /home/USER/mig-home fuse noauto,user,port=%(sftp_port)d 0 0
</pre>
to your /etc/fstab .
</div>
<div class="div-sftp-client-notes">
<a href="javascript:toggleHidden('.div-sftp-client-notes');"
    class="additemlink" title="Toggle view">Show more SFTP client details...
    </a>
</div>
'''
        
        keyword_keys = "authkeys"
        if 'publickey' in configuration.user_sftp_auth:
            html += '''
</td></tr>
<tr><td>
<h3>Authorized Public Keys</h3>
You can use any existing RSA key, or create a new one. If you signed up with a
x509 user certificate, you should also have received such a key.pem along with
your user certificate. In any case you need to save the contents of the
corresponding public key (X.pub) in the text area below, to be able to connect
with username and key as described in the Login Details.
<br/>
'''
            area = '''
<textarea id="%(keyword_keys)s" cols=82 rows=5 name="publickeys">
%(default_authkeys)s
</textarea>
'''
            html += wrap_edit_area(keyword_keys, area, ssh_edit, 'BASIC')
            html += '''
(leave empty to disable sftp access with public keys)
</td></tr>
'''
            
        keyword_password = "******"
        if 'password' in configuration.user_sftp_auth:

            # We only want a single password and a masked input field
            html += '''
<tr><td>
<h3>Authorized Password</h3>
Please enter and save your desired password in the text field below, to be able
to connect with username and password as described in the Login Details.
<br/>
<input type=password id="%(keyword_password)s" size=40 name="password"
value="%(default_authpassword)s" />
(leave empty to disable sftp access with password)
</td></tr>
'''
        
        html += '''
<tr><td>
<input type="submit" value="Save SFTP Settings" />
</td></tr>
'''
        
        html += '''
</table>
</form>
</div>
'''
        html = html % {
            'default_authkeys': default_authkeys,
            'default_authpassword': default_authpassword,
            'site': configuration.short_title,
            'keyword_keys': keyword_keys,
            'keyword_password': keyword_password,
            'username': username,
            'sftp_server': sftp_server,
            'sftp_port': sftp_port,
            'auth_methods': ' / '.join(configuration.user_sftp_auth).title(),
            }

        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'webdavs' in topics:

        # load current davs

        current_davs_dict = load_davs(client_id, configuration)
        if not current_davs_dict:
            
            # no current davs found
            
            current_davs_dict = {}

        default_authkeys = current_davs_dict.get('authkeys', '')
        default_authpassword = current_davs_dict.get('authpassword', '')
        username = client_alias(client_id)
        if configuration.user_davs_alias:
            username = extract_field(client_id, configuration.user_davs_alias)
            create_alias_link(username, client_id, configuration.user_home)
        davs_server = configuration.user_davs_show_address
        davs_port = configuration.user_davs_show_port
        html = \
        '''
<div id="davsaccess">
<form method="post" action="settingsaction.py">
<table class="davssettings fixedlayout">
<tr class="title"><td class="centertext">
WebDAVS access to your %(site)s account
</td></tr>
<tr><td>

</td></tr>
<tr><td>
You can configure WebDAVS login to your %(site)s account for transparent file
access from your PC or workstation.<br/>
<h3>Login Details</h3>
<ul>
<li>Host <em>%(davs_server)s</em></li>
<li>Port <em>%(davs_port)s</em></li>
<li>Username <em>%(username)s</em></li>
<li>%(auth_methods)s <em>as you choose below</em></li>
</ul>
</td></tr>
<tr><td>
<input type="hidden" name="topic" value="webdavs" />
<div class="div-webdavs-client-notes hidden">
<a href="javascript:toggleHidden('.div-webdavs-client-notes');"
    class="removeitemlink" title="Toggle view">
    Show less WebDAVS client details...</a>
<h3>Graphical WebDAVS access</h3>
Several native file browsers and web browsers are known to generally work for
graphical access to your %(site)s home over WebDAVS.
<br />
Enter the address https://%(davs_server)s:%(davs_port)s and when fill in the
login details:
<pre>
Username %(username)s
Password YOUR_PASSWORD_HERE
</pre>
other graphical clients should work as well.
<h3>Command line WebDAVS access on Linux/UN*X</h3>
Save something like the following lines in your local ~/.netrc
to avoid typing the full login details every time:<br />
<pre>
machine %(davs_server)s
login %(username)s
password YOUR_PASSWORD_HERE
</pre>
From then on you can use e.g. cadaver or fusedav to access your %(site)s home:
<pre>
cadaver https://%(davs_server)s:%(davs_port)s
</pre>
<pre>
fusedav https://%(davs_server)s:%(davs_port)s mig-home -o uid=$(id -u) -o gid=$(id -g)
</pre>
</div>
<div class="div-webdavs-client-notes">
<a href="javascript:toggleHidden('.div-webdavs-client-notes');"
    class="additemlink" title="Toggle view">
    Show more WebDAVS client details...</a>
</div>
'''
        
        keyword_keys = "authkeys"
        if 'publickey' in configuration.user_davs_auth:
            html += '''
</td></tr>
<tr><td>
<h3>Authorized Public Keys</h3>
You can use any existing RSA key, including the key.pem you received along with
your user certificate, or create a new one. In any case you need to save the
contents of the corresponding public key (X.pub) in the text area below, to be
able to connect with username and key as described in the Login Details.
<br/>'''
            area = '''
<textarea id="%(keyword_keys)s" cols=82 rows=5 name="publickeys">
%(default_authkeys)s
</textarea>
'''
            html += wrap_edit_area(keyword_keys, area, davs_edit, 'BASIC')
            html += '''
(leave empty to disable davs access with public keys)
</td></tr>
'''
            
        keyword_password = "******"
        if 'password' in configuration.user_davs_auth:
            # We only want a single password and a masked input field
            html += '''
<tr><td>
<h3>Authorized Password</h3>
Please enter and save your desired password in the text field below, to be able
to connect with username and password as described in the Login Details.
<br/>
<input type=password id="%(keyword_password)s" size=40 name="password"
value="%(default_authpassword)s" />
(leave empty to disable davs access with password)
</td></tr>
'''
        
        html += '''
<tr><td>
<input type="submit" value="Save WebDAVS Settings" />
</td></tr>
'''
        
        html += '''
</table>
</form>
</div>
'''
        html = html % {
            'default_authkeys': default_authkeys,
            'default_authpassword': default_authpassword,
            'site': configuration.short_title,
            'keyword_keys': keyword_keys,
            'keyword_password': keyword_password,
            'username': username,
            'davs_server': davs_server,
            'davs_port': davs_port,
            'auth_methods': ' / '.join(configuration.user_davs_auth).title(),
            }

        output_objects.append({'object_type': 'html_form', 'text': html})

    if 'ftps' in topics:

        # load current ftps

        current_ftps_dict = load_ftps(client_id, configuration)
        if not current_ftps_dict:
            
            # no current ftps found
            
            current_ftps_dict = {}

        default_authkeys = current_ftps_dict.get('authkeys', '')
        default_authpassword = current_ftps_dict.get('authpassword', '')
        username = client_alias(client_id)
        if configuration.user_ftps_alias:
            username = extract_field(client_id, configuration.user_ftps_alias)
            create_alias_link(username, client_id, configuration.user_home)
        ftps_server = configuration.user_ftps_show_address
        ftps_ctrl_port = configuration.user_ftps_show_ctrl_port
        html = \
        '''
<div id="ftpsaccess">
<form method="post" action="settingsaction.py">
<table class="ftpssettings fixedlayout">
<tr class="title"><td class="centertext">
FTPS access to your %(site)s account
</td></tr>
<tr><td>
</td></tr>
<tr><td>
You can configure FTPS login to your %(site)s account for efficient file
access.<br/>
<h3>Login Details</h3>
<ul>
<li>Host <em>%(ftps_server)s</em></li>
<li>Port <em>%(ftps_ctrl_port)s</em></li>
<li>Username <em>%(username)s</em></li>
<li>%(auth_methods)s <em>as you choose below</em></li>
</ul>
</td></tr>
<tr><td>
<input type="hidden" name="topic" value="ftps" />
<div class="div-ftps-client-notes hidden">
<a href="javascript:toggleHidden('.div-ftps-client-notes');"
    class="removeitemlink" title="Toggle view">
    Show less FTPS client details...</a>
<h3>Graphical FTPS access</h3>
The FireFTP plugin for Firefox is known to generally work for graphical
access to your %(site)s home over FTPS.
Enter the following values in the FireFTP Account Manager:
<pre>
Host %(ftps_server)s
Login %(username)s
Password YOUR_PASSWORD_HERE
Security FTPS
Port %(ftps_ctrl_port)s
</pre>
Other FTP clients and web browsers may work as well if you enter the address
ftps://%(ftps_server)s:%(ftps_ctrl_port)s
and fill in the login details when prompted:
<pre>
Username %(username)s
Password YOUR_PASSWORD_HERE
</pre>
<h3>Command line FTPS access on Linux/UN*X</h3>
Save something like the following lines in your local ~/.netrc
to avoid typing the full login details every time:<br />
<pre>
machine %(ftps_server)s
login %(username)s
password YOUR_PASSWORD_HERE
</pre>
From then on you can use e.g. lftp or CurlFtpFS to access your %(site)s home:
<!--
TODO: we need to provide the intermediate cert for server cert check like this
set ssl:ca-file sub.class1.server.ca.pem
-->
<pre>
lftp -e "set ssl:verify-certificate no; set ftp:ssl-protect-data on" \\
     -p %(ftps_ctrl_port)s %(ftps_server)s
</pre>
<pre>
curlftpfs -o ssl %(ftps_server)s:%(ftps_ctrl_port)s mig-home \\
          -o user=%(username)s -ouid=$(id -u) -o gid=$(id -g) -o no_verify_peer
</pre>
</div>
<div class="div-ftps-client-notes">
<a href="javascript:toggleHidden('.div-ftps-client-notes');"
    class="additemlink" title="Toggle view">Show more FTPS client details...
</a>
</div>
'''
        
        keyword_keys = "authkeys"
        if 'publickey' in configuration.user_ftps_auth:
            html += '''
</td></tr>
<tr><td>
<h3>Authorized Public Keys</h3>
You can use any existing RSA key, including the key.pem you received along with
your user certificate, or create a new one. In any case you need to save the
contents of the corresponding public key (X.pub) in the text area below, to be
able to connect with username and key as described in the Login Details.
<br/>
'''
            area = '''
<textarea id="%(keyword_keys)s" cols=82 rows=5 name="publickeys">
%(default_authkeys)s
</textarea>
'''
            html += wrap_edit_area(keyword_keys, area, ftps_edit, 'BASIC')
            html += '''
(leave empty to disable ftps access with public keys)
</td></tr>
'''
            
        keyword_password = "******"
        if 'password' in configuration.user_ftps_auth:

            # We only want a single password and a masked input field
            html += '''
<tr><td>
<h3>Authorized Password</h3>
Please enter and save your desired password in the text field below, to be able
to connect with username and password as described in the Login Details.
<br/>
<input type=password id="%(keyword_password)s" size=40 name="password"
value="%(default_authpassword)s" />
(leave empty to disable ftps access with password)
</td></tr>
'''
        
        html += '''
<tr><td>
<input type="submit" value="Save FTPS Settings" />
</td></tr>
'''
        
        html += '''
</table>
</form>
</div>
'''
        html = html % {
            'default_authkeys': default_authkeys,
            'default_authpassword': default_authpassword,
            'site': configuration.short_title,
            'keyword_keys': keyword_keys,
            'keyword_password': keyword_password,
            'username': username,
            'ftps_server': ftps_server,
            'ftps_ctrl_port': ftps_ctrl_port,
            'auth_methods': ' / '.join(configuration.user_ftps_auth).title(),
            }

        output_objects.append({'object_type': 'html_form', 'text': html})

    # if ARC-enabled server:
    if 'arc' in topics:
        # provide information about the available proxy, offer upload
        try:
            home_dir = os.path.normpath(base_dir)
            session_Ui = arc.Ui(home_dir, require_user_proxy=True)
            proxy = session_Ui.getProxy()
            if proxy.IsExpired():
                # can rarely happen, constructor will throw exception
                output_objects.append({'object_type': 'text', 
                                       'text': 'Proxy certificate is expired.'})
            else:
                output_objects.append({'object_type': 'text', 
                                       'text': 'Proxy for %s' \
                                       % proxy.GetIdentitySN()})
                output_objects.append(
                    {'object_type': 'text', 
                     'text': 'Proxy certificate will expire on %s (in %s sec.)'
                     % (proxy.Expires(), proxy.getTimeleft())
                     })
        except arc.NoProxyError, err:
            output_objects.append({'object_type':'warning',
                                   'text': 'No proxy certificate to load: %s' \
                                   % err.what()})
    
        output_objects = output_objects + arc.askProxy()
Exemple #4
0
def html_tmpl(configuration, client_id, title_entry, csrf_map={}, chroot=''):
    """HTML page base: some upload and menu entries depend on configuration"""

    active_menu = extract_menu(configuration, title_entry)
    user_settings = title_entry.get('user_settings', {})
    legacy_ui = legacy_user_interface(configuration, user_settings)
    fill_helpers = {'short_title': configuration.short_title}
    html = '''
    <!-- CONTENT -->

			<div class="container">
				<div id="app-nav-container" class="row">
                                <h1>Welcome to %(short_title)s!</h1>
					<div class="home-page__header col-12">
						<p class="sub-title">Tools from %(short_title)s helps you with storage, sharing and archiving of data. %(short_title)s delivers centralised storage space for personal and shared files.</p>
					</div>
            ''' % fill_helpers
    html += render_apps(configuration, title_entry, active_menu)
    html += '''
                                <div class="col-lg-12 vertical-spacer"></div>
				</div>
			</div>

    '''

    # Dynamic app selection
    form_method = 'post'
    csrf_limit = get_csrf_limit(configuration)
    target_op = 'settingsaction'
    csrf_token = make_csrf_token(configuration, form_method, target_op,
                                 client_id, csrf_limit)
    settings_specs = get_keywords_dict()
    current_settings_dict = load_settings(client_id, configuration)
    if not current_settings_dict:

        # no current settings found

        current_settings_dict = {}
    fill_helpers['form_prefix'] = '''
    <form class="save_settings save_apps" action="settingsaction.py" method="%s">
        <input type="hidden" name="%s" value="%s">
    ''' % (form_method, csrf_field, csrf_token)
    fill_helpers['form_suffix'] = '''
            %s
            <input type="submit" value="Save">
        </form>
    ''' % save_settings_html(configuration)
    apps_field = 'SITE_USER_MENU'
    # NOTE: build list of all default and user selectable apps in that order
    app_list = [app_id for app_id in configuration.site_default_menu]
    app_list += [
        app_id for app_id in configuration.site_user_menu
        if not app_id in app_list
    ]

    mandatory_apps = []
    for app_name in configuration.site_default_menu:
        mandatory_apps.append(menu_items[app_name]['title'])
    fill_helpers['mandatory_apps'] = ', '.join(mandatory_apps)
    html += '''
<!-- APP POP-UP -->
		<div id="add-app__window" class="app-container hidden">
			<span class="add-app__close far fa-times-circle" onclick="closeAddApp()"></span>
			<div class="container">
				<div class="row">
					<div class="app-page__header col-12">
						<h1>Your apps & app-setup</h1>
                        <p class="sub-title-white">Here you can select which apps you want to use in your %(short_title)s system. Only %(mandatory_apps)s are mandatory.</p>
					</div>
					<div class="app-page__header col-12">
						<h2>Select your apps</h2>
                                                %(form_prefix)s
    ''' % fill_helpers
    # The backend form requires all user settings even if we only want to edit
    # the user apps subset here - just fill as hidden values.
    # TODO: consider a save version with only relevant values.
    for (key, val) in current_settings_dict.items():
        if key == apps_field:
            continue
        spec = settings_specs[key]
        if spec['Type'] == 'multiplestrings':
            html += '''        <textarea class="hidden" name="%s">%s</textarea>
            ''' % (key, '\n'.join(val))

        elif spec['Type'] == 'string':
            html += '''        <input type="hidden" name="%s" value="%s">
            ''' % (key, val)
        elif spec['Type'] == 'boolean':
            html += '''        <input type="hidden" name="%s" value="%s">
            ''' % (key, val)

    html += '''						<div class="app-grid row">
    '''
    for app_id in app_list:
        app = menu_items[app_id]
        app_name = app['title']
        if not legacy_ui and app.get('legacy_only', False):
            continue
        if app_id == 'vgrids':
            app_name = '%ss' % configuration.site_vgrid_label
        mandatory = (app_id in configuration.site_default_menu)
        app_btn_classes = 'app__btn col-12 '
        if mandatory:
            app_btn_classes += "mandatory"
        else:
            app_btn_classes += "optional"
        app_icon_classes = app['class']
        check_field = ''
        if not mandatory:
            checked, checkmark = "", "checkmark"
            if app_id in current_settings_dict.get(apps_field, []):
                checked = "checked='checked'"
                checkmark = "checkmark"
            check_field = '''
        <input type="checkbox" name="SITE_USER_MENU" %s value="%s">
        <span class="%s"></span>
            ''' % (checked, app_id, checkmark)
        html += '''
                            <div class="col-lg-2">
			        <div class="%s">
                                    <label class="app-content">
                                    %s
                                    <div class="background-app">
                                        <span class="%s"></span><h3>%s</h3>
                                    </div>
                                    </label>
                                </div>
                            </div>
                ''' % (app_btn_classes, check_field, app_icon_classes,
                       app_name)

    html += '''
						</div>
                                                <br />
                                                %(form_suffix)s
					</div>
				</div>
			</div>
                <div class="col-lg-12 vertical-spacer"></div>
            </div>
                ''' % fill_helpers

    return html
Exemple #5
0
def main(client_id, user_arguments_dict):
    """Main function used by front end"""

    (configuration, logger, output_objects, op_name) = \
        initialize_main_variables(client_id, op_header=False)
    client_dir = client_id_dir(client_id)
    defaults = signature()[1]
    (validate_status, accepted) = validate_input_and_cert(
        user_arguments_dict,
        defaults,
        output_objects,
        client_id,
        configuration,
        allow_rejects=False,
    )

    if not validate_status:
        return (accepted, returnvalues.CLIENT_ERROR)

    status = returnvalues.OK

    chroot = ''
    if configuration.site_enable_gdp:
        chroot = get_project_from_client_id(configuration, client_id)

    all_paths = accepted['path']
    entry_path = all_paths[-1]
    title_entry = find_entry(output_objects, 'title')
    user_settings = title_entry.get('user_settings', {})
    title_entry['text'] = 'File Manager'
    title_entry['style'] = css_tmpl(configuration, user_settings)

    legacy_buttons = False
    if legacy_user_interface(configuration, user_settings):
        legacy_buttons = True
        logger.info("enable legacy buttons")

    if configuration.site_enable_jobs and \
            'submitjob' in extract_menu(configuration, title_entry):
        enable_submit = 'true'
    else:
        enable_submit = 'false'
    csrf_map = {}
    method = 'post'
    limit = get_csrf_limit(configuration)
    for target_op in csrf_backends:
        csrf_map[target_op] = make_csrf_token(configuration, method, target_op,
                                              client_id, limit)
    (add_import, add_init,
     add_ready) = js_tmpl_parts(configuration, entry_path, enable_submit,
                                str(configuration.site_enable_preview),
                                legacy_buttons, csrf_map, chroot)
    title_entry['script']['advanced'] += add_import
    title_entry['script']['init'] += add_init
    title_entry['script']['ready'] += add_ready

    output_objects.append({
        'object_type': 'header',
        'class': 'fileman-title',
        'container_class': 'fillwidth',
        'text': 'File Manager'
    })
    output_objects.append({
        'object_type':
        'html_form',
        'text':
        html_tmpl(configuration, client_id, title_entry, csrf_map, chroot)
    })

    if len(all_paths) > 1:
        output_objects.append({
            'object_type': 'sectionheader',
            'text': 'All requested paths:'
        })
        for path in all_paths:
            output_objects.append({
                'object_type': 'link',
                'text': path,
                'destination': 'fileman.py?path=%s' % path
            })
            output_objects.append({'object_type': 'text', 'text': ''})

    return (output_objects, status)
Exemple #6
0
def html_tmpl(configuration, client_id, title_entry, csrf_map={}, chroot=''):
    """HTML page base: some upload and menu entries depend on configuration"""

    edit_includes = ['switcher']
    fill_entries = {
        'vgrid_label': configuration.site_vgrid_label,
        'default_max_chunks': default_max_chunks,
        'chroot': chroot
    }
    fill_entries['create_sharelink_form'] = create_share_link_form(
        configuration, client_id, 'json', '', csrf_map.get('sharelink', ''))
    fill_entries['import_sharelink_form'] = import_share_link_form(
        configuration, client_id, 'json', '', csrf_map.get('cp', ''))
    fill_entries['import_freeze_form'] = import_freeze_form(
        configuration, client_id, 'json', '', csrf_map.get('cp', ''))
    if configuration.site_enable_jobs and \
            'submitjob' in extract_menu(configuration, title_entry):
        fill_entries["upload_submit_entry"] = '''
            <label for="submitmrsl_0">Submit mRSL files (also .mRSL files included in packages):</label>
            <input id="submitmrsl_0" type="checkbox" checked="" name="submitmrsl_0"/>
            '''
        edit_includes.append('submit')
    else:
        fill_entries["upload_submit_entry"] = '''
            <input id="submitmrsl_0" type="hidden" value="0" name="submitmrsl_0"/>
        '''
    # Fill csrf tokens for targets with static form, others are filled in JS
    fill_entries["csrf_field"] = csrf_field
    for (target_op, token) in csrf_map.items():
        fill_entries["%s_csrf_token" % target_op] = token

    # TODO: switch to use shared fancy_upload_html from shared.html!
    html = '''
    <div id="fm_debug"></div>
    <div id="fm_filemanager">
        <div class="tree-container container-fluid">
            <div class="tree-row row">
                <div class="tree-header col-3"></div>
                <div class="fm_path_breadcrumbs col-6">
                    <ul id="fm_xbreadcrumbs" class="xbreadcrumbs"><!-- dynamic --></ul>
                </div>
                <div class="fm_buttonbar col-3 d-none d-lg-block">
                    <ul id="fm_buttons" class="buttonbar">
                    <!-- dynamically modified by js to show optional buttons -->
                    <li class="datatransfersbutton hidden" title="Manage Data Transfers">&nbsp;</li>
                    <li class="sharelinksbutton hidden" title="Manage Share Links">&nbsp;</li>
                    <li class="parentdirbutton" title="Open Parent Directory">&nbsp;</li>
                    <li class="refreshbutton" title="Refresh">&nbsp;</li>
                    </ul>
                </div>
                <div class="fm_buttonbar-big col-6 d-block d-lg-none hidden">
                    <ul id="fm_buttons" class="buttonbar">
                    <!-- dynamically modified by js to show optional buttons -->
                    <li class="datatransfersbutton hidden" title="Manage Data Transfers">&nbsp;</li>
                    <li class="sharelinksbutton hidden" title="Manage Share Links">&nbsp;</li>
                    <li class="parentdirbutton" title="Open Parent Directory">&nbsp;</li>
                    <li class="refreshbutton" title="Refresh">&nbsp;</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="fm_addressbar">
            <input type="hidden" value="/" name="fm_current_path" />
        </div>
        <div id="fm_previews" class="fm_previews">
            <!-- this is a placeholder for contents: do not remove! -->
            <!-- filled by preview.js : init_html -->
        </div>
        <div class="fm_folders col-lg-3">
            <ul class="jqueryFileTree">
                <li class="directory expanded">
                    <a href="#">...</a>
                </li>
            </ul>
        </div>

        <div class="fm_files col-lg-9">
            <table id="fm_filelisting">
                <thead>
                    <tr>
                        <th class="fm_name">Name</th>
                        <th class="fm_size">Size</th>
                        <th class="fm_type">Type</th>
                        <th class="fm_date">Date Modified</th>
                        <th class="fm_toolbox">...</th>
                    </tr>
                </thead>
                <tbody id=fm_filelistbody>
                    <!-- this is a placeholder for contents: do not remove! -->
                </tbody>
            </table>
        </div>

        <div id="fm_statusbar" class="col-lg-12">
            <div id="fm_statusprogress" class=" col-lg-3">
            <div class="progress-label">Loading...</div></div>
            <div id="fm_options" class="col-lg-2">
                <label id="fm_toggle_touchscreen" class="switch" for="fm_touchscreen" >
                <input id="fm_touchscreen" type="checkbox" />
                <span class="slider round" title="all clicks trigger menu"></span>
                </label><span id="fm_touchscreen_label">Touch mode</span>
                <label id="fm_toggle_dotfiles" class="switch">
                <input id="fm_dotfiles" type="checkbox" />
                <span class="slider round" title="Show hidden files and folders"></span>
                </label><span id="fm_dotfiles_label">Hidden files</span>
            </div>
            <div id="fm_statusinfo" class="col-lg-7">&nbsp;</div>
        </div>
    </div>

    <div id="cmd_dialog" title="Command output" style="display: none;"></div>

    <div id="upload_dialog" title="Upload File" style="display: none;">
      <div id="upload_tabs">
        <ul>'''
    if configuration.site_enable_gdp:
        html += '''
            <li><a href="#fancyuploadtab">Upload</a></li>'''
    else:
        html += '''
            <li><a href="#fancyuploadtab">Fancy Upload</a></li>
            <li><a href="#legacyuploadtab">Legacy Upload</a></li>'''
    html += '''
        </ul>
        <div id="fancyuploadtab">
            <!-- The file upload form used as target for the file upload widget -->
            <!-- TODO: this form action and args do not seem to have any effect -->
            <!-- Probably all overriden in our filemanager upload JS -->
            <form id="fancyfileupload" action="uploadchunked.py?output_format=json;action=put"
                method="POST" enctype="multipart/form-data">
                <input type="hidden" name="%(csrf_field)s" value="%(uploadchunked_csrf_token)s" />
                <fieldset id="fancyfileuploaddestbox">
                    <label id="fancyfileuploaddestlabel" for="fancyfileuploaddest">
                        Optional final destination dir:
                    </label>
                    <input id="fancyfileuploaddest" type="text" size=60 value="">
                </fieldset>

                <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
                <div class="fileupload-buttonbar">
                    <div class="fileupload-buttons">
                        <!-- The fileinput-button span is used to style the file input field as button -->
                        <span class="fileinput-button">
                            <span>Add files...</span>
                            <input type="file" name="files[]" multiple>
                        </span>
                        <button type="submit" class="start">Start upload</button>
                        <button type="reset" class="cancel">Cancel upload</button>
                        <button type="button" class="delete">Delete</button>
                        <input type="checkbox" class="toggle">
                        <!-- The global file processing state -->
                        <span class="fileupload-process"><!-- dynamic --></span>
                    </div>
                    <!-- The global progress state -->
                    <div class="fileupload-progress fade">
                        <!-- The global progress bar -->
                        <div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
                        <!-- The extended global progress state -->
                        <div class="progress-extended">&nbsp;</div>
                    </div>
                </div>
                <!-- The table listing the files available for upload/download -->
                <table role="presentation" class="table table-striped fancyuploadfileslist"><tbody class="uploadfileslist">
                <!-- dynamic --></tbody></table>
            </form>
            <!-- For status and error output messages -->
            <div id="fancyuploadchunked_output"><!-- dynamic --></div>
        </div>'''
    if not configuration.site_enable_gdp:
        html += '''
        <div id="legacyuploadtab">
            <form id="upload_form" enctype="multipart/form-data" method="post" action="textarea.py">
                <fieldset>
                    <input type="hidden" name="%(csrf_field)s" value="%(textarea_csrf_token)s" />
                    <input type="hidden" name="output_format" value="json"/>
                    <input type="hidden" name="max_file_size" value="100000"/>

                    %(upload_submit_entry)s
                    <br />

                    <label for="remotefilename_0">Optional remote filename (extra useful in windows):</label>
                    <input id="remotefilename_0" type="text" value="./" size="50" name="remotefilename_0" />
                    <br />

                    <label for="extract_0">Extract package files (.zip, .tar.gz, .tar.bz2)</label>
                    <input id="extract_0" type="checkbox" name="extract_0"/>
                    <br />

                    <label for="fileupload_0_0_0">File:</label>
                    <input id="fileupload_0_0_0" type="file" name="fileupload_0_0_0"/>
                    <input type="submit" value="Upload" onClick="$(\'#upload_output\').html(\'<div><span class=\\\'iconleftpad info spinner\\\'>uploading ... please wait</span></div>\')" />
                </fieldset>
            </form>
            <div id="upload_output"><!-- dynamic --></div>
        </div>'''
    html += '''
      </div>
    </div>
    <div id="mkdir_dialog" title="Create New Folder" style="display: none;">

        <form id="mkdir_form" method="post" action="mkdir.py">
        <fieldset>
            <input type="hidden" name="%(csrf_field)s" value="%(mkdir_csrf_token)s" />
            <input type="hidden" name="output_format" value="json" />
            <input type="hidden" name="current_dir" value="./" />
            <label for="path">Directory name:</label>
            <input id="path" class="singlefield" type="text" name="path" size=50 />
        </fieldset>
        </form>
        <div id="mkdir_output"><!-- dynamic --></div>
    </div>

    <div id="rename_dialog" title="Rename" style="display: none;">
    <form id="rename_form" method="post" action="mv.py">
    <fieldset>
        <input type="hidden" name="%(csrf_field)s" value="%(mv_csrf_token)s" />
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="r" />
        <input type="hidden" name="src" value="" />
        <input type="hidden" name="dst" value="" />

        <label for="name">New name:</label>
        <input id="name" class="singlefield" type="text" name="name" size=50 value="" />
    </fieldset>
    </form>
    <div id="rename_output"><!-- dynamic --></div>
    </div>

    <div id="chksum_dialog" title="Checksum" style="display: none;">
    <!-- NOTE: no explicit form action, only submit through jquery -->
    <form id="chksum_form" action="javascript:void(0);">
    <fieldset>
        <input type="hidden" name="%(csrf_field)s" value="%(pack_csrf_token)s" />
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="hash_algo" value="" />
        <input type="hidden" name="current_dir" value="" />

        <label for="path">Target file name(s):</label>
        <input id="path" class="singlefield" type="text" name="path" size=50  value="" />
        <br/><br/>
        <input type="hidden" name="path" value="" />
        <label for="dst">Output file name:</label>
        <input id="dst" class="singlefield" type="text" name="dst" size=50  value="" />
        <br/><br/>
        <label for="max_chunks">Max chunks:</label>
        <input id="max_chunks" class="singlefield" type="text" name="max_chunks"
            size=8  value="%(default_max_chunks)s" />
    </fieldset>
    <p>
    The optional output file is particularly convenient for checksums on big
    files, where the web browser may time-out before the checksum returns an
    answer.<br />
    Optionally change Max chunks to 0 in order to checksum the entire file. It
    may be slow, though, as the run time is proportional to the chunks checked.
    <br />
    </p>
    </form>
    <div id="chksum_output"><!-- dynamic --></div>
    </div>

    <div id="pack_dialog" title="Pack" style="display: none;">
    <!-- NOTE: no explicit form action, only submit through jquery -->
    <form id="pack_form" action="javascript:void(0);">
    <fieldset>
        <input type="hidden" name="%(csrf_field)s" value="%(pack_csrf_token)s" />
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="src" value="" />
        <input type="hidden" name="current_dir" value="" />

        <label for="dst">Archive file name:</label>
        <input id="dst" class="singlefield" type="text" name="dst" size=50  value="" />
    </fieldset>
    <p>
    The provided file extension decides the archive type.<br />
    Use .e.g. <em>.zip</em> for a zip archive or <em>.tgz</em> for compressed tarball.
    </p>
    </form>
    <div id="pack_output"><!-- dynamic --></div>
    </div>

    <div id="unpack_dialog" title="Unpack" style="display: none;">
    <!-- NOTE: no explicit form action, only submit through jquery -->
    <form id="unpack_form" action="javascript:void(0);">
    <fieldset>
        <input type="hidden" name="%(csrf_field)s" value="%(unpack_csrf_token)s" />
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="src" value="" />

        <label for="dst">Unpack to folder:</label>
        <input id="dst" class="singlefield" type="text" name="dst" size=50  value="" />
    </fieldset>
    </form>
    <div id="unpack_output"><!-- dynamic --></div>
    </div>

    <div id="grep_dialog" title="Text search in file" style="display: none;">

        <form id="grep_form" method="post" action="grep.py">
        <fieldset>
            <input type="hidden" name="output_format" value="json" />
            <label for="path">Path to search:</label>
            <input id="path" class="singlefield" type="text" name="path" size=50 />
            <br />
            <label for="pattern">Search word/pattern:</label>
            <input id="pattern" class="singlefield" type="text" name="pattern" size=50 />
        </fieldset>
        </form>
        <div id="grep_output"><!-- dynamic --></div>
    </div>

    <div id="create_sharelink_dialog" title="Create Share Link"
        style="display: none;">
    %(create_sharelink_form)s
    <div id="create_sharelink_output"><!-- dynamic --></div>
    </div>

    <div id="import_sharelink_dialog" title="Import from Share Link"
        style="display: none;">
    %(import_sharelink_form)s
    <div id="import_sharelink_output"><!-- dynamic --></div>
    </div>

    <div id="import_freeze_dialog" title="Import from archive"
        style="display: none;">
    %(import_freeze_form)s
    <div id="import_freeze_output"><!-- dynamic --></div>
    </div>

    <div id="imagesettings_dialog" title="Image Settings" style="display: none;">
    <fieldset>
    <div id="imagesettings_list" class="fm_metaio_list"></div>
    <div id="imagesettings_edit_tabs">
        <form id="imagesettings_form" method="post" action="imagepreview.py">
        <input type="hidden" name="%(csrf_field)s" value="%(imagepreview_csrf_token)s" />
        <input type="hidden" name="output_format" value="json" />
        <input type="hidden" name="flags" value="" />
        <input type="hidden" name="action" value="" />
        <input type="hidden" name="path" value="" />
        <input type="hidden" name="settings_status" value="" />
        <ul>
            <li><a href="#imagesettings_edit_file_tab">File</a></li>
            <li><a href="#imagesettings_edit_volume_tab">Volume</a></li>
        </ul>
        <div id="imagesettings_edit_file_tab">
            <table class="fm_metaio_edit_table">
            <tr><td>
                <label class="halffield">-- Image --</label>
            </td></tr>
            <tr><td>
                <label class="halffield" for="extension">Extension:</label>
                <input type="text" name="extension" value="" />
            </td></tr>
            <tr><td>
                <label class="halffield" for="setting_recursive">Apply to sub-folders:</label>
                <input type="checkbox" name="settings_recursive" value="False" />
            </td></tr>
            <tr><td>
                <label class="halffield" for="image_type">Type:</label>
                <select name="image_type">
                    <option value="raw">Raw</option>
                    <option value="tiff">Tiff</option>
                </select>
            </td></tr>
            </table>
            <div id="imagesettings_edit_image_type_raw">
                <table class="fm_metaio_edit_table">
                <tr><td>
                    <label class="halffield" for="data_type">Data type:</label>
                    <select name="data_type">
                        <option value="float32">float32</option>
                        <option value="float64">float64</option>
                        <option value="uint8">uint8</option>
                        <option value="uint16">uint16</option>
                        <option value="uint32">uint32</option>
                        <option value="uint64">uint64</option>
                        <option value="int8">int8</option>
                        <option value="int16">int16</option>
                        <option value="int32">int32</option>
                        <option value="int64">int64</option>
                    </select>
                </td></tr>
                <tr><td>
                    <label class="halffield" for="offset">Offset:</label>
                    <input type="text" name="offset" value="" />
                </td></tr>
                <tr><td>
                    <label class="halffield" for="x_dimension">Width:</label>
                    <input type="text" name="x_dimension" value="" />
                </td></tr>
                <tr><td>
                    <label class="halffield" for="y_dimension">Height:</label>
                    <input type="text" name="y_dimension" value="" />
                </td></tr>
                </table>
            </div>
            <table class="fm_metaio_edit_table">
            <tr><td>
            </td></tr>
            <tr><td>
                <label class="halffield" for="dummy">-- Preview --</label>
                <input type="hidden" name="dummy" value="" />
            </td></tr>
            <tr><td>
                <label class="halffield" for="preview_cutoff_min">Cutoff min value:</label>
                <input type="text" name="preview_cutoff_min" value="" />
            </td></tr>
            <tr><td>
                <label class="halffield" for="preview_cutoff_max">Cutoff max value:</label>
                <input type="text" name="preview_cutoff_max" value="" />
            </td></tr>
            </table>
        </div>
        <div id="imagesettings_edit_volume_tab">
            <table class="fm_metaio_edit_table">
            <tr><td>
                <label class="halffield">-- Volume --</label>
            </td></tr>
            <tr><td>
                <label class="halffield" for="volume_slice_filepattern">Slice file pattern:</label>
                <input type="text" name="volume_slice_filepattern" value="" />
            </td></tr>
            <tr><td>
                <label class="halffield" for="z_dimension">Number of slices:</label>
                <input type="text" name="z_dimension" value="" />
            </td></tr>
            </table>
        </div>
        </form>
    </div>
    </fieldset>
    <div id="imagesettings_output"><!-- dynamic --></div>
    </div>
    '''
    html += '''
    <div id="editor_dialog" title="Editor" style="display: none;">
    <div class="iconleftpad spinner"></div>
    %s
''' % edit_file(configuration,
                client_id,
                '',
                '',
                output_format='json',
                includes=edit_includes)
    html += '''
    <div id="editor_output"><!-- dynamic --></div>
    </div>
    '''
    return html % fill_entries