Пример #1
0
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.'
Пример #2
0
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.'
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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