def cli_revert_to_revision(revid): """Submit specified record revision REVID upload, to replace current version. """ if not revision_format_valid_p(revid): print 'ERROR: revision %s is invalid; ' \ 'must be NNN.YYYYMMDDhhmmss.' % revid sys.exit(1) xml_record = get_marcxml_of_revision_id(revid) if xml_record == '': print 'ERROR: Revision %s does not exist. ' % revid sys.exit(1) recid = split_revid(revid)[0] if record_locked_by_other_user(recid, -1): print 'The record is currently being edited. ' \ 'Please try again in a few minutes.' sys.exit(1) if record_locked_by_queue(recid): print 'The record is locked because of unfinished upload tasks. ' \ 'Please try again in a few minutes.' sys.exit(1) save_xml_record(recid, 0, xml_record) print 'Your modifications have now been submitted. They will be ' \ 'processed as soon as the task queue is empty.'
def cli_revert_to_revision(revid): """Submit specified record revision REVID upload, to replace current version. """ if not revision_format_valid_p(revid): print 'ERROR: revision %s is invalid; ' \ 'must be NNN.YYYYMMDDhhmmss.' % revid sys.exit(1) xml_record = get_marcxml_of_revision_id(revid) if xml_record == '': print 'ERROR: Revision %s does not exist. ' % revid sys.exit(1) recid = split_revid(revid)[0] if record_locked_by_other_user(recid, -1): print 'The record is currently being edited. ' \ 'Please try again in a few minutes.' sys.exit(1) if record_locked_by_queue(recid): print 'The record is locked because of unfinished upload tasks. ' \ 'Please try again in a few minutes.' sys.exit(1) save_xml_record(recid, 0, xml_record) print 'Your modifications have now been submitted. They will be ' \ 'processed as soon as the task queue is empty.'
def _get_record_slave(recid, result, mode=None, uid=None): """Check if record exists and return it in dictionary format. If any kind of error occurs returns None. If mode=='revision' then recid parameter is considered as revid.""" record = None if recid == 'none': mode = 'none' if mode == 'recid': record_status = record_exists(recid) #check for errors if record_status == 0: result['resultCode'], result[ 'resultText'] = 1, 'Non-existent record: %s' % recid elif record_status == -1: result['resultCode'], result[ 'resultText'] = 1, 'Deleted record: %s' % recid elif record_locked_by_queue(recid): result['resultCode'], result[ 'resultText'] = 1, 'Record %s locked by queue' % recid else: record = create_record(print_record(recid, 'xm'))[0] record_order_subfields(record) elif mode == 'tmpfile': file_path = '%s_%s.xml' % (_get_file_path( recid, uid), CFG_BIBEDIT_TO_MERGE_SUFFIX) if not os.path.isfile(file_path): #check if file doesn't exist result['resultCode'], result[ 'resultText'] = 1, 'Temporary file doesnt exist' else: #open file tmpfile = open(file_path, 'r') record = create_record(tmpfile.read())[0] tmpfile.close() elif mode == 'revision': if revision_format_valid_p(recid): marcxml = get_marcxml_of_revision_id(recid) if marcxml: record = create_record(marcxml)[0] else: result['resultCode'], result[ 'resultText'] = 1, 'The specified revision does not exist' else: result['resultCode'], result[ 'resultText'] = 1, 'Invalid revision id' elif mode == 'none': return {} else: result['resultCode'], result[ 'resultText'] = 1, 'Invalid record mode for record2' return record
def _get_record_slave(recid, result, mode=None, uid=None): """Check if record exists and return it in dictionary format. If any kind of error occurs returns None. If mode=='revision' then recid parameter is considered as revid.""" record = None if recid == 'none': mode = 'none' if mode == 'recid': record_status = record_exists(recid) #check for errors if record_status == 0: result['resultCode'], result['resultText'] = 1, 'Non-existent record: %s' % recid elif record_status == -1: result['resultCode'], result['resultText'] = 1, 'Deleted record: %s' % recid elif record_locked_by_queue(recid): result['resultCode'], result['resultText'] = 1, 'Record %s locked by queue' % recid else: record = create_record( print_record(recid, 'xm') )[0] record_order_subfields(record) elif mode == 'tmpfile': file_path = '%s_%s.xml' % (_get_file_path(recid, uid), CFG_BIBEDIT_TO_MERGE_SUFFIX) if not os.path.isfile(file_path): #check if file doesn't exist result['resultCode'], result['resultText'] = 1, 'Temporary file doesnt exist' else: #open file tmpfile = open(file_path, 'r') record = create_record( tmpfile.read() )[0] tmpfile.close() elif mode == 'revision': if revision_format_valid_p(recid): marcxml = get_marcxml_of_revision_id(recid) if marcxml: record = create_record(marcxml)[0] else: result['resultCode'], result['resultText'] = 1, 'The specified revision does not exist' else: result['resultCode'], result['resultText'] = 1, 'Invalid revision id' elif mode == 'none': return {} else: result['resultCode'], result['resultText'] = 1, 'Invalid record mode for record2' return record
def _get_record(recid, uid, result, fresh_record=False): """Retrieve record structure. """ record = None mtime = None cache_dirty = None record_status = record_exists(recid) existing_cache = cache_exists(recid, uid) if record_status == 0: result['resultCode'], result[ 'resultText'] = 1, 'Non-existent record: %s' % recid elif record_status == -1: result['resultCode'], result[ 'resultText'] = 1, 'Deleted record: %s' % recid elif not existing_cache and record_locked_by_other_user(recid, uid): result['resultCode'], result[ 'resultText'] = 1, 'Record %s locked by user' % recid elif existing_cache and cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): result['resultCode'], result[ 'resultText'] = 1, 'Record %s locked by user' % recid elif record_locked_by_queue(recid): result['resultCode'], result[ 'resultText'] = 1, 'Record %s locked by queue' % recid else: if fresh_record: delete_cache(recid, uid) existing_cache = False if not existing_cache: record_revision, record = create_cache(recid, uid) mtime = get_cache_mtime(recid, uid) cache_dirty = False else: tmpRes = get_cache_contents(recid, uid) cache_dirty, record_revision, record = tmpRes[0], tmpRes[ 1], tmpRes[2] touch_cache(recid, uid) mtime = get_cache_mtime(recid, uid) if not latest_record_revision(recid, record_revision): result['cacheOutdated'] = True result['resultCode'], result['resultText'], result[ 'cacheDirty'], result[ 'cacheMTime'] = 0, 'Record OK', cache_dirty, mtime record_order_subfields(record) return record
def _get_record_slave(recid, result, mode=None, uid=None): """Check if record exists and return it in dictionary format. If any kind of error occurs returns None. If mode=='revision' then recid parameter is considered as revid.""" record = None if recid == "none": mode = "none" if mode == "recid": record_status = record_exists(recid) # check for errors if record_status == 0: result["resultCode"], result["resultText"] = 1, "Non-existent record: %s" % recid elif record_status == -1: result["resultCode"], result["resultText"] = 1, "Deleted record: %s" % recid elif record_locked_by_queue(recid): result["resultCode"], result["resultText"] = 1, "Record %s locked by queue" % recid else: record = create_record(print_record(recid, "xm"))[0] elif mode == "tmpfile": file_path = "%s_%s.xml" % (_get_file_path(recid, uid), CFG_BIBEDIT_TO_MERGE_SUFFIX) if not os.path.isfile(file_path): # check if file doesn't exist result["resultCode"], result["resultText"] = 1, "Temporary file doesnt exist" else: # open file tmpfile = open(file_path, "r") record = create_record(tmpfile.read())[0] tmpfile.close() elif mode == "revision": if revision_format_valid_p(recid): marcxml = get_marcxml_of_revision_id(recid) if marcxml: record = create_record(marcxml)[0] else: result["resultCode"], result["resultText"] = 1, "The specified revision does not exist" else: result["resultCode"], result["resultText"] = 1, "Invalid revision id" elif mode == "none": return {} else: result["resultCode"], result["resultText"] = 1, "Invalid record mode for record2" return record
def _get_record(recid, uid, result, fresh_record=False): """Retrieve record structure. """ record = None mtime = None cache_dirty = None record_status = record_exists(recid) existing_cache = cache_exists(recid, uid) if record_status == 0: result["resultCode"], result["resultText"] = 1, "Non-existent record: %s" % recid elif record_status == -1: result["resultCode"], result["resultText"] = 1, "Deleted record: %s" % recid elif not existing_cache and record_locked_by_other_user(recid, uid): result["resultCode"], result["resultText"] = 1, "Record %s locked by user" % recid elif existing_cache and cache_expired(recid, uid) and record_locked_by_other_user(recid, uid): result["resultCode"], result["resultText"] = 1, "Record %s locked by user" % recid elif record_locked_by_queue(recid): result["resultCode"], result["resultText"] = 1, "Record %s locked by queue" % recid else: if fresh_record: delete_cache_file(recid, uid) existing_cache = False if not existing_cache: record_revision, record = create_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) cache_dirty = False else: tmpRes = get_cache_file_contents(recid, uid) cache_dirty, record_revision, record = tmpRes[0], tmpRes[1], tmpRes[2] touch_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) if not latest_record_revision(recid, record_revision): result["cacheOutdated"] = True result["resultCode"], result["resultText"], result["cacheDirty"], result["cacheMTime"] = ( 0, "Record OK", cache_dirty, mtime, ) return record
def _get_record(recid, uid, result, fresh_record=False): """Retrieve record structure. """ record = None mtime = None cache_dirty = None record_status = record_exists(recid) existing_cache = cache_exists(recid, uid) if record_status == 0: result['resultCode'], result['resultText'] = 1, 'Non-existent record: %s' % recid elif record_status == -1: result['resultCode'], result['resultText'] = 1, 'Deleted record: %s' % recid elif not existing_cache and record_locked_by_other_user(recid, uid): result['resultCode'], result['resultText'] = 1, 'Record %s locked by user' % recid elif existing_cache and cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): result['resultCode'], result['resultText'] = 1, 'Record %s locked by user' % recid elif record_locked_by_queue(recid): result['resultCode'], result['resultText'] = 1, 'Record %s locked by queue' % recid else: if fresh_record: delete_cache(recid, uid) existing_cache = False if not existing_cache: record_revision, record = create_cache(recid, uid) mtime = get_cache_mtime(recid, uid) cache_dirty = False else: tmpRes = get_cache_contents(recid, uid) cache_dirty, record_revision, record = tmpRes[0], tmpRes[1], tmpRes[2] touch_cache(recid, uid) mtime = get_cache_mtime(recid, uid) if not latest_record_revision(recid, record_revision): result['cacheOutdated'] = True result['resultCode'], result['resultText'], result['cacheDirty'], result['cacheMTime'] = 0, 'Record OK', cache_dirty, mtime record_order_subfields(record) return record
def perform_request_test_search(search_criteria, update_commands, output_format, page_to_display, language, outputTags, collection="", compute_modifications=0, upload_mode='-c', req=None, checked_records=None): """Returns the results of a test search. @param search_criteria: search criteria used in the test search @type search_criteria: string @param update_commands: list of commands used to update record contents @type update_commands: list of objects @param output_format: specifies the output format as expected from bibformat @type output_format: string (hm, hb, hd, xm, xn, hx) @param page_to_display: the number of the page that should be displayed to the user @type page_to_display: int @param language: the language used to format the content @param outputTags: list of tags to be displayed in search results @type outputTags: list of strings @param collection: collection to be filtered in the results @type collection: string @param compute_modifications: if equals 0 do not compute else compute modifications @type compute_modifications: int """ RECORDS_PER_PAGE = 100 response = {} if collection == "Any collection": collection = "" record_IDs = search_engine.perform_request_search(p=search_criteria, c=collection, req=req) # initializing checked_records if not initialized yet or empty if checked_records is None or not checked_records: checked_records = record_IDs number_of_records = len(record_IDs) if page_to_display < 1: page_to_display = 1 last_page_number = number_of_records / RECORDS_PER_PAGE + 1 if page_to_display > last_page_number: page_to_display = last_page_number first_record_to_display = RECORDS_PER_PAGE * (page_to_display - 1) last_record_to_display = (RECORDS_PER_PAGE * page_to_display) - 1 displayed_records = record_IDs[first_record_to_display:last_record_to_display + 1] if not compute_modifications: record_IDs = displayed_records records_content = [] record_modifications = 0 locked_records = [] for record_id in record_IDs: if upload_mode == '-r' and record_locked_by_queue(record_id): locked_records.append(record_id) current_modifications = [current_command._modifications for current_command in update_commands] formated_record = _get_formated_record(record_id=record_id, output_format=output_format, update_commands=update_commands, language=language, outputTags=outputTags, checked=record_id in checked_records, displayed_records=displayed_records) new_modifications = [current_command._modifications for current_command in update_commands] if new_modifications > current_modifications: record_modifications += 1 if formated_record: records_content.append((record_id, formated_record)) total_modifications = [] if compute_modifications: field_modifications = 0 subfield_modifications = 0 for current_command in update_commands: field_modifications += current_command._modifications for subfield_command in current_command._subfield_commands: subfield_modifications += subfield_command._modifications if record_modifications: total_modifications.append(record_modifications) total_modifications.append(field_modifications) total_modifications.append(subfield_modifications) response['display_info_box'] = compute_modifications or locked_records response['info_html'] = multiedit_templates.info_box(language=language, total_modifications=total_modifications) if locked_records: response['info_html'] += multiedit_templates.tmpl_locked_record_list(language=language, locked_records=locked_records) response['search_html'] = multiedit_templates.search_results(records=records_content, number_of_records=number_of_records, current_page=page_to_display, records_per_page=RECORDS_PER_PAGE, language=language, output_format=output_format, checked_records=checked_records) response['checked_records'] = checked_records return response
def perform_request_record(req, request_type, recid, uid, data): """Handle 'major' record related requests like fetching, submitting or deleting a record, cancel editing or preparing a record for merging. """ response = {} if request_type == 'newRecord': # Create a new record. new_recid = reserve_record_id() new_type = data['newType'] if new_type == 'empty': # Create a new empty record. create_cache_file(recid, uid) response['resultCode'], response['newRecID'] = 6, new_recid elif new_type == 'template': # Create a new record from XML record template. template_filename = data['templateFilename'] template = get_record_template(template_filename) if not template: response['resultCode'] = 108 else: record = create_record(template)[0] if not record: response['resultCode'] = 109 else: record_add_field(record, '001', controlfield_value=str(new_recid)) create_cache_file(new_recid, uid, record, True) response['resultCode'], response['newRecID'] = 7, new_recid elif new_type == 'clone': # Clone an existing record (from the users cache). existing_cache = cache_exists(recid, uid) if existing_cache: try: record = get_cache_file_contents(recid, uid)[2] except: # if, for example, the cache format was wrong (outdated) record = get_bibrecord(recid) else: # Cache missing. Fall back to using original version. record = get_bibrecord(recid) record_delete_field(record, '001') record_add_field(record, '001', controlfield_value=str(new_recid)) create_cache_file(new_recid, uid, record, True) response['resultCode'], response['newRecID'] = 8, new_recid elif request_type == 'getRecord': # Fetch the record. Possible error situations: # - Non-existing record # - Deleted record # - Record locked by other user # - Record locked by queue # A cache file will be created if it does not exist. # If the cache is outdated (i.e., not based on the latest DB revision), # cacheOutdated will be set to True in the response. record_status = record_exists(recid) existing_cache = cache_exists(recid, uid) read_only_mode = False if data.has_key("inReadOnlyMode"): read_only_mode = data['inReadOnlyMode'] if record_status == 0: response['resultCode'] = 102 elif record_status == -1: response['resultCode'] = 103 elif not read_only_mode and not existing_cache and \ record_locked_by_other_user(recid, uid): response['resultCode'] = 104 elif not read_only_mode and existing_cache and \ cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): response['resultCode'] = 104 elif not read_only_mode and record_locked_by_queue(recid): response['resultCode'] = 105 else: if data.get('deleteRecordCache'): delete_cache_file(recid, uid) existing_cache = False pending_changes = [] disabled_hp_changes = {} if read_only_mode: if data.has_key('recordRevision'): record_revision_ts = data['recordRevision'] record_xml = get_marcxml_of_revision(recid, record_revision_ts) record = create_record(record_xml)[0] record_revision = timestamp_to_revision(record_revision_ts) pending_changes = [] disabled_hp_changes = {} else: # a normal cacheless retrieval of a record record = get_bibrecord(recid) record_revision = get_record_last_modification_date(recid) pending_changes = [] disabled_hp_changes = {} cache_dirty = False mtime = 0 elif not existing_cache: record_revision, record = create_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) pending_changes = [] disabled_hp_changes = {} cache_dirty = False else: try: cache_dirty, record_revision, record, pending_changes, disabled_hp_changes= \ get_cache_file_contents(recid, uid) touch_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) if not latest_record_revision(recid, record_revision): response['cacheOutdated'] = True except: record_revision, record = create_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) pending_changes = [] disabled_hp_changes = {} cache_dirty = False if data['clonedRecord']: response['resultCode'] = 9 else: response['resultCode'] = 3 revision_author = get_record_revision_author(recid, record_revision) last_revision_ts = revision_to_timestamp(get_record_last_modification_date(recid)) revisions_history = get_record_revision_timestamps(recid) response['cacheDirty'], response['record'], response['cacheMTime'],\ response['recordRevision'], response['revisionAuthor'], \ response['lastRevision'], response['revisionsHistory'], \ response['inReadOnlyMode'], response['pendingHpChanges'], \ response['disabledHpChanges'] = cache_dirty, record, mtime, \ revision_to_timestamp(record_revision), revision_author, \ last_revision_ts, revisions_history, read_only_mode, pending_changes, \ disabled_hp_changes # Set tag format from user's session settings. try: tagformat_settings = session_param_get(req, 'bibedit_tagformat') tagformat = tagformat_settings[recid] except KeyError: tagformat = CFG_BIBEDIT_TAG_FORMAT response['tagFormat'] = tagformat elif request_type == 'submit': # Submit the record. Possible error situations: # - Missing cache file # - Cache file modified in other editor # - Record locked by other user # - Record locked by queue # - Invalid XML characters # If the cache is outdated cacheOutdated will be set to True in the # response. if not cache_exists(recid, uid): response['resultCode'] = 106 elif not get_cache_mtime(recid, uid) == data['cacheMTime']: response['resultCode'] = 107 elif cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): response['resultCode'] = 104 elif record_locked_by_queue(recid): response['resultCode'] = 105 else: try: record_revision, record, pending_changes, disabled_changes = get_cache_file_contents(recid, uid)[1:] xml_record = print_rec(record) record, status_code, list_of_errors = create_record(xml_record) if status_code == 0: response['resultCode'], response['errors'] = 110, \ list_of_errors elif not data['force'] and \ not latest_record_revision(recid, record_revision): response['cacheOutdated'] = True else: save_xml_record(recid, uid) response['resultCode'] = 4 except: response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV['wrong_cache_file_format'] elif request_type == 'revert': revId = data['revId'] job_date = "%s-%s-%s %s:%s:%s" % re_revdate_split.search(revId).groups() revision_xml = get_marcxml_of_revision(recid, job_date) save_xml_record(recid, uid, revision_xml) if (cache_exists(recid, uid)): delete_cache_file(recid, uid) response['resultCode'] = 4 elif request_type == 'cancel': # Cancel editing by deleting the cache file. Possible error situations: # - Cache file modified in other editor if cache_exists(recid, uid): if get_cache_mtime(recid, uid) == data['cacheMTime']: delete_cache_file(recid, uid) response['resultCode'] = 5 else: response['resultCode'] = 107 else: response['resultCode'] = 5 elif request_type == 'deleteRecord': # Submit the record. Possible error situations: # - Record locked by other user # - Record locked by queue # As the user is requesting deletion we proceed even if the cache file # is missing and we don't check if the cache is outdated or has # been modified in another editor. existing_cache = cache_exists(recid, uid) pending_changes = [] if existing_cache and cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): response['resultCode'] = 104 elif record_locked_by_queue(recid): response['resultCode'] = 105 else: if not existing_cache: record_revision, record, pending_changes, desactivated_hp_changes = create_cache_file(recid, uid) else: try: record_revision, record, pending_changes, desactivated_hp_changes = get_cache_file_contents( recid, uid)[1:] except: record_revision, record, pending_changes, desactivated_hp_changes = create_cache_file(recid, uid) record_add_field(record, '980', ' ', ' ', '', [('c', 'DELETED')]) update_cache_file_contents(recid, uid, record_revision, record, pending_changes, desactivated_hp_changes) save_xml_record(recid, uid) delete_related_holdingpen_changes(recid) # we don't need any changes related to a deleted record response['resultCode'] = 10 elif request_type == 'deleteRecordCache': # Delete the cache file. Ignore the request if the cache has been # modified in another editor. if cache_exists(recid, uid) and get_cache_mtime(recid, uid) == \ data['cacheMTime']: delete_cache_file(recid, uid) response['resultCode'] = 11 elif request_type == 'prepareRecordMerge': # We want to merge the cache with the current DB version of the record, # so prepare an XML file from the file cache, to be used by BibMerge. # Possible error situations: # - Missing cache file # - Record locked by other user # - Record locked by queue # We don't check if cache is outdated (a likely scenario for this # request) or if it has been modified in another editor. if not cache_exists(recid, uid): response['resultCode'] = 106 elif cache_expired(recid, uid) and \ record_locked_by_other_user(recid, uid): response['resultCode'] = 104 elif record_locked_by_queue(recid): response['resultCode'] = 105 else: save_xml_record(recid, uid, to_upload=False, to_merge=True) response['resultCode'] = 12 return response
def perform_request_test_search(search_criteria, update_commands, output_format, page_to_display, language, outputTags, collection="", compute_modifications=0, upload_mode='-c', req=None, checked_records=None): """Returns the results of a test search. @param search_criteria: search criteria used in the test search @type search_criteria: string @param update_commands: list of commands used to update record contents @type update_commands: list of objects @param output_format: specifies the output format as expected from bibformat @type output_format: string (hm, hb, hd, xm, xn, hx) @param page_to_display: the number of the page that should be displayed to the user @type page_to_display: int @param language: the language used to format the content @param outputTags: list of tags to be displayed in search results @type outputTags: list of strings @param collection: collection to be filtered in the results @type collection: string @param compute_modifications: if equals 0 do not compute else compute modifications @type compute_modifications: int """ RECORDS_PER_PAGE = 100 response = {} if collection == "Any collection": collection = "" record_IDs = search_engine.perform_request_search(p=search_criteria, c=collection, req=req) # initializing checked_records if not initialized yet or empty if checked_records is None or not checked_records: checked_records = record_IDs number_of_records = len(record_IDs) if page_to_display < 1: page_to_display = 1 last_page_number = number_of_records / RECORDS_PER_PAGE + 1 if page_to_display > last_page_number: page_to_display = last_page_number first_record_to_display = RECORDS_PER_PAGE * (page_to_display - 1) last_record_to_display = (RECORDS_PER_PAGE * page_to_display) - 1 displayed_records = record_IDs[ first_record_to_display:last_record_to_display + 1] if not compute_modifications: record_IDs = displayed_records records_content = [] record_modifications = 0 locked_records = [] for record_id in record_IDs: if upload_mode == '-r' and record_locked_by_queue(record_id): locked_records.append(record_id) current_modifications = [ current_command._modifications for current_command in update_commands ] formated_record = _get_formated_record( record_id=record_id, output_format=output_format, update_commands=update_commands, language=language, outputTags=outputTags, checked=record_id in checked_records, displayed_records=displayed_records) new_modifications = [ current_command._modifications for current_command in update_commands ] if new_modifications > current_modifications: record_modifications += 1 if formated_record: records_content.append((record_id, formated_record)) total_modifications = [] if compute_modifications: field_modifications = 0 subfield_modifications = 0 for current_command in update_commands: field_modifications += current_command._modifications for subfield_command in current_command._subfield_commands: subfield_modifications += subfield_command._modifications if record_modifications: total_modifications.append(record_modifications) total_modifications.append(field_modifications) total_modifications.append(subfield_modifications) response['display_info_box'] = compute_modifications or locked_records response['info_html'] = multiedit_templates.info_box( language=language, total_modifications=total_modifications) if locked_records: response['info_html'] += multiedit_templates.tmpl_locked_record_list( language=language, locked_records=locked_records) response['search_html'] = multiedit_templates.search_results( records=records_content, number_of_records=number_of_records, current_page=page_to_display, records_per_page=RECORDS_PER_PAGE, language=language, output_format=output_format, checked_records=checked_records) response['checked_records'] = checked_records return response
def perform_request_record(req, request_type, recid, uid, data, ln=CFG_SITE_LANG): """Handle 'major' record related requests like fetching, submitting or deleting a record, cancel editing or preparing a record for merging. """ response = {} if request_type == "newRecord": # Create a new record. new_recid = reserve_record_id() new_type = data["newType"] if new_type == "empty": # Create a new empty record. create_cache_file(recid, uid) response["resultCode"], response["newRecID"] = 6, new_recid elif new_type == "template": # Create a new record from XML record template. template_filename = data["templateFilename"] template = get_record_template(template_filename) if not template: response["resultCode"] = 108 else: record = create_record(template)[0] if not record: response["resultCode"] = 109 else: record_add_field(record, "001", controlfield_value=str(new_recid)) create_cache_file(new_recid, uid, record, True) response["resultCode"], response["newRecID"] = 7, new_recid elif new_type == "clone": # Clone an existing record (from the users cache). existing_cache = cache_exists(recid, uid) if existing_cache: try: record = get_cache_file_contents(recid, uid)[2] except: # if, for example, the cache format was wrong (outdated) record = get_bibrecord(recid) else: # Cache missing. Fall back to using original version. record = get_bibrecord(recid) record_delete_field(record, "001") record_add_field(record, "001", controlfield_value=str(new_recid)) create_cache_file(new_recid, uid, record, True) response["resultCode"], response["newRecID"] = 8, new_recid elif request_type == "getRecord": # Fetch the record. Possible error situations: # - Non-existing record # - Deleted record # - Record locked by other user # - Record locked by queue # A cache file will be created if it does not exist. # If the cache is outdated (i.e., not based on the latest DB revision), # cacheOutdated will be set to True in the response. record_status = record_exists(recid) existing_cache = cache_exists(recid, uid) read_only_mode = False if data.has_key("inReadOnlyMode"): read_only_mode = data["inReadOnlyMode"] if record_status == 0: response["resultCode"] = 102 elif record_status == -1: response["resultCode"] = 103 elif not read_only_mode and not existing_cache and record_locked_by_other_user(recid, uid): response["resultCode"] = 104 elif ( not read_only_mode and existing_cache and cache_expired(recid, uid) and record_locked_by_other_user(recid, uid) ): response["resultCode"] = 104 elif not read_only_mode and record_locked_by_queue(recid): response["resultCode"] = 105 else: if data.get("deleteRecordCache"): delete_cache_file(recid, uid) existing_cache = False pending_changes = [] disabled_hp_changes = {} if read_only_mode: if data.has_key("recordRevision"): record_revision_ts = data["recordRevision"] record_xml = get_marcxml_of_revision(recid, record_revision_ts) record = create_record(record_xml)[0] record_revision = timestamp_to_revision(record_revision_ts) pending_changes = [] disabled_hp_changes = {} else: # a normal cacheless retrieval of a record record = get_bibrecord(recid) record_revision = get_record_last_modification_date(recid) pending_changes = [] disabled_hp_changes = {} cache_dirty = False mtime = 0 undo_list = [] redo_list = [] elif not existing_cache: record_revision, record = create_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) pending_changes = [] disabled_hp_changes = {} undo_list = [] redo_list = [] cache_dirty = False else: # TODO: This try except should be replaced with something nicer, # like an argument indicating if a new cache file is to # be created try: cache_dirty, record_revision, record, pending_changes, disabled_hp_changes, undo_list, redo_list = get_cache_file_contents( recid, uid ) touch_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) if not latest_record_revision(recid, record_revision) and get_record_revisions(recid) != (): # This sould prevent from using old cache in case of # viewing old version. If there are no revisions, # it means we should skip this step because this # is a new record response["cacheOutdated"] = True except: record_revision, record = create_cache_file(recid, uid) mtime = get_cache_mtime(recid, uid) pending_changes = [] disabled_hp_changes = {} cache_dirty = False undo_list = [] redo_list = [] if data["clonedRecord"]: response["resultCode"] = 9 else: response["resultCode"] = 3 revision_author = get_record_revision_author(recid, record_revision) last_revision_ts = revision_to_timestamp(get_record_last_modification_date(recid)) revisions_history = get_record_revision_timestamps(recid) number_of_physical_copies = get_number_copies(recid) bibcirc_details_URL = create_item_details_url(recid, ln) can_have_copies = can_record_have_physical_copies(recid) response["cacheDirty"], response["record"], response["cacheMTime"], response["recordRevision"], response[ "revisionAuthor" ], response["lastRevision"], response["revisionsHistory"], response["inReadOnlyMode"], response[ "pendingHpChanges" ], response[ "disabledHpChanges" ], response[ "undoList" ], response[ "redoList" ] = ( cache_dirty, record, mtime, revision_to_timestamp(record_revision), revision_author, last_revision_ts, revisions_history, read_only_mode, pending_changes, disabled_hp_changes, undo_list, redo_list, ) response["numberOfCopies"] = number_of_physical_copies response["bibCirculationUrl"] = bibcirc_details_URL response["canRecordHavePhysicalCopies"] = can_have_copies # Set tag format from user's session settings. try: tagformat_settings = session_param_get(req, "bibedit_tagformat") tagformat = tagformat_settings[recid] except KeyError: tagformat = CFG_BIBEDIT_TAG_FORMAT response["tagFormat"] = tagformat elif request_type == "submit": # Submit the record. Possible error situations: # - Missing cache file # - Cache file modified in other editor # - Record locked by other user # - Record locked by queue # - Invalid XML characters # If the cache is outdated cacheOutdated will be set to True in the # response. if not cache_exists(recid, uid): response["resultCode"] = 106 elif not get_cache_mtime(recid, uid) == data["cacheMTime"]: response["resultCode"] = 107 elif cache_expired(recid, uid) and record_locked_by_other_user(recid, uid): response["resultCode"] = 104 elif record_locked_by_queue(recid): response["resultCode"] = 105 else: try: tmp_result = get_cache_file_contents(recid, uid) record_revision = tmp_result[1] record = tmp_result[2] pending_changes = tmp_result[3] # disabled_changes = tmp_result[4] xml_record = print_rec(record) record, status_code, list_of_errors = create_record(xml_record) if status_code == 0: response["resultCode"], response["errors"] = 110, list_of_errors elif not data["force"] and not latest_record_revision(recid, record_revision): response["cacheOutdated"] = True else: save_xml_record(recid, uid) response["resultCode"] = 4 except: response["resultCode"] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV["error_wrong_cache_file_format"] elif request_type == "revert": revId = data["revId"] job_date = "%s-%s-%s %s:%s:%s" % re_revdate_split.search(revId).groups() revision_xml = get_marcxml_of_revision(recid, job_date) save_xml_record(recid, uid, revision_xml) if cache_exists(recid, uid): delete_cache_file(recid, uid) response["resultCode"] = 4 elif request_type == "cancel": # Cancel editing by deleting the cache file. Possible error situations: # - Cache file modified in other editor if cache_exists(recid, uid): if get_cache_mtime(recid, uid) == data["cacheMTime"]: delete_cache_file(recid, uid) response["resultCode"] = 5 else: response["resultCode"] = 107 else: response["resultCode"] = 5 elif request_type == "deleteRecord": # Submit the record. Possible error situations: # - Record locked by other user # - Record locked by queue # As the user is requesting deletion we proceed even if the cache file # is missing and we don't check if the cache is outdated or has # been modified in another editor. existing_cache = cache_exists(recid, uid) pending_changes = [] if has_copies(recid): response["resultCode"] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV["error_physical_copies_exist"] elif existing_cache and cache_expired(recid, uid) and record_locked_by_other_user(recid, uid): response["resultCode"] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV["error_rec_locked_by_user"] elif record_locked_by_queue(recid): response["resultCode"] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV["error_rec_locked_by_queue"] else: if not existing_cache: record_revision, record, pending_changes, deactivated_hp_changes, undo_list, redo_list = create_cache_file( recid, uid ) else: try: record_revision, record, pending_changes, deactivated_hp_changes, undo_list, redo_list = get_cache_file_contents( recid, uid )[ 1: ] except: record_revision, record, pending_changes, deactivated_hp_changes = create_cache_file(recid, uid) record_add_field(record, "980", " ", " ", "", [("c", "DELETED")]) undo_list = [] redo_list = [] update_cache_file_contents( recid, uid, record_revision, record, pending_changes, deactivated_hp_changes, undo_list, redo_list ) save_xml_record(recid, uid) delete_related_holdingpen_changes(recid) # we don't need any changes # related to a deleted record response["resultCode"] = 10 elif request_type == "deleteRecordCache": # Delete the cache file. Ignore the request if the cache has been # modified in another editor. if cache_exists(recid, uid) and get_cache_mtime(recid, uid) == data["cacheMTime"]: delete_cache_file(recid, uid) response["resultCode"] = 11 elif request_type == "prepareRecordMerge": # We want to merge the cache with the current DB version of the record, # so prepare an XML file from the file cache, to be used by BibMerge. # Possible error situations: # - Missing cache file # - Record locked by other user # - Record locked by queue # We don't check if cache is outdated (a likely scenario for this # request) or if it has been modified in another editor. if not cache_exists(recid, uid): response["resultCode"] = 106 elif cache_expired(recid, uid) and record_locked_by_other_user(recid, uid): response["resultCode"] = 104 elif record_locked_by_queue(recid): response["resultCode"] = 105 else: save_xml_record(recid, uid, to_upload=False, to_merge=True) response["resultCode"] = 12 return response