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] title_entry = find_entry(output_objects, 'title') title_entry['text'] = "Show freeze" (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) freeze_id = accepted['freeze_id'][-1] flavor = accepted['flavor'][-1] checksum_list = [i for i in accepted['checksum'] if i] operation = accepted['operation'][-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'] title_entry['text'] = title output_objects.append({'object_type': 'header', 'text': title}) sorted_algos = supported_hash_algos() sorted_algos.sort() for checksum in checksum_list: if not checksum in sorted_algos: output_objects.append({ 'object_type': 'error_text', 'text': 'Invalid checksum algo(s): %s' % checksum }) return (output_objects, returnvalues.CLIENT_ERROR) if not configuration.site_enable_freeze: output_objects.append({ 'object_type': 'error_text', 'text': '''Freezing archives is disabled on this site. Please contact the site admins %s if you think it should be enabled. ''' % configuration.admin_email }) return (output_objects, returnvalues.OK) if not operation in allowed_operations: output_objects.append({ 'object_type': 'error_text', 'text': '''Operation must be one of %s.''' % ', '.join(allowed_operations) }) return (output_objects, returnvalues.OK) # We don't generally know checksum and edit status until AJAX returns hide_elems = {'edit': 'hidden', 'update': 'hidden', 'register': 'hidden'} for algo in sorted_algos: hide_elems['%ssum' % algo] = 'hidden' if operation in show_operations: # jquery support for tablesorter and confirmation dialog # table initially sorted by col. 0 (filename) refresh_call = 'ajax_showfreeze("%s", "%s", %s, "%s", "%s", "%s", "%s")' % \ (freeze_id, flavor, checksum_list, keyword_updating, keyword_final, configuration.site_freeze_doi_url, configuration.site_freeze_doi_url_field) table_spec = { 'table_id': 'frozenfilestable', 'sort_order': '[[0,0]]', 'refresh_call': refresh_call } (add_import, add_init, add_ready) = man_base_js(configuration, [table_spec]) if operation == "show": add_ready += '%s;' % refresh_call # Only show requested checksums for algo in sorted_algos: if algo in checksum_list: add_ready += """ $('.%ssum').show(); """ % checksum else: add_ready += """ $('.%ssum').hide(); """ % algo title_entry['script']['advanced'] += add_import title_entry['script']['init'] += add_init title_entry['script']['ready'] += add_ready output_objects.append({ 'object_type': 'html_form', 'text': man_base_html(configuration) }) output_objects.append({ 'object_type': 'table_pager', 'entry_name': 'frozen files', 'default_entries': default_pager_entries, 'refresh_button': False }) # Helper form for removes form_method = 'post' csrf_limit = get_csrf_limit(configuration) target_op = 'deletefreeze' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( 'delfreeze', '%s.py' % target_op, { 'freeze_id': '__DYNAMIC__', 'flavor': '__DYNAMIC__', 'path': '__DYNAMIC__', 'target': TARGET_PATH, csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) # NB: the restrictions on freeze_id prevents illegal directory traversal if not is_frozen_archive(client_id, 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) if operation in list_operations: (load_status, freeze_dict) = get_frozen_archive(client_id, freeze_id, configuration, checksum_list) 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) # Allow edit if not in updating/final state and allow request DOI if # finalized and not a backup archive. freeze_state = freeze_dict.get('STATE', keyword_final) if freeze_state == keyword_updating: hide_elems['update'] = '' elif freeze_state != keyword_final: hide_elems['edit'] = '' elif flavor != 'backup' and configuration.site_freeze_doi_url and \ freeze_dict.get('PUBLISH_URL', ''): hide_elems['register'] = '' logger.debug("%s: build obj for '%s': %s" % (op_name, freeze_id, brief_freeze(freeze_dict))) output_objects.append( build_freezeitem_object(configuration, freeze_dict)) if operation == "show": # insert dummy placeholder to build table output_objects.append({ 'object_type': 'frozenarchive', 'id': freeze_id, 'creator': client_id, 'flavor': flavor, 'frozenfiles': [], 'name': 'loading ...', 'description': 'loading ...', 'created': 'loading ...', 'state': 'loading ...' }) if operation in show_operations: output_objects.append({ 'object_type': 'html_form', 'text': """<p> Show archive with file checksums - might take quite a while to calculate: </p>""" }) for algo in sorted_algos: output_objects.append({'object_type': 'html_form', 'text': '<p>'}) output_objects.append({ 'object_type': 'link', 'destination': "showfreeze.py?freeze_id=%s;flavor=%s;checksum=%s" % (freeze_id, flavor, algo), 'class': 'infolink iconspace genericbutton', 'title': 'View archive with %s checksums' % algo.upper(), 'text': 'Show with %s checksums' % algo.upper() }) output_objects.append({'object_type': 'html_form', 'text': '</p>'}) # We don't know state of archive in this case until AJAX returns # so we hide the section and let AJAX show it if relevant output_objects.append({ 'object_type': 'html_form', 'text': """ <div class='updatearchive %(update)s'> <p class='warn_message'> Archive is currently in the process of being updated. No further changes can be applied until running archive operations are completed. </p> </div> <div class='editarchive %(edit)s'> <p> You can continue inspecting and changing your archive until you're satisfied, then finalize it for actual persistent freezing. </p> <p>""" % hide_elems }) output_objects.append({ 'object_type': 'link', 'destination': "adminfreeze.py?freeze_id=%s;flavor=%s" % (freeze_id, flavor), 'class': 'editarchivelink iconspace genericbutton', 'title': 'Further modify your pending %s archive' % flavor, 'text': 'Edit archive' }) output_objects.append({'object_type': 'html_form', 'text': '</p>'}) form_method = 'post' target_op = 'createfreeze' csrf_limit = get_csrf_limit(configuration) csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( 'createfreeze', '%s.py' % target_op, { 'freeze_id': freeze_id, 'flavor': flavor, 'freeze_state': keyword_final, csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({ 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s');" % ('createfreeze', 'Really finalize %s?' % freeze_id), 'class': 'finalizearchivelink iconspace genericbutton', 'title': 'Finalize %s archive to prevent further changes' % flavor, 'text': 'Finalize archive', }) output_objects.append({ 'object_type': 'html_form', 'text': """ </div> <div class='registerarchive %(register)s'> <p> You can register a <a href='http://www.doi.org/index.html'>Digital Object Identifier (DOI)</a> for finalized archives. This may be useful in case you want to reference the contents in a publication. </p> """ % hide_elems }) form_method = 'post' target_op = 'registerfreeze' csrf_limit = get_csrf_limit(configuration) csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( 'registerfreeze', configuration.site_freeze_doi_url, { 'freeze_id': freeze_id, 'freeze_author': client_id, configuration.site_freeze_doi_url_field: '__DYNAMIC__', 'callback_url': "%s.py" % target_op, csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({ 'object_type': 'html_form', 'text': configuration.site_freeze_doi_text }) output_objects.append({ 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s');" % ('registerfreeze', 'Really request DOI for %s?' % freeze_id), 'class': 'registerarchivelink iconspace genericbutton', 'title': 'Register a DOI for %s archive %s' % (flavor, freeze_id), 'text': 'Request archive DOI', }) output_objects.append({ 'object_type': 'html_form', 'text': """ </div>""" }) output_objects.append({ 'object_type': 'html_form', 'text': """ <div class='vertical-spacer'></div>""" }) 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) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Frozen Archives' # jquery support for tablesorter and confirmation on "leave": 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" src="/images/js/jquery.confirm.js"></script> <script type="text/javascript" > $(document).ready(function() { // init confirmation dialog $( "#confirm_dialog" ).dialog( // see http://jqueryui.com/docs/dialog/ for options { autoOpen: false, modal: true, closeOnEscape: true, width: 500, buttons: { "Cancel": function() { $( "#" + name ).dialog("close"); } } }); // table initially sorted by col. 0 (ID) 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; } $("#frozenarchivetable").tablesorter({widgets: ["zebra", "saveSort"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); } ); </script> ''' % default_pager_entries output_objects.append({'object_type': 'header', 'text' : 'Frozen Archives'}) output_objects.append({'object_type': 'html_form', 'text':''' <div id="confirm_dialog" title="Confirm" style="background:#fff;"> <div id="confirm_text"><!-- filled by js --></div> <textarea cols="40" rows="4" id="confirm_input" style="display:none;"></textarea> </div> ''' }) 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) output_objects.append( {'object_type': 'text', 'text' : '''Frozen archives are write-once collections of files used e.g. in relation to conference paper submissions. Please note that local policies may prevent users from deleting frozen archives without explicit acceptance from the management. '''}) output_objects.append({'object_type': 'sectionheader', 'text' : 'Existing frozen archives'}) (status, ret) = list_frozen_archives(configuration, client_id) if not status: logger.error("%s: failed for '%s': %s" % (op_name, client_id, ret)) output_objects.append({'object_type': 'error_text', 'text' : ret}) return (output_objects, returnvalues.SYSTEM_ERROR) frozenarchives = [] for freeze_id in ret: (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) freeze_item = build_freezeitem_object(configuration, freeze_dict) freeze_id = freeze_item['id'] flavor = freeze_item.get('flavor', 'freeze') freeze_item['viewfreezelink'] = { 'object_type': 'link', 'destination': "showfreeze.py?freeze_id=%s;flavor=%s" % \ (freeze_id, flavor), 'class': 'infolink', 'title': 'View frozen archive %s' % freeze_id, 'text': ''} if client_id == freeze_item['creator']: js_name = 'delete%s' % hexlify(freeze_id) helper = html_post_helper(js_name, 'deletefreeze.py', {'freeze_id': freeze_id, 'flavor': flavor}) output_objects.append({'object_type': 'html_form', 'text': helper}) freeze_item['delfreezelink'] = { 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s');" % \ (js_name, 'Really remove %s?' % freeze_id), 'class': 'removelink', 'title': 'Remove %s' % \ freeze_id, 'text': ''} frozenarchives.append(freeze_item) output_objects.append({'object_type': 'table_pager', 'entry_name': 'frozen archives', 'default_entries': default_pager_entries}) output_objects.append({'object_type': 'frozenarchives', 'frozenarchives': frozenarchives}) output_objects.append({'object_type': 'sectionheader', 'text': 'Additional Frozen Archives'}) output_objects.append({'object_type': 'link', 'destination': 'adminfreeze.py', 'class': 'addlink', 'title': 'Specify a new frozen archive', 'text': 'Create a new frozen archive'}) 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] title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Frozen Archives' (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) operation = accepted['operation'][-1] if not configuration.site_enable_freeze: output_objects.append({ 'object_type': 'text', 'text': '''Freezing archives is disabled on this site. Please contact the site admins %s if you think it should be enabled. ''' % configuration.admin_email }) return (output_objects, returnvalues.OK) if not operation in allowed_operations: output_objects.append({ 'object_type': 'text', 'text': '''Operation must be one of %s.''' % ', '.join(allowed_operations) }) return (output_objects, returnvalues.OK) logger.info("%s %s begin for %s" % (op_name, operation, client_id)) if operation in show_operations: # jquery support for tablesorter and confirmation on delete # table initially sorted by col. 5 (State), 3 (Created date), 2 (name) if client_id in configuration.site_freeze_admins: permanent_flavors = [] else: permanent_flavors = configuration.site_permanent_freeze # NOTE: must insert permanent_flavors list as string here refresh_call = 'ajax_freezedb(%s, "%s")' % (str(permanent_flavors), keyword_final) table_spec = { 'table_id': 'frozenarchivetable', 'sort_order': '[[5,1],[3,1],[2,0]]', 'refresh_call': refresh_call } (add_import, add_init, add_ready) = man_base_js(configuration, [table_spec]) if operation == "show": add_ready += '%s;' % refresh_call title_entry['script']['advanced'] += add_import title_entry['script']['init'] += add_init title_entry['script']['ready'] += add_ready output_objects.append({ 'object_type': 'html_form', 'text': man_base_html(configuration) }) output_objects.append({ 'object_type': 'header', 'text': 'Frozen Archives' }) output_objects.append({ 'object_type': 'text', 'text': '''Frozen archives are write-once collections of files used e.g. in relation to conference paper submissions. Please note that local policies may prevent users from deleting frozen archives without explicit acceptance from the management. ''' }) output_objects.append({ 'object_type': 'sectionheader', 'text': 'Existing frozen archives' }) # Helper form for removes form_method = 'post' csrf_limit = get_csrf_limit(configuration) target_op = 'deletefreeze' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( 'delfreeze', '%s.py' % target_op, { 'freeze_id': '__DYNAMIC__', 'flavor': '__DYNAMIC__', 'target': TARGET_ARCHIVE, csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({ 'object_type': 'table_pager', 'entry_name': 'frozen archives', 'default_entries': default_pager_entries }) frozenarchives = [] if operation in list_operations: # NOTE: we do NOT enforce creator match here as edituser can't update # without breaking any published archives (list_status, ret) = list_frozen_archives(configuration, client_id, strict_owner=False) if not list_status: logger.error("%s: failed for '%s': %s" % (op_name, client_id, ret)) output_objects.append({'object_type': 'error_text', 'text': ret}) return (output_objects, returnvalues.SYSTEM_ERROR) logger.debug("%s %s: building list of archives" % (op_name, operation)) for freeze_id in ret: # TODO: add file count to meta and switch here # (load_status, freeze_dict) = get_frozen_meta(client_id, freeze_id, # configuration) (load_status, freeze_dict) = get_frozen_archive(client_id, freeze_id, configuration, checksum_list=[]) 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) freeze_item = build_freezeitem_object(configuration, freeze_dict, summary=True) freeze_id = freeze_item['id'] flavor = freeze_item.get('flavor', 'freeze') # Users may view all their archives freeze_item['viewfreezelink'] = { 'object_type': 'link', 'destination': "showfreeze.py?freeze_id=%s;flavor=%s" % (freeze_id, flavor), 'class': 'infolink iconspace', 'title': 'View frozen archive %s' % freeze_id, 'text': '' } # Users may edit pending archives if freeze_item['state'] != keyword_final: freeze_item['editfreezelink'] = { 'object_type': 'link', 'destination': "adminfreeze.py?freeze_id=%s" % freeze_id, 'class': 'adminlink iconspace', 'title': 'Edit archive %s' % freeze_id, 'text': '' } # Users may delete pending or non permanent archives. # Freeze admins may delete all their own archives. if freeze_item['state'] != keyword_final or \ flavor not in configuration.site_permanent_freeze or \ client_id in configuration.site_freeze_admins: freeze_item['delfreezelink'] = { 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', %s, %s);" % ('delfreeze', 'Really remove %s?' % freeze_id, 'undefined', "{freeze_id: '%s', flavor: '%s'}" % (freeze_id, flavor)), 'class': 'removelink iconspace', 'title': 'Remove %s' % freeze_id, 'text': '' } frozenarchives.append(freeze_item) logger.debug("%s %s: inserting list of %d archives" % (op_name, operation, len(frozenarchives))) output_objects.append({ 'object_type': 'frozenarchives', 'frozenarchives': frozenarchives }) if operation in show_operations: output_objects.append({ 'object_type': 'sectionheader', 'text': 'Additional Frozen Archives' }) output_objects.append({ 'object_type': 'text', 'text': """ You can create frozen snapshots/archives of particular subsets of your data in order to make sure a verbatim copy is preserved. The freeze archive method includes support for persistent publishing, so that you can e.g. reference your data in publications. Backup archives can be used as a basic backup mechanism, so that you can manually recover from any erroneous file removals.""" }) output_objects.append({ 'object_type': 'html_form', 'text': """<p> Choose one of the archive methods below to make a manual archive: </p> <p>""" }) output_objects.append({ 'object_type': 'link', 'destination': 'adminfreeze.py?flavor=freeze', 'class': 'addlink iconspace', 'title': 'Make a new freeze archive of e.g. ' 'research data to be published', 'text': 'Create a new freeze archive' }) output_objects.append({'object_type': 'html_form', 'text': '</p><p>'}) output_objects.append({ 'object_type': 'link', 'destination': 'adminfreeze.py?flavor=backup', 'class': 'addlink iconspace', 'title': 'Make a new backup archive of %s data' % configuration.short_title, 'text': 'Create a new backup archive' }) output_objects.append({ 'object_type': 'html_form', 'text': "<br/><br/></p>" }) if configuration.site_enable_duplicati: output_objects.append({ 'object_type': 'text', 'text': ''' Alternatively you can use Duplicati for traditional incremental backup/restore with optional encryption of all your backup contents.''' }) output_objects.append({ 'object_type': 'html_form', 'text': """ <p>For further details please refer to the """ }) output_objects.append({ 'object_type': 'link', 'destination': 'setup.py?topic=duplicati', 'class': '', 'title': 'Open Duplicati settings', 'text': 'Duplicati Settings' }) output_objects.append({ 'object_type': 'html_form', 'text': """ and the %s documentation.<br/><br/></p>""" % configuration.short_title }) if configuration.site_enable_seafile: output_objects.append({ 'object_type': 'text', 'text': ''' We recommend our Seafile sync solution for any small or medium sized data sets, for which you want automatic file versioning and easy roll-back support.''' }) output_objects.append({ 'object_type': 'html_form', 'text': """ <p>For further details please refer to the """ }) output_objects.append({ 'object_type': 'link', 'destination': 'setup.py?topic=seafile', 'class': '', 'title': 'Open Seafile settings', 'text': 'Seafile Settings' }) output_objects.append({ 'object_type': 'html_form', 'text': """ and the %s documentation.</p>""" % configuration.short_title }) logger.info("%s %s end for %s" % (op_name, operation, client_id)) 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)