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) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Delete frozen archive' 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) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) flavor = accepted['flavor'][-1] if not flavor in freeze_flavors.keys(): output_objects.append({'object_type': 'error_text', 'text': 'Invalid freeze flavor: %s' % flavor}) return (output_objects, returnvalues.CLIENT_ERROR) title = freeze_flavors[flavor]['deletefreeze_title'] output_objects.append({'object_type': 'header', 'text': title}) title_entry = find_entry(output_objects, 'title') title_entry['text'] = title if not configuration.site_enable_freeze: output_objects.append({'object_type': 'text', 'text': '''Freezing archives is disabled on this site. Please contact the Grid admins %s if you think it should be enabled. ''' % configuration.admin_email}) return (output_objects, returnvalues.OK) freeze_id = accepted['freeze_id'][-1] # NB: the restrictions on freeze_id prevents illegal directory traversal if not is_frozen_archive(freeze_id, configuration): logger.error("%s: invalid freeze '%s': %s" % (op_name, client_id, freeze_id)) output_objects.append({'object_type': 'error_text', 'text': "No such frozen archive: '%s'" % freeze_id}) return (output_objects, returnvalues.CLIENT_ERROR) (load_status, freeze_dict) = get_frozen_archive(freeze_id, configuration) if not load_status: logger.error("%s: load failed for '%s': %s" % \ (op_name, freeze_id, freeze_dict)) output_objects.append( {'object_type': 'error_text', 'text': 'Could not read frozen archive details for %s' % freeze_id}) return (output_objects, returnvalues.SYSTEM_ERROR) # Prevent easy delete if the frozen archive if configuration forbids it if configuration.site_permanent_freeze: output_objects.append( {'object_type': 'error_text', 'text': "Can't delete frozen archive '%s' yourself due to site policy" % freeze_id}) return (output_objects, returnvalues.CLIENT_ERROR) # Make sure the frozen archive belongs to the user trying to delete it if client_id != freeze_dict['CREATOR']: logger.error("%s: illegal access attempt for '%s': %s" % \ (op_name, freeze_id, client_id)) output_objects.append({'object_type': 'error_text', 'text': \ 'You are not the owner of frozen archive "%s"' % freeze_id}) return (output_objects, returnvalues.CLIENT_ERROR) if freeze_dict.get('FLAVOR','freeze') != flavor: logger.error("%s: flavor mismatch for '%s': %s vs %s" % \ (op_name, freeze_id, flavor, freeze_dict)) output_objects.append({'object_type': 'error_text', 'text' : 'No such %s archive "%s"' % (flavor, freeze_id)}) return (output_objects, returnvalues.CLIENT_ERROR) # Delete the frozen archive (status, msg) = delete_frozen_archive(freeze_id, configuration) # If something goes wrong when trying to delete frozen archive # freeze_id, an error is displayed. if not status: logger.error("%s: failed for '%s': %s" % (op_name, freeze_id, msg)) output_objects.append({'object_type': 'error_text', 'text' : 'Could not remove %s frozen archive: %s' % (freeze_id, msg)}) return (output_objects, returnvalues.SYSTEM_ERROR) # If deletion of frozen archive freeze_id is successful, we just # return OK else: logger.info("%s: successful for '%s': %s" % (op_name, freeze_id, client_id)) output_objects.append( {'object_type': 'text', 'text' : 'Successfully deleted frozen archive: "%s"' % freeze_id}) output_objects.append({'object_type': 'link', 'destination': 'freezedb.py', 'class': 'infolink', 'title': 'Show frozen archives', 'text': 'Show frozen archives'}) return (output_objects, returnvalues.OK)
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) defaults = signature()[1] # All non-file fields must be validated validate_args = dict([(key, user_arguments_dict.get(key, val)) for \ (key, val) in defaults.items()]) (validate_status, accepted) = validate_input_and_cert( validate_args, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended use'}) return (output_objects, returnvalues.CLIENT_ERROR) flavor = accepted['flavor'][-1].strip() if not flavor in freeze_flavors.keys(): output_objects.append({'object_type': 'error_text', 'text': 'Invalid freeze flavor: %s' % flavor}) return (output_objects, returnvalues.CLIENT_ERROR) title = freeze_flavors[flavor]['createfreeze_title'] output_objects.append({'object_type': 'header', 'text': title}) title_entry = find_entry(output_objects, 'title') title_entry['text'] = title if not configuration.site_enable_freeze: output_objects.append({'object_type': 'text', 'text': '''Freezing archives is disabled on this site. Please contact the Grid admins %s if you think it should be enabled. ''' % configuration.admin_email}) return (output_objects, returnvalues.OK) freeze_name = accepted['freeze_name'][-1].strip() freeze_description = accepted['freeze_description'][-1].strip() freeze_author = accepted['freeze_author'][-1].strip() freeze_department = accepted['freeze_department'][-1].strip() freeze_organization = accepted['freeze_organization'][-1].strip() freeze_publish = (accepted['freeze_publish'][-1].strip() != 'False') if not freeze_name: output_objects.append({'object_type': 'error_text', 'text': 'You must provide a name for the archive!'}) return (output_objects, returnvalues.CLIENT_ERROR) freeze_meta = {'NAME': freeze_name, 'DESCRIPTION': freeze_description, 'FLAVOR': flavor, 'AUTHOR': freeze_author, 'DEPARTMENT': freeze_department, 'ORGANIZATION': freeze_organization, 'PUBLISH': freeze_publish} if flavor == 'phd' and (not freeze_author or not freeze_department): output_objects.append({'object_type': 'error_text', 'text': 'You must provide author and department for ' 'the thesis!'}) return (output_objects, returnvalues.CLIENT_ERROR) # Now parse and validate files to archive for name in defaults.keys(): if user_arguments_dict.has_key(name): del user_arguments_dict[name] (copy_files, copy_rejected) = parse_form_copy(user_arguments_dict, client_id, configuration) (move_files, move_rejected) = parse_form_move(user_arguments_dict, client_id, configuration) (upload_files, upload_rejected) = parse_form_upload(user_arguments_dict, client_id, configuration) if copy_rejected + move_rejected + upload_rejected: output_objects.append({'object_type': 'error_text', 'text' : 'Errors parsing freeze files: %s' % \ '\n '.join(copy_rejected + move_rejected + \ upload_rejected)}) return (output_objects, returnvalues.CLIENT_ERROR) if not (copy_files + move_files + upload_files): output_objects.append({'object_type': 'error_text', 'text' : 'No files included to freeze!'}) return (output_objects, returnvalues.CLIENT_ERROR) freeze_entries = len(copy_files + move_files + upload_files) if freeze_entries > max_freeze_files: output_objects.append({'object_type': 'error_text', 'text' : 'Too many freeze files (%s), max %s' % (freeze_entries, max_freeze_files)}) return (output_objects, returnvalues.CLIENT_ERROR) (retval, retmsg) = create_frozen_archive(freeze_meta, copy_files, move_files, upload_files, client_id, configuration) if not retval: output_objects.append({'object_type': 'error_text', 'text' : 'Error creating new frozen archive: %s' % retmsg}) return (output_objects, returnvalues.SYSTEM_ERROR) freeze_id = freeze_meta['ID'] = retmsg logger.info("%s: successful for '%s': %s" % (op_name, freeze_id, client_id)) output_objects.append({'object_type': 'text', 'text' : 'Created frozen archive with ID %s successfully!' % freeze_id}) output_objects.append({ 'object_type': 'link', 'destination': 'showfreeze.py?freeze_id=%s;flavor=%s' % (freeze_id, flavor), 'class': 'viewlink', 'title': 'View your frozen archive', 'text': 'View new %s frozen archive' % freeze_id, }) if freeze_publish: public_url = published_url(freeze_meta, configuration) output_objects.append({'object_type': 'text', 'text' : 'The archive is publicly available at:'}) output_objects.append({ 'object_type': 'link', 'destination': public_url, 'class': 'viewlink', 'title': 'View published archive', 'text': public_url, }) return (output_objects, returnvalues.OK)
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) 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) flavor = accepted['flavor'][-1].strip() if not flavor in freeze_flavors.keys(): output_objects.append({'object_type': 'error_text', 'text': 'Invalid freeze flavor: %s' % flavor}) return (output_objects, returnvalues.CLIENT_ERROR) title = freeze_flavors[flavor]['adminfreeze_title'] output_objects.append({'object_type': 'header', 'text': title}) title_entry = find_entry(output_objects, 'title') title_entry['text'] = title if not configuration.site_enable_freeze: output_objects.append({'object_type': 'text', 'text': '''Freezing archives is disabled on this site. Please contact the Grid admins %s if you think it should be enabled. ''' % configuration.admin_email}) return (output_objects, returnvalues.OK) # jquery support for dynamic addition of copy/upload fields title_entry['style'] = themed_styles(configuration, base=['jquery.contextmenu.css', 'jquery.xbreadcrumbs.css', 'jquery.fmbreadcrumbs.css', 'jquery.fileupload.css', 'jquery.fileupload-ui.css'], skin=['fileupload-ui.custom.css', 'xbreadcrumbs.custom.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> <!-- Filemanager and dependencies --> <script type="text/javascript" src="/images/js/jquery.form.js"></script> <script type="text/javascript" src="/images/js/jquery.prettyprint.js"></script> <script type="text/javascript" src="/images/js/jquery.filemanager.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.widgets.js"></script> <script type="text/javascript" src="/images/js/jquery.contextmenu.js"></script> <script type="text/javascript" src="/images/js/jquery.xbreadcrumbs.js"></script> <!-- The preview image plugin --> <script type="text/javascript" src="/images/js/preview.js"></script> <!-- The image manipulation CamanJS plugin used by the preview image plugin --> <script type="text/javascript" src="/images/lib/CamanJS/dist/caman.full.js"></script> <script type="text/javascript"> Caman.DEBUG = false </script> <!-- The nouislider plugin used by the preview image plugin --> <script type="text/javascript" src="/images/lib/noUiSlider/jquery.nouislider.all.js"></script> <!-- Fancy file uploader and dependencies --> <!-- The Templates plugin is included to render the upload/download listings --> <script type="text/javascript" src="/images/js/tmpl.min.js"></script> <!-- The Load Image plugin is included for the preview images and image resizing functionality --> <script type="text/javascript" src="/images/js/load-image.min.js"></script> <!-- Bootstrap JS is not required, but included for the responsive demo navigation --> <!-- The Iframe Transport is required for browsers without support for XHR file uploads --> <script type="text/javascript" src="/images/js/jquery.iframe-transport.js"></script> <!-- The basic File Upload plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload.js"></script> <!-- The File Upload processing plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload-process.js"></script> <!-- The File Upload image preview & resize plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload-image.js"></script> <!-- The File Upload validation plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload-validate.js"></script> <!-- The File Upload user interface plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload-ui.js"></script> <!-- The File Upload jQuery UI plugin --> <script type="text/javascript" src="/images/js/jquery.fileupload-jquery-ui.js"></script> <!-- The template to display files available for upload --> <script id="template-upload" type="text/x-tmpl"> {% console.log("using upload template"); %} {% console.log("... with upload files: "+$.fn.dump(o)); %} {% var dest_dir = "./" + $("#fancyfileuploaddest").val(); %} {% console.log("using upload dest: "+dest_dir); %} {% for (var i=0, file; file=o.files[i]; i++) { %} {% var rel_path = $.fn.normalizePath(dest_dir+"/"+file.name); %} {% console.log("using upload rel_path: "+rel_path); %} <tr class="template-upload fade"> <td> <span class="preview"></span> </td> <td> <p class="name">{%=rel_path%}</p> <strong class="error"></strong> </td> <td> <div class="size pending">Processing...</div> <div class="progress"></div> </td> <td> {% if (!i && !o.options.autoUpload) { %} <button class="start" disabled>Start</button> {% } %} {% if (!i) { %} <button class="cancel">Cancel</button> {% } %} </td> </tr> {% } %} </script> <!-- The template to display files available for download --> <script id="template-download" type="text/x-tmpl"> {% console.log("using download template"); %} {% console.log("... with download files: "+$.fn.dump(o)); %} {% for (var i=0, file; file=o.files[i]; i++) { %} {% var rel_path = $.fn.normalizePath("./"+file.name); %} {% console.log("using download rel_path: "+rel_path); %} <tr class="template-download fade"> <td> <span class="preview"> {% if (file.thumbnailUrl) { %} <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a> {% } %} </span> </td> <td> <p class="name"> <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?\'data-gallery\':\'\'%}>{%=rel_path%}</a> </p> {% if (file.error) { %} <div><span class="error">Error</span> {%=file.error%}</div> {% } %} </td> <td> <div class="size">{%=o.formatFileSize(file.size)%}</div> </td> <td> <button class="delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields=\'{"withCredentials":true}\'{% } %}>{% if (file.deleteUrl) { %}Delete{% } else { %}Dismiss{% } %}</button> <input type="checkbox" name="delete" value="1" class="toggle"> </td> </tr> {% } %} </script> <script type="text/javascript" > var copy_fields = 0; var upload_fields = 0; var open_file_chooser; var open_upload_dialog; ''' title_entry['javascript'] += ''' /* default upload destination */ var remote_path = "%s"; ''' % upload_tmp_dir title_entry['javascript'] += ''' function add_copy(div_id) { var field_id = "freeze_copy_"+copy_fields; var field_name = "freeze_copy_"+copy_fields; var wrap_id = field_id+"_wrap"; var browse_id = field_id+"_browse"; copy_entry = "<span id=\'"+wrap_id+"\'>"; copy_entry += "<input type=\'button\' value=\'Remove\' "; copy_entry += " onClick=\'remove_field(\"+wrap_id+\");\'/>"; // add browse button to mimic upload field copy_entry += "<input type=\'button\' id=\'"+browse_id+"\' "; copy_entry += " value=\'Browse...\' />"; copy_entry += "<input type=\'text\' id=\'"+field_id+"\' "; copy_entry += " name=\'" + field_name + "\' size=80 /><br / >"; copy_entry += "</span>"; $("#"+div_id).append(copy_entry); $("#"+field_id).click(function() { open_file_chooser("Add file or directory (right click to select)", function(file) { $("#"+field_id).val(file); }); }); $("#"+browse_id).click(function() { $("#"+field_id).click(); }); $("#"+field_id).click(); copy_fields += 1; } function add_upload(div_id) { var field_id, field_name, wrap_id, path, on_remove; open_upload_dialog("Upload Files", function() { console.log("in upload callback"); $(".uploadfileslist > tr > td > p.name > a").each( function(index) { console.log("callback for upload item no. "+index); path = $(this).text(); if ($(this).attr("href") == "") { console.log("skipping empty (error) upload: "+path); // Continue to next iteration on errors return true; } console.log("callback for upload path "+path); field_id = "freeze_move_"+upload_fields; field_name = "freeze_move_"+upload_fields; wrap_id = field_id+"_wrap"; if ($("#"+div_id+" > span > input[value=\'"+path+"\']").length) { console.log("skipping duplicate path: "+path); // Continue to next iteration on errors return true; } else { console.log("adding new path: "+path); } on_remove = ""; on_remove += "remove_field("+wrap_id+");"; on_remove += "$.fn.delete_upload(\\""+path+"\\");"; upload_entry = "<span id=\'"+wrap_id+"\'>"; upload_entry += "<input type=\'button\' value=\'Remove\' "; upload_entry += " onClick=\'"+on_remove+"\'/>"; upload_entry += "<input type=\'text\' id=\'"+field_id+"\' "; upload_entry += " name=\'" + field_name + "\' size=50 "; upload_entry += "value=\'"+path+"\' /><br / >"; upload_entry += "</span>"; $("#"+div_id).append(upload_entry); console.log("callback added upload: "+upload_entry); upload_fields += 1; }); console.log("callback done"); }, remote_path, true); } function remove_field(field_id) { $(field_id).remove(); } // init file chooser dialogs with directory selction support function init_dialogs() { open_file_chooser = mig_filechooser_init("fm_filechooser", function(file) { return; }, false, "/"); open_upload_dialog = mig_fancyuploadchunked_init("fancyuploadchunked_dialog"); $("#addfilebutton").click(function() { add_copy(\"copyfiles\"); }); $("#adduploadbutton").click(function() { add_upload(\"uploadfiles\"); }); } function init_page() { init_dialogs(); } $(document).ready(function() { // do sequenced initialisation (separate function) init_page(); } ); </script> ''' shared_files_form = """ <!-- and now this... we do not want to see it, except in a dialog: --> <div id='fm_filechooser' style='display:none'> <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_folders'> <ul class='jqueryFileTree'> <li class='directory expanded'> <a>...</a> </li> </ul> </div> <div class='fm_files'> <table id='fm_filelisting' style='font-size:13px; 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> <!-- 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'> </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> <div id='cmd_dialog' title='Command output' style='display: none;'></div> <div id='fancyuploadchunked_dialog' title='Upload File' style='display: none;'> <!-- 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'> </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> """ if flavor == 'freeze': intro_text = """ Please enter your archive details below and select any files to be included in the archive. <p class='warn_message'>Note that a frozen archive can not be changed after creation and it can only be manually removed by the management, so please be careful when filling in the details. </p> """ files_form = shared_files_form freeze_form = """ <form enctype='multipart/form-data' method='post' action='createfreeze.py'> <b>Name:</b><br /> <input type='hidden' name='flavor' value='freeze' /> <input type='text' name='freeze_name' size=30 autofocus /> <input type='hidden' name='freeze_author' value='UNSET' /> <input type='hidden' name='freeze_department' value='UNSET' /> <input type='hidden' name='freeze_organization' value='UNSET' /> <br /><b>Description:</b><br /> <textarea cols='80' rows='20' name='freeze_description'></textarea> <br /> <br /> <div id='freezefiles'> <b>Freeze Archive Files:</b> <input type='button' id='addfilebutton' value='Add file/directory' /> <input type='button' id='adduploadbutton' value='Add upload' /> <div id='copyfiles'> <!-- Dynamically filled --> </div> <div id='uploadfiles'> <!-- Dynamically filled --> </div> </div> <br /> <div id='freezepublish'> <input type='checkbox' name='freeze_publish' /> <b>Make Dataset Publicly Available</b> </div> <br /> <input type='submit' value='Create Archive' /> </form> """ if flavor == 'phd': intro_text = """ Please enter your PhD details below and select any files associated with your thesis. <p class='warn_message'>Note that a thesis archive can not be changed after creation and it can only be manually removed by the management, so please be careful when filling in the details. </p> """ files_form = shared_files_form freeze_form = """ <form enctype='multipart/form-data' method='post' action='createfreeze.py'> <b>Thesis Title:</b><br /> <input type='hidden' name='flavor' value='phd' /> <input type='hidden' name='freeze_organization' value='UNSET' /> <input type='text' name='freeze_name' size=80 /> <br /><b>Author Name:</b><br /> <input type='text' name='freeze_author' size=40 /> <br /><b>Department:</b><br /> <input type='text' name='freeze_department' size=40 /> <br /> <br /> <div id='freezefiles'> <b>Thesis and Associated Files to Archive:</b> <input type='button' id='addfilebutton' value='Add file/directory' /> <input type='button' id='adduploadbutton' value='Add upload' /> <div id='copyfiles'> <!-- Dynamically filled --> </div> <div id='uploadfiles'> <!-- Dynamically filled --> </div> </div> <br /> <div id='freezepublish'> <input type='checkbox' name='freeze_publish' /> <b>Make Dataset Publicly Available</b> </div> <br /><b>Dataset Description:</b><br /> <textarea cols='80' rows='20' name='freeze_description'></textarea> <br /> <br /> <input type='submit' value='Archive Thesis' /> </form> """ output_objects.append({'object_type': 'html_form', 'text': intro_text}) output_objects.append({'object_type': 'html_form', 'text': files_form}) output_objects.append({'object_type': 'html_form', 'text': freeze_form}) return (output_objects, returnvalues.OK)
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) 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) flavor = accepted["flavor"][-1] if not flavor in freeze_flavors.keys(): output_objects.append({"object_type": "error_text", "text": "Invalid freeze flavor: %s" % flavor}) return (output_objects, returnvalues.CLIENT_ERROR) title = freeze_flavors[flavor]["showfreeze_title"] output_objects.append({"object_type": "header", "text": title}) title_entry = find_entry(output_objects, "title") title_entry["text"] = title if not configuration.site_enable_freeze: output_objects.append( { "object_type": "text", "text": """Freezing archives is disabled on this site. Please contact the Grid admins %s if you think it should be enabled. """ % configuration.admin_email, } ) return (output_objects, returnvalues.OK) # jquery support for tablesorter css_helpers = { "css_base": os.path.join(configuration.site_images, "css"), "skin_base": configuration.site_skin_base, } title_entry["style"] = themed_styles(configuration) title_entry["javascript"] = ( """ <script type="text/javascript" src="/images/js/jquery.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.widgets.js"></script> <script type="text/javascript" src="/images/js/jquery-ui.js"></script> <script type="text/javascript" > $(document).ready(function() { // table initially sorted by col. 0 (filename) var sortOrder = [[0,1]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("#frozenfilestable").tablesorter({widgets: ["zebra", "saveSort"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); } ); </script> """ % default_pager_entries ) freeze_id = accepted["freeze_id"][-1] # NB: the restrictions on freeze_id prevents illegal directory traversal if not is_frozen_archive(freeze_id, configuration): logger.error("%s: invalid freeze '%s': %s" % (op_name, client_id, freeze_id)) output_objects.append( {"object_type": "error_text", "text": "'%s' is not an existing frozen archive!" % freeze_id} ) return (output_objects, returnvalues.CLIENT_ERROR) (load_status, freeze_dict) = get_frozen_archive(freeze_id, configuration) if not load_status: logger.error("%s: load failed for '%s': %s" % (op_name, freeze_id, freeze_dict)) output_objects.append({"object_type": "error_text", "text": 'Could not read details for "%s"' % freeze_id}) return (output_objects, returnvalues.SYSTEM_ERROR) if freeze_dict.get("FLAVOR", "freeze") != flavor: logger.error("%s: flavor mismatch for '%s': %s vs %s" % (op_name, freeze_id, flavor, freeze_dict)) output_objects.append({"object_type": "error_text", "text": 'No such %s archive "%s"' % (flavor, freeze_id)}) return (output_objects, returnvalues.CLIENT_ERROR) output_objects.append( {"object_type": "table_pager", "entry_name": "frozen files", "default_entries": default_pager_entries} ) output_objects.append(build_freezeitem_object(configuration, freeze_dict)) return (output_objects, returnvalues.OK)