diff --git a/modules/bibedit/lib/bibedit_engine.py b/modules/bibedit/lib/bibedit_engine.py index b73dff247..c398b306c 100644 --- a/modules/bibedit/lib/bibedit_engine.py +++ b/modules/bibedit/lib/bibedit_engine.py @@ -1,390 +1,390 @@ ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. __revision__ = "$Id$" import os import time import cPickle from invenio.config import CFG_BINDIR, CFG_TMPDIR, CFG_BIBEDIT_TIMEOUT from invenio.bibedit_dblayer import marc_to_split_tag from invenio.bibedit_config import * from invenio.search_engine import print_record, record_exists from invenio.bibrecord import record_xml_output, create_record, field_add_subfield, record_add_field import invenio.template -from invenio.bibtask import bibsched_low_level_task_submission +from invenio.bibtask import task_low_level_submission bibedit_templates = invenio.template.load('bibedit') def perform_request_index(ln, recid, cancel, delete, confirm_delete, uid, temp, format_tag, edit_tag, delete_tag, num_field, add, dict_value=None): """Returns the body of main page. """ errors = [] warnings = [] body = '' if cancel != 0: os.system("rm %s.tmp" % get_file_path(cancel)) if delete != 0: if confirm_delete != 0: body = bibedit_templates.tmpl_deleted(ln, 1, delete, temp, format_tag) else: (record, junk) = get_record(ln, delete, uid, "false") add_field(delete, uid, record, "980", "", "", "c", "DELETED") save_temp_record(record, uid, "%s.tmp" % get_file_path(delete)) save_xml_record(delete) body = bibedit_templates.tmpl_deleted(ln) else: if recid != 0 : if record_exists(recid) > 0: (record, body) = get_record(ln, recid, uid, temp) if record != '': if add == 3: body = '' if edit_tag is not None and dict_value is not None: record = edit_record(recid, uid, record, edit_tag, dict_value, num_field) if delete_tag is not None and num_field is not None: record = delete_field(recid, uid, record, delete_tag, num_field) if add == 4: tag = dict_value.get("add_tag" , '') ind1 = dict_value.get("add_ind1" , '') ind2 = dict_value.get("add_ind2" , '') subcode = dict_value.get("add_subcode", '') value = dict_value.get("add_value" , '') if tag != '' and subcode != '' and value != '': record = add_field(recid, uid, record, tag, ind1, ind2, subcode, value) body += bibedit_templates.tmpl_table_header(ln, "record", recid, temp, format_tag, add=add) keys = record.keys() keys.sort() for tag in keys: fields = record.get(str(tag), "empty") if fields != "empty": for field in fields: if field[0]: # Only display if has subfield(s) body += bibedit_templates.tmpl_table_value(ln, recid, tag, field, format_tag, "record", add) if add == 3: body += bibedit_templates.tmpl_table_value(ln, recid, '', [], format_tag, "record", add, 1) body += bibedit_templates.tmpl_table_footer(ln, "record", add) else: body = bibedit_templates.tmpl_record_choice_box(ln, 2) else: if record_exists(recid) == -1: body = bibedit_templates.tmpl_record_choice_box(ln, 3) else: body = bibedit_templates.tmpl_record_choice_box(ln, 1) else: body = bibedit_templates.tmpl_record_choice_box(ln, 0) return (body, errors, warnings) def perform_request_edit(ln, recid, uid, tag, num_field, num_subfield, format_tag, temp, del_subfield, add, dict_value): """Returns the body of edit page. """ errors = [] warnings = [] body = '' if record_exists(recid) in (-1, 0): body = bibedit_templates.tmpl_record_choice_box(ln, 0) return (body, errors, warnings) (record, junk) = get_record(ln, recid, uid, temp) if del_subfield is not None: record = delete_subfield(recid, uid, record, tag, num_field, num_subfield) if add == 2: subcode = dict_value.get("add_subcode", "empty") value = dict_value.get("add_value" , "empty") if subcode == '': subcode = "empty" if value == '': value = "empty" if value != "empty" and subcode != "empty": record = add_subfield(recid, uid, tag, record, num_field, subcode, value) body += bibedit_templates.tmpl_table_header(ln, "edit", recid, temp=temp, tag=tag, num_field=num_field, add=add) tag = tag[:3] fields = record.get(str(tag), "empty") if fields != "empty": for field in fields: if field[4] == int(num_field) : body += bibedit_templates.tmpl_table_value(ln, recid, tag, field, format_tag, "edit", add) break body += bibedit_templates.tmpl_table_footer(ln, "edit", add) return (body, errors, warnings) def perform_request_submit(ln, recid): """Submits record to the database. """ save_xml_record(recid) errors = [] warnings = [] body = bibedit_templates.tmpl_submit(ln) return (body, errors, warnings) def get_file_path(recid): """ return the file path of record. """ return "%s/%s_%s" % (CFG_TMPDIR, CFG_BIBEDIT_TMPFILENAMEPREFIX, str(recid)) def save_xml_record(recid): """Saves XML record file to database. """ file_path = get_file_path(recid) file_temp = open("%s.xml" % file_path, 'w') file_temp.write(record_xml_output(get_temp_record("%s.tmp" % file_path)[1])) file_temp.close() - bibsched_low_level_task_submission('bibupload', 'bibedit', '-r', '%s.xml' % file_path) + task_low_level_submission('bibupload', 'bibedit', '-r', '%s.xml' % file_path) os.system("rm %s.tmp" % file_path) def save_temp_record(record, uid, file_path): """ Save record dict in temp file. """ file_temp = open(file_path, "w") cPickle.dump([uid, record], file_temp) file_temp.close() def get_temp_record(file_path): """Loads record dict from a temp file. """ file_temp = open(file_path) [uid, record] = cPickle.load(file_temp) file_temp.close() return (uid, record) def get_record(ln, recid, uid, temp): """Returns a record dict, and warning message in case of error. """ file_path = get_file_path(recid) if temp != "false": warning_temp_file = bibedit_templates.tmpl_warning_temp_file(ln) else: warning_temp_file = '' if os.path.isfile("%s.tmp" % file_path): (uid_record_temp, record) = get_temp_record("%s.tmp" % file_path) if uid_record_temp != uid: time_tmp_file = os.path.getmtime("%s.tmp" % file_path) time_out_file = int(time.time()) - CFG_BIBEDIT_TIMEOUT if time_tmp_file < time_out_file : os.system("rm %s.tmp" % file_path) record = create_record(print_record(recid, 'xm'))[0] save_temp_record(record, uid, "%s.tmp" % file_path) else: record = '' else: record = create_record(print_record(recid, 'xm'))[0] save_temp_record(record, uid, "%s.tmp" % file_path) return (record, warning_temp_file) ######### EDIT ######### def edit_record(recid, uid, record, edit_tag, dict_value, num_field): """Edits value of a record. """ for num_subfield in range( len(dict_value.keys())/3 ): # Iterate over subfield indices of field new_subcode = dict_value.get("subcode%s" % num_subfield, None) old_subcode = dict_value.get("old_subcode%s" % num_subfield, None) new_value = dict_value.get("value%s" % num_subfield, None) old_value = dict_value.get("old_value%s" % num_subfield, None) if new_value is not None and old_value is not None \ and new_subcode is not None and old_subcode is not None: # Make sure we actually get these values if new_value != '' and new_subcode != '': # Forbid empty values if new_value != old_value or \ new_subcode != old_subcode: # only change when necessary edit_tag = edit_tag[:5] record = edit_subfield(record, edit_tag, new_subcode, new_value, num_field, num_subfield) save_temp_record(record, uid, "%s.tmp" % get_file_path(recid)) return record def edit_subfield(record, tag, new_subcode, new_value, num_field, num_subfield): """Edits the value of a subfield. """ new_value = bibedit_templates.tmpl_clean_value(str(new_value), "html") (tag, ind1, ind2, junk) = marc_to_split_tag(tag) fields = record.get(str(tag), None) if fields is not None: i = -1 for field in fields: i += 1 if field[4] == int(num_field): subfields = field[0] j = -1 for subfield in subfields: j += 1 if j == num_subfield: # Rely on counted index to identify subfield to edit... record[tag][i][0][j] = (new_subcode, new_value) break break return record ######### ADD ######## def add_field(recid, uid, record, tag, ind1, ind2, subcode, value_subfield): """Adds a new field to the record. """ tag = tag[:3] new_field_number = record_add_field(record, tag, ind1, ind2) record = add_subfield(recid, uid, tag, record, new_field_number, subcode, value_subfield) save_temp_record(record, uid, "%s.tmp" % get_file_path(recid)) return record def add_subfield(recid, uid, tag, record, num_field, subcode, value): """Adds a new subfield to a field. """ tag = tag[:3] fields = record.get(str(tag)) i = -1 for field in fields: i += 1 if field[4] == int(num_field) : subfields = field[0] same_subfield = False for subfield in subfields: if subfield[0] == subcode: same_subfield = True if not same_subfield: field_add_subfield(record[tag][i], subcode, value) break save_temp_record(record, uid, "%s.tmp" % get_file_path(recid)) return record ######### DELETE ######## def delete_field(recid, uid, record, tag, num_field): """Deletes field in record. """ (tag, junk, junk, junk) = marc_to_split_tag(tag) tmp = [] for field in record[tag]: if field[4] != int(num_field) : tmp.append(field) if tmp != []: record[tag] = tmp else: del record[tag] save_temp_record(record, uid, "%s.tmp" % get_file_path(recid)) return record def delete_subfield(recid, uid, record, tag, num_field, num_subfield): """Deletes subfield of a field. """ (tag, junk, junk, subcode) = marc_to_split_tag(tag) tmp = [] i = -1 deleted = False for field in record[tag]: i += 1 if field[4] == int(num_field): j = 0 for subfield in field[0]: if j != num_subfield: #if subfield[0] != subcode or deleted == True: tmp.append((subfield[0], subfield[1])) #else: # deleted = True j += 1 break record[tag][i] = (tmp, record[tag][i][1], record[tag][i][2], record[tag][i][3], record[tag][i][4]) save_temp_record(record, uid, "%s.tmp" % get_file_path(recid)) return record diff --git a/modules/bibformat/lib/bibreformat.py b/modules/bibformat/lib/bibreformat.py index 88d468532..d628a47f7 100644 --- a/modules/bibformat/lib/bibreformat.py +++ b/modules/bibformat/lib/bibreformat.py @@ -1,573 +1,573 @@ ## -*- mode: python; coding: utf-8; -*- ## ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """Call BibFormat engine and create HTML brief (and other) formats for bibliographic records. Upload formats via BibUpload.""" __revision__ = "$Id$" import sys try: from invenio.dbquery import run_sql from invenio.config import \ CFG_SITE_URL,\ CFG_TMPDIR,\ CFG_BINDIR from invenio.search_engine import perform_request_search, search_pattern from invenio.search_engine import print_record, encode_for_xml from invenio.bibformat import format_record from invenio.bibformat_utils import encode_for_xml from invenio.bibformat_config import CFG_BIBFORMAT_USE_OLD_BIBFORMAT from invenio.bibtask import task_init, write_message, task_set_option, \ task_get_option, task_update_progress, task_has_option, \ - bibsched_low_level_task_submission + task_low_level_submission import sys import os import time except ImportError, e: print "Error: %s" % e sys.exit(1) sql_queries = [] # holds SQL queries to be executed cds_query = {} # holds CDS query parameters (fields, collection, pattern) process_format = 0 # flag, process records without created format process = 1 # flag, process records (unless count only) fmt = "hb" # default format to be processed ### run the bibreformat task bibsched scheduled ### def bibreformat_task(sql, sql_queries, cds_query, process_format): """ BibReformat main task """ global process, fmt t1 = os.times()[4] ### Query the database ### task_update_progress('Fetching records to process') if process_format: # '-without' parameter write_message("Querying database for records without cache...") without_format = without_fmt(sql) recIDs = [] if cds_query['field'] != "" or \ cds_query['collection'] != "" or \ cds_query['pattern'] != "": write_message("Querying database (CDS query)...") if cds_query['collection'] == "": # use search_pattern() whenever possible, as it can search # even in private collections res = search_pattern(p=cds_query['pattern'], f=cds_query['field'], m=cds_query['matching']).tolist() else: # use perform_request_search when '-c' argument has been # defined, as it is not supported by search_pattern() res = perform_request_search(req=None, of='id', c=cds_query['collection'], p=cds_query['pattern'], f=cds_query['field']) for item in res: recIDs.append(item) for sql_query in sql_queries: write_message("Querying database (SQL query) ...") res = run_sql(sql_query) for item in res: recIDs.append(item[0]) ### list of corresponding record IDs was retrieved ### now format the selected records if process_format: write_message("Records to be processed: %d" % (len(recIDs) \ + len(without_format))) write_message("Out of it records without existing cache: %d" % len(without_format)) else: write_message("Records to be processed: %d" % (len(recIDs))) ### Initialize main loop total_rec = 0 # Total number of records tbibformat = 0 # time taken up by external call tbibupload = 0 # time taken up by external call ### Iterate over all records prepared in lists I (option) if process: if CFG_BIBFORMAT_USE_OLD_BIBFORMAT: # FIXME: remove this # when migration from php to # python bibformat is done (total_rec_1, tbibformat_1, tbibupload_1) = iterate_over_old(recIDs, fmt) else: (total_rec_1, tbibformat_1, tbibupload_1) = iterate_over_new(recIDs, fmt) total_rec += total_rec_1 tbibformat += tbibformat_1 tbibupload += tbibupload_1 ### Iterate over all records prepared in list II (no_format) if process_format and process: if CFG_BIBFORMAT_USE_OLD_BIBFORMAT: # FIXME: remove this # when migration from php to # python bibformat is done (total_rec_2, tbibformat_2, tbibupload_2) = iterate_over_old(without_format, fmt) else: (total_rec_2, tbibformat_2, tbibupload_2) = iterate_over_new(without_format, fmt) total_rec += total_rec_2 tbibformat += tbibformat_2 tbibupload += tbibupload_2 ### Final statistics t2 = os.times()[4] elapsed = t2 - t1 message = "total records processed: %d" % total_rec write_message(message) message = "total processing time: %2f sec" % elapsed write_message(message) message = "Time spent on external call (os.system):" write_message(message) message = " bibformat: %2f sec" % tbibformat write_message(message) message = " bibupload: %2f sec" % tbibupload write_message(message) ### Result set operations ### def lhdiff(l1, l2): "Does list difference via intermediate hash." d = {} ld = [] for e in l2: d[e] = 1 for e in l1: if not d.has_key(e): ld.append(e) return ld ### Result set operations ### def ldiff(l1, l2): "Returns l1 - l2." ld = [] for e in l1: if not e in l2: ld.append(e) return ld ### Identify recIDs of records with missing format ### def without_fmt(sql): "List of record IDs to be reformated, not having the specified format yet" rec_ids_with_cache = [] all_rec_ids = [] q1 = sql['q1'] q2 = sql['q2'] ## get complete recID list all_rec_ids = [x[0] for x in run_sql(q1)] ## get complete recID list of formatted records rec_ids_with_cache = [x[0] for x in run_sql(q2)] return lhdiff(all_rec_ids, rec_ids_with_cache) ### Bibreformat all selected records (using new python bibformat) ### (see iterate_over_old further down) def iterate_over_new(list, fmt): "Iterate over list of IDs" global total_rec n_it_rec = 0 # Number of records for current iteration n_it_max = 10000 # Number of max records in one iteration total_rec = 0 # Number of formatted records formatted_records = '' # (string-)List of formatted record of an iteration tbibformat = 0 # time taken up by external call tbibupload = 0 # time taken up by external call start_date = "1970-01-01 01:01:01" # Time at which the record was formatted for recID in list: total_rec += 1 n_it_rec += 1 task_update_progress('Formatting %s out of %s' %(total_rec, len(list))) message = "Processing record %d with format %s (New BibFormat)" % (recID, fmt) write_message(message, verbose=9) ### bibformat external call ### t1 = os.times()[4] start_date = time.strftime('%Y-%m-%d %H:%M:%S') formatted_record = format_record(recID, fmt, on_the_fly=True) t2 = os.times()[4] tbibformat = tbibformat + (t2 - t1) # Encapsulate record in xml tags that bibupload understands prologue = ''' <record> <controlfield tag="001">%s</controlfield> <datafield tag="FMT" ind1=" " ind2=" "> <subfield code="f">%s</subfield> <subfield code="d">%s</subfield> <subfield code="g">''' % (recID, fmt, start_date) epilogue = ''' </subfield> </datafield> </record>''' if formatted_record != '': # Skip this record if its value is empty. formatted_records += prologue + encode_for_xml(formatted_record) + epilogue # every n_it_max record, upload all formatted records. # also upload if recID is last one if (n_it_rec > n_it_max or total_rec == len(list)) and \ formatted_records != '': #Save formatted records to disk for bibupload finalfilename = "%s/rec_fmt_%s.xml" % (CFG_TMPDIR, time.strftime('%Y%m%d_%H%M%S')) filehandle = open(finalfilename, "w") filehandle.write("<collection>" + \ formatted_records + \ "</collection>") filehandle.close() ### bibupload external call ### t1 = os.times()[4] message = "START bibupload external call" write_message(message, verbose=9) - bibsched_low_level_task_submission('bibupload', 'bibreformat', '-f', finalfilename) + task_low_level_submission('bibupload', 'bibreformat', '-f', finalfilename) t2 = os.times()[4] tbibupload = tbibupload + (t2 - t1) message = "END bibupload external call (time elapsed:%2f)" % (t2-t1) write_message(message, verbose=9) #Reset iteration state n_it_rec = 0 formatted_records = '' return (total_rec, tbibformat, tbibupload) def iterate_over_old(list, fmt): "Iterate over list of IDs" n_rec = 0 n_max = 10000 xml_content = '' # hold the contents tbibformat = 0 # time taken up by external call tbibupload = 0 # time taken up by external call total_rec = 0 # Number of formatted records for record in list: n_rec = n_rec + 1 total_rec = total_rec + 1 message = "Processing record: %d" % (record) write_message(message, verbose=9) query = "id=%d&of=xm" % (record) count = 0 contents = print_record(record, 'xm') while (contents == "") and (count < 10): contents = print_record(record, 'xm') count = count + 1 time.sleep(10) if count == 10: sys.stderr.write("Failed to download %s from %s after 10 attempts... terminating" % (query, CFG_SITE_URL)) sys.exit(0) xml_content = xml_content + contents if xml_content: if n_rec >= n_max: finalfilename = "%s/rec_fmt_%s.xml" % (CFG_TMPDIR, time.strftime('%Y%m%d_%H%M%S')) filename = "%s/bibreformat.xml" % CFG_TMPDIR filehandle = open(filename ,"w") filehandle.write(xml_content) filehandle.close() ### bibformat external call ### t11 = os.times()[4] message = "START bibformat external call" write_message(message, verbose=9) command = "%s/bibformat otype='%s' < %s/bibreformat.xml > %s 2> %s/bibreformat.err" % (CFG_BINDIR, fmt.upper(), CFG_TMPDIR, finalfilename, CFG_TMPDIR) os.system(command) t22 = os.times()[4] message = "END bibformat external call (time elapsed:%2f)" % (t22-t11) write_message(message, verbose=9) tbibformat = tbibformat + (t22 - t11) ### bibupload external call ### t11 = os.times()[4] message = "START bibupload external call" write_message(message, verbose=9) - bibsched_low_level_task_submission('bibupload', 'bibreformat', '-f', finalfilename) + task_low_level_submission('bibupload', 'bibreformat', '-f', finalfilename) t22 = os.times()[4] message = "END bibupload external call (time elapsed:%2f)" % (t22-t11) write_message(message, verbose=9) tbibupload = tbibupload + (t22- t11) n_rec = 0 xml_content = '' ### Process the last re-formated chunk ### if n_rec > 0: write_message("Processing last record set (%d)" % n_rec, verbose=9) finalfilename = "%s/rec_fmt_%s.xml" % (CFG_TMPDIR, time.strftime('%Y%m%d_%H%M%S')) filename = "%s/bibreformat.xml" % CFG_TMPDIR filehandle = open(filename ,"w") filehandle.write(xml_content) filehandle.close() ### bibformat external call ### t11 = os.times()[4] message = "START bibformat external call" write_message(message, verbose=9) command = "%s/bibformat otype='%s' < %s/bibreformat.xml > %s 2> %s/bibreformat.err" % (CFG_BINDIR, fmt.upper(), CFG_TMPDIR, finalfilename, CFG_TMPDIR) os.system(command) t22 = os.times()[4] message = "END bibformat external call (time elapsed:%2f)" % (t22 - t11) write_message(message, verbose=9) tbibformat = tbibformat + (t22 - t11) ### bibupload external call ### t11 = os.times()[4] message = "START bibupload external call" write_message(message, verbose=9) - bibsched_low_level_task_submission('bibupload', 'bibreformat', '-f', finalfilename) + task_low_level_submission('bibupload', 'bibreformat', '-f', finalfilename) t22 = os.times()[4] message = "END bibupload external call (time elapsed:%2f)" % (t22 - t11) write_message(message, verbose=9) tbibupload = tbibupload + (t22 - t11) return (total_rec, tbibformat, tbibupload) def task_run_core(): """Runs the task by fetching arguments from the BibSched task queue. This is what BibSched will be invoking via daemon call.""" global process, fmt, process_format ## initialize parameters fmt = task_get_option('format') sql = { "all" : "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format ='%s'" % fmt, "last": "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format='%s' and bf.last_updated < br.modification_date" % fmt, "q1" : "select br.id from bibrec as br", "q2" : "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format ='%s'" % fmt } if task_has_option("all"): sql_queries.append(sql['all']) if task_has_option("without"): process_format = 1 if task_has_option("noprocess"): process = 0 if task_has_option("last"): sql_queries.append(sql['last']) if task_has_option("collection"): cds_query['collection'] = task_get_option('collection') else: cds_query['collection'] = "" if task_has_option("field"): cds_query['field'] = task_get_option('field') else: cds_query['field'] = "" if task_has_option("pattern"): cds_query['pattern'] = task_get_option('pattern') else: cds_query['pattern'] = "" if task_has_option("matching"): cds_query['matching'] = task_get_option('matching') else: cds_query['matching'] = "" ### sql commands to be executed during the script run ### bibreformat_task(sql, sql_queries, cds_query, process_format) return True def main(): """Main that construct all the bibtask.""" task_init(authorization_action='runbibformat', authorization_msg="BibReformat Task Submission", description=""" BibReformat formats the records and saves the produced outputs for later retrieval. BibReformat is usually run periodically via BibSched in order to (1) format new records in the database and to (2) reformat records for which the meta data has been modified. BibReformat has to be run manually when (3) format config files have been modified, in order to see the changes in the web interface. Although it is not necessary to run BibReformat to display formatted records in the web interface, BibReformat allows to improve serving speed by precreating the outputs. It is suggested to run BibReformat for 'HB' output. Option -m cannot be used at the same time as option -c. Option -c prevents from finding records in private collections. Examples: bibreformat Format all new or modified records (in HB). bibreformat -o HD Format all new or modified records in HD. bibreformat -a Force reformatting all records (in HB). bibreformat -c 'Photos' Force reformatting all records in 'Photos' collection (in HB). bibreformat -c 'Photos' -o HD Force reformatting all records in 'Photos' collection in HD. bibreformat -n Show how many records are to be (re)formatted. bibreformat -n -c 'Articles' Show how many records are to be (re)formatted in 'Articles' collection. bibreformat -oHB -s1h Format all new and modified records every hour, in HB. """, help_specific_usage=""" -o, --format \t Specify output format (default HB) -n, --noprocess \t Count records to be formatted (no processing done) Reformatting options: -a, --all \t Force reformatting all records -c, --collection \t Force reformatting records by collection -f, --field \t Force reformatting records by field -p, --pattern \t Force reformatting records by pattern Pattern options: -m, --matching \t Specify if pattern is exact (e), regular expression (r), \t partial (p), any of the words (o) or all of the words (a) """, version=__revision__, specific_params=("ac:f:p:lo:nm:", ["all", "collection=", "matching=", "field=", "pattern=", "format=", "noprocess"]), task_submit_check_options_fnc=task_submit_check_options, task_submit_elaborate_specific_parameter_fnc=task_submit_elaborate_specific_parameter, task_run_fnc=task_run_core) def task_submit_check_options(): """Last checks and updating on the options...""" if not (task_has_option('all') or task_has_option('collection') \ or task_has_option('field') or task_has_option('pattern') \ or task_has_option('matching')): task_set_option('without', 1) task_set_option('last', 1) return True def task_submit_elaborate_specific_parameter(key, value, opts, args): """Elaborate specific CLI parameters of BibReformat.""" if key in ("-a", "--all"): task_set_option("all", 1) task_set_option("without", 1) elif key in ("-c", "--collection"): task_set_option("collection", value) elif key in ("-n", "--noprocess"): task_set_option("noprocess", 1) elif key in ("-f", "--field"): task_set_option("field", value) elif key in ("-p","--pattern"): task_set_option("pattern", value) elif key in ("-m", "--matching"): task_set_option("matching", value) elif key in ("-o","--format"): task_set_option("format", value) else: return False return True ### okay, here we go: if __name__ == '__main__': main() diff --git a/modules/bibsched/lib/bibtask.py b/modules/bibsched/lib/bibtask.py index 5d56ef9fe..f5efbca56 100644 --- a/modules/bibsched/lib/bibtask.py +++ b/modules/bibsched/lib/bibtask.py @@ -1,558 +1,558 @@ # -*- coding: utf-8 -*- ## ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """CDS Invenio Bibliographic Task Class. BibTask class. A BibTask is an executable under CFG_BINDIR, whose name is stored in bibtask_config.CFG_BIBTASK_VALID_TASKS. A valid task must call the task_init function with the proper parameters. Generic task related parameters (user, sleeptime, runtime, task_id, task_name verbose) go to _task_params global dictionary accessible through task_get_task_param. Option specific to the particular BibTask go to _options global dictionary and are accessible via task_get_option/task_set_option. In order to log something properly, just use write_message(s) with the desired verbose level. task_update_status and task_update_progress can be used to update the status of the task (DONE, FAILED, DONE WITH ERRORS...) and it's progress (1 out 100..) within the bibsched monitor. It is possible to enqueue a BibTask via API call by means of -bibsched_low_level_task_submission. +task_low_level_submission. """ __revision__ = "$Id$" import getopt import getpass import marshal import os import re import signal import sys import time import traceback from invenio.dbquery import run_sql, _db_login, _db_logout from invenio.access_control_engine import acc_authorize_action from invenio.config import CFG_PREFIX, CFG_BINDIR from invenio.errorlib import register_exception from invenio.access_control_config import CFG_EXTERNAL_AUTH_USING_SSO, \ CFG_EXTERNAL_AUTHENTICATION from invenio.webuser import get_user_preferences, get_email from invenio.bibtask_config import CFG_BIBTASK_VALID_TASKS, \ CFG_BIBTASK_DEFAULT_TASK_SETTINGS # Which tasks don't need to ask the user for authorization? cfg_valid_processes_no_auth_needed = ("bibupload", ) -def bibsched_low_level_task_submission(name, user, *argv): +def task_low_level_submission(name, user, *argv): """Let special lowlevel enqueuing of a task on the bibsche queue. @param name is the name of the bibtask. It must be a valid executable under CFG_BINDIR. @param user is a string that will appear as the "user" submitting the task. Since task are submitted via API it make sense to set the user to the name of the module/function that called - bibsched_low_level_task_submission. + task_low_level_submission. @param argv will be merged with the default setting of the given task as they can be found in bibtask_config. In order to know which variable are valid and which is the semantic, please have a glimpse at bibtask_config and to the source of the task_submit_elaborate_specific_parameter function of the desired bibtask. @return the task_id when the task is correctly enqueued. Use with care! """ task_id = None try: if not name in CFG_BIBTASK_VALID_TASKS: raise StandardError('%s is not a valid task name' % name) argv = tuple([os.path.join(CFG_BINDIR, name)] + list(argv)) ## submit task: task_id = run_sql("""INSERT INTO schTASK (proc,user, runtime,sleeptime,status,arguments) VALUES (%s,%s,NOW(),'','WAITING',%s)""", (name, user, marshal.dumps(argv))) except Exception: register_exception() if task_id: run_sql("""DELETE FROM schTASK WHERE id=%s""", (task_id, )) raise return task_id def task_init( authorization_action="", authorization_msg="", description="", help_specific_usage="", version=__revision__, specific_params=("", []), task_stop_helper_fnc=None, task_submit_elaborate_specific_parameter_fnc=None, task_submit_check_options_fnc=None, task_run_fnc=None): """ Initialize a BibTask. @param authorization_action is the name of the authorization action connected with this task; @param authorization_msg is the header printed when asking for an authorization password; @param description is the generic description printed in the usage page; @param help_specific_usage is the specific parameter help @param task_stop_fnc is a function that will be called whenever the task is stopped @param task_submit_elaborate_specific_parameter_fnc will be called passing a key and a value, for parsing specific cli parameters. Must return True if it has recognized the parameter. Must eventually update the options with bibtask_set_option; @param task_submit_check_options must check the validity of options (via bibtask_get_option) once all the options where parsed; @param task_run_fnc will be called as the main core function. Must return False in case of errors. """ global _task_params, _options _task_params = { "version" : version, "task_stop_helper_fnc" : task_stop_helper_fnc, "task_name" : os.path.basename(sys.argv[0]), "user" : '', "verbose" : 1, "sleeptime" : '', "runtime" : time.strftime("%Y-%m-%d %H:%M:%S"), } to_be_submitted = True if len(sys.argv) == 2 and sys.argv[1].isdigit(): _task_params['task_id'] = int(sys.argv[1]) argv = _task_get_options(_task_params['task_id'], _task_params['task_name']) to_be_submitted = False else: argv = sys.argv _task_build_params(_task_params['task_name'], argv, description, help_specific_usage, version, specific_params, task_submit_elaborate_specific_parameter_fnc, task_submit_check_options_fnc) write_message('argv=%s' % (argv, ), verbose=9) write_message('_options=%s' % (_options, ), verbose=9) write_message('_task_params=%s' % (_task_params, ), verbose=9) if to_be_submitted: _task_submit(argv, authorization_action, authorization_msg) else: try: if not _task_run(task_run_fnc): write_message("Error occurred. Exiting.", sys.stderr) except Exception, e: write_message("Unexpected error occurred: %s." % e, sys.stderr) write_message("Traceback is:", sys.stderr) traceback.print_tb(sys.exc_info()[2]) write_message("Exiting.", sys.stderr) task_update_status("ERROR") def _task_build_params( task_name, argv, description="", help_specific_usage="", version=__revision__, specific_params=("", []), task_submit_elaborate_specific_parameter_fnc=None, task_submit_check_options_fnc=None): """ Build the BibTask params. @param argv a list of string as in sys.argv @param description is the generic description printed in the usage page; @param help_specific_usage is the specific parameter help @param task_submit_elaborate_specific_parameter_fnc will be called passing a key and a value, for parsing specific cli parameters. Must return True if it has recognized the parameter. Must eventually update the options with bibtask_set_option; @param task_submit_check_options must check the validity of options (via bibtask_get_option) once all the options where parsed; """ global _task_params, _options _options = {} if task_name in CFG_BIBTASK_DEFAULT_TASK_SETTINGS: _options.update(CFG_BIBTASK_DEFAULT_TASK_SETTINGS[task_name]) # set user-defined options: try: (short_params, long_params) = specific_params opts, args = getopt.getopt(argv[1:], "hVv:u:s:t:" + short_params, [ "help", "version", "verbose=", "user=", "sleep=", "time=" ] + long_params) except getopt.GetoptError, err: _usage(1, err, help_specific_usage=help_specific_usage, description=description) try: for opt in opts: if opt[0] in ["-h", "--help"]: _usage(0, help_specific_usage=help_specific_usage, description=description) elif opt[0] in ["-V", "--version"]: print _task_params["version"] sys.exit(0) elif opt[0] in [ "-u", "--user"]: _task_params["user"] = opt[1] elif opt[0] in ["-v", "--verbose"]: _task_params["verbose"] = int(opt[1]) elif opt[0] in [ "-s", "--sleeptime" ]: get_datetime(opt[1]) # see if it is a valid shift _task_params["sleeptime"] = opt[1] elif opt[0] in [ "-t", "--runtime" ]: _task_params["runtime"] = get_datetime(opt[1]) elif not callable(task_submit_elaborate_specific_parameter_fnc) or \ not task_submit_elaborate_specific_parameter_fnc(opt[0], opt[1], opts, args): _usage(1, help_specific_usage=help_specific_usage, description=description) except StandardError, e: _usage(e, help_specific_usage=help_specific_usage, description=description) if callable(task_submit_check_options_fnc): if not task_submit_check_options_fnc(): _usage(1, help_specific_usage=help_specific_usage, description=description) def task_set_option(key, value): """Set an value to key in the option dictionary of the task""" global _options try: _options[key] = value except NameError: _options = {key : value} def task_get_option(key, default=None): """Returns the value corresponding to key in the option dictionary of the task""" try: return _options.get(key, default) except NameError: return default def task_has_option(key): """Map the has_key query to _options""" try: return _options.has_key(key) except NameError: return False def task_get_task_param(key, default=None): """Returns the value corresponding to the particular task param""" try: return _task_params.get(key, default) except NameError: return default def task_set_task_param(key, value): """Set the value corresponding to the particular task param""" global _task_params try: _task_params[key] = value except NameError: _task_params = {key : value} def task_update_progress(msg): """Updates progress information in the BibSched task table.""" write_message("Updating task progress to %s." % msg, verbose=9) return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, _task_params["task_id"])) def task_update_status(val): """Updates status information in the BibSched task table.""" write_message("Updating task status to %s." % val, verbose=9) return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, _task_params["task_id"])) def task_read_status(): """Read status information in the BibSched task table.""" res = run_sql("SELECT status FROM schTASK where id=%s", (_task_params['task_id'],), 1) try: out = res[0][0] except: out = 'UNKNOWN' return out def write_messages(msgs, stream=sys.stdout, verbose=1): """Write many messages through write_message""" for msg in msgs.split('\n'): write_message(msg, stream, verbose) def write_message(msg, stream=sys.stdout, verbose=1): """Write message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff.""" if msg and _task_params['verbose'] >= verbose: if stream == sys.stdout or stream == sys.stderr: stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime())) try: stream.write("%s\n" % msg) except UnicodeEncodeError: stream.write("%s\n" % msg.encode('ascii', 'backslashreplace')) stream.flush() else: sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream) _shift_re = re.compile("([-\+]{0,1})([\d]+)([dhms])") def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"): """Returns a date string according to the format string. It can handle normal date strings and shifts with respect to now.""" date = time.time() factors = {"d":24*3600, "h":3600, "m":60, "s":1} m = _shift_re.match(var) if m: sign = m.groups()[0] == "-" and -1 or 1 factor = factors[m.groups()[2]] value = float(m.groups()[1]) date = time.localtime(date + sign * factor * value) date = time.strftime(format_string, date) else: date = time.strptime(var, format_string) date = time.strftime(format_string, date) return date def authenticate(user, authorization_action, authorization_msg=""): """Authenticate the user against the user database. Check for its password, if it exists. Check for authorization_action access rights. Return user name upon authorization success, do system exit upon authorization failure. """ # With SSO it's impossible to check for pwd if CFG_EXTERNAL_AUTH_USING_SSO or os.path.basename(sys.argv[0]) in cfg_valid_processes_no_auth_needed: return user if authorization_msg: print authorization_msg print "=" * len(authorization_msg) if user == "": print >> sys.stdout, "\rUsername: ", user = sys.stdin.readline().lower().strip() else: print >> sys.stdout, "\rUsername:", user ## first check user: # p_un passed may be an email or a nickname: res = run_sql("select id from user where email=%s", (user,), 1) + \ run_sql("select id from user where nickname=%s", (user,), 1) if not res: print "Sorry, %s does not exist." % user sys.exit(1) else: uid = res[0][0] ok = False login_method = get_user_preferences(uid)['login_method'] if not CFG_EXTERNAL_AUTHENTICATION[login_method][0]: #Local authentication, let's see if we want passwords. res = run_sql("select id from user where id=%s " "and password=AES_ENCRYPT(email,'')", (uid,), 1) if res: ok = True if not ok: password_entered = getpass.getpass() if not CFG_EXTERNAL_AUTHENTICATION[login_method][0]: res = run_sql("select id from user where id=%s " "and password=AES_ENCRYPT(email, %s)", (uid, password_entered), 1) if res: ok = True else: if CFG_EXTERNAL_AUTHENTICATION[login_method][0].auth_user(get_email(uid), password_entered): ok = True if not ok: print "Sorry, wrong credentials for %s." % user sys.exit(1) else: ## secondly check authorization for the authorization_action: (auth_code, auth_message) = acc_authorize_action(uid, authorization_action) if auth_code != 0: print auth_message sys.exit(1) return user def _task_submit(argv, authorization_action, authorization_msg): """Submits task to the BibSched task queue. This is what people will be invoking via command line.""" ## sanity check: remove eventual "task" option: ## authenticate user: _task_params['user'] = authenticate(_task_params["user"], authorization_action, authorization_msg) ## submit task: write_message("storing task options %s\n" % argv, verbose=9) _task_params['task_id'] = run_sql("""INSERT INTO schTASK (id,proc,user, runtime,sleeptime,status,arguments) VALUES (NULL,%s,%s,%s,%s,'WAITING',%s)""", (_task_params['task_name'], _task_params['user'], _task_params["runtime"], _task_params["sleeptime"], marshal.dumps(argv))) ## update task number: write_message("Task #%d submitted." % _task_params['task_id']) return _task_params['task_id'] def _task_get_options(task_id, task_name): """Returns options for the task 'id' read from the BibSched task queue table.""" out = {} res = run_sql("SELECT arguments FROM schTASK WHERE id=%s AND proc=%s", (task_id, task_name)) try: out = marshal.loads(res[0][0]) except: write_message("Error: %s task %d does not seem to exist." \ % (task_name, task_id), sys.stderr) sys.exit(1) write_message('Options retrieved: %s' % (out, ), verbose=9) return out def _task_run(task_run_fnc): """Runs the task by fetching arguments from the BibSched task queue. This is what BibSched will be invoking via daemon call. The task prints Fibonacci numbers for up to NUM on the stdout, and some messages on stderr. @param task_run_fnc will be called as the main core function. Must return False in case of errors. Return True in case of success and False in case of failure.""" ## We prepare the pid file inside /prefix/var/run/taskname_id.pid global _options pidfile_name = os.path.join(CFG_PREFIX, 'var', 'run', 'bibsched_task_%d.pid' % _task_params['task_id']) pidfile = open(pidfile_name, 'w') pidfile.write(str(os.getpid())) pidfile.close() ## check task status: task_status = task_read_status() if task_status != "WAITING": write_message("Error: The task #%d is %s. I expected WAITING." % (_task_params['task_id'], task_status), sys.stderr) return False ## we can run the task now: write_message("Task #%d started." % _task_params['task_id']) task_update_status("RUNNING") ## initialize signal handler: signal.signal(signal.SIGUSR1, _task_sig_sleep) signal.signal(signal.SIGTERM, _task_sig_stop) signal.signal(signal.SIGABRT, _task_sig_suicide) signal.signal(signal.SIGCONT, _task_sig_wakeup) signal.signal(signal.SIGINT, _task_sig_unknown) ## run the task: _task_params['task_starting_time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) if callable(task_run_fnc) and task_run_fnc(): task_update_status("DONE") else: task_update_status("DONE WITH ERRORS") ## we are done: write_message("Task #%d finished." % _task_params['task_id']) ## Removing the pid os.remove(pidfile_name) return True def _usage(exitcode=1, msg="", help_specific_usage="", description=""): """Prints usage info.""" if msg: sys.stderr.write("Error: %s.\n" % msg) sys.stderr.write("Usage: %s [options]\n" % sys.argv[0]) if help_specific_usage: sys.stderr.write("Command options:\n") sys.stderr.write(help_specific_usage) sys.stderr.write("Scheduling options:\n") sys.stderr.write(" -u, --user=USER\tUser name to submit the" " task as, password needed.\n") sys.stderr.write(" -t, --runtime=TIME\tTime to execute the" " task (now), e.g.: +15s, 5m, 3h, 2002-10-27 13:57:26\n") sys.stderr.write(" -s, --sleeptime=SLEEP\tSleeping frequency after" " which to repeat task (no), e.g.: 30m, 2h, 1d\n") sys.stderr.write("General options:\n") sys.stderr.write(" -h, --help\t\tPrint this help.\n") sys.stderr.write(" -V, --version\t\tPrint version information.\n") sys.stderr.write(" -v, --verbose=LEVEL\tVerbose level (0=min," " 1=default, 9=max).\n") if description: sys.stderr.write(description) sys.exit(exitcode) def _task_sig_sleep(sig, frame): """Signal handler for the 'sleep' signal sent by BibSched.""" write_message("task_sig_sleep(), got signal %s frame %s" % (sig, frame), verbose=9) # _db_logout() #FIXME Not sure this can do more evil than good things. write_message("sleeping...") task_update_status("SLEEPING") signal.pause() # wait for wake-up signal def _task_sig_wakeup(sig, frame): """Signal handler for the 'wakeup' signal sent by BibSched.""" write_message("task_sig_wakeup(), got signal %s frame %s" % (sig, frame), verbose=9) # _db_login(1) #FIXME Not sure this can do more evil than good things. write_message("continuing...") task_update_status("CONTINUING") def _task_sig_stop(sig, frame): """Signal handler for the 'stop' signal sent by BibSched.""" write_message("task_sig_stop(), got signal %s frame %s" % (sig, frame), verbose=9) write_message("stopping...") task_update_status("STOPPING") if callable(_task_params['task_stop_helper_fnc']): try: write_message("flushing cache or whatever...") _task_params['task_stop_helper_fnc']() time.sleep(3) except StandardError, err: write_message("Error during stopping! %e" % err) task_update_status("STOPPINGFAILED") sys.exit(1) # _db_logout() #FIXME Not sure this can do more evil than good things. write_message("stopped") task_update_status("STOPPED") sys.exit(0) def _task_sig_suicide(sig, frame): """Signal handler for the 'suicide' signal sent by BibSched.""" write_message("task_sig_suicide(), got signal %s frame %s" % (sig, frame), verbose=9) write_message("suiciding myself now...") task_update_status("SUICIDING") _db_logout() write_message("suicided") task_update_status("SUICIDED") sys.exit(0) def _task_sig_unknown(sig, frame): """Signal handler for the other unknown signals sent by shell or user.""" # do nothing for unknown signals: write_message("unknown signal %d (frame %s) ignored" % (sig, frame)) diff --git a/modules/websubmit/lib/functions/Insert_Modify_Record.py b/modules/websubmit/lib/functions/Insert_Modify_Record.py index 0e46454ca..7effc4e96 100644 --- a/modules/websubmit/lib/functions/Insert_Modify_Record.py +++ b/modules/websubmit/lib/functions/Insert_Modify_Record.py @@ -1,44 +1,44 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. __revision__ = "$Id$" import os import shutil import time from invenio.config import \ CFG_BINDIR, \ CFG_TMPDIR from invenio.websubmit_config import InvenioWebSubmitFunctionError -from invenio.bibtask import bibsched_low_level_task_submission +from invenio.bibtask import task_low_level_submission def Insert_Modify_Record(parameters, curdir, form, user_info=None): global rn if os.path.exists("%s/recmysqlfmt" % curdir): recfile = "recmysqlfmt" elif os.path.exists("%s/recmysql" % curdir): recfile = "recmysql" else: raise InvenioWebSubmitFunctionError("Could not find record file") initialfile = "%s/%s" % (curdir,recfile) finalfile = "%s/%s_%s" % (CFG_TMPDIR,rn,time.strftime("%Y-%m-%d_%H:%M:%S")) shutil.copy(initialfile,finalfile) - bibsched_low_level_task_submission('bibupload', 'websubmit.Insert_Modify_Record', '-c', finalfile) + task_low_level_submission('bibupload', 'websubmit.Insert_Modify_Record', '-c', finalfile) return "" diff --git a/modules/websubmit/lib/functions/Insert_Record.py b/modules/websubmit/lib/functions/Insert_Record.py index 09723e58d..2594a8ab7 100644 --- a/modules/websubmit/lib/functions/Insert_Record.py +++ b/modules/websubmit/lib/functions/Insert_Record.py @@ -1,42 +1,42 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. __revision__ = "$Id$" import os import time import shutil from invenio.config import \ CFG_BINDIR, \ CFG_TMPDIR from invenio.websubmit_config import InvenioWebSubmitFunctionError -from invenio.bibtask import bibsched_low_level_task_submission +from invenio.bibtask import task_low_level_submission def Insert_Record(parameters, curdir, form, user_info=None): global rn if os.path.exists("%s/recmysql" % curdir): recfile = "recmysql" else: raise InvenioWebSubmitFunctionError("Could not find record file") initialfile = "%s/%s" % (curdir,recfile) finalfile = "%s/%s_%s" % (CFG_TMPDIR,rn,time.strftime("%Y-%m-%d_%H:%M:%S")) shutil.copy(initialfile,finalfile) - bibsched_low_level_task_submission('bibupload', 'websumit.Insert_Record', '-r', '-i', finalfile) + task_low_level_submission('bibupload', 'websumit.Insert_Record', '-r', '-i', finalfile) return ""