def replace_text(record, tag, field_number, subfield_index):
     """Method for replacing the text, performed on
     all the matching fields."""
     #get the field value
     field_value = ""
     for field in record[tag]:
         if field[4] == field_number:
             subfields = field[0]
             (dummy_field_code, field_value) = subfields[subfield_index]
     replace_string = re.escape(self._value)
     for val in self._additional_values:
         replace_string += "|" + re.escape(val)
     #replace text
     new_value = re.sub(replace_string, self._new_value, field_value)
     #update the subfield if needed
     if new_value != field_value:
         bibrecord.record_modify_subfield(
             record,
             tag,
             self._subfield,
             new_value,
             subfield_index,
             field_position_global=field_number)
     else:
         #No modification ocurred, update modification counter
         self._modifications -= 1
Пример #2
0
def check_record(record,
                 source_field,
                 new_code,
                 pattern='',
                 subfield_filter=(None, None),
                 complement=False):
    """ Changes the code of a subfield to new_code """
    import re
    from invenio.bibrecord import record_modify_subfield
    assert len(source_field) == 6
    source_field = source_field.replace("_", " ")
    assert len(subfield_filter) == 2
    subfield_filter = tuple(subfield_filter)
    for pos, val in record.iterfield(source_field, subfield_filter):
        pattern_matches = re.search(pattern, val) if pattern else True
        if (pattern_matches and not complement) or \
           (complement and not pattern_matches):
            record_modify_subfield(record,
                                   source_field[:3],
                                   new_code,
                                   val,
                                   pos[2],
                                   field_position_local=pos[1])
            record.set_amended('move from %s to %s: %s' %
                               (source_field.replace(" ", "_"), new_code, val))
Пример #3
0
def check_record(record):
    """
    If 710__g contains 'for the' or 'on behalf of'
    check whether there is an author name.
    Split and clean collaboration.
    """
    from invenio.bibrecord import record_modify_subfield
    from invenio.bibrecord import record_add_field
    message = ""
    rec_modified = False
    rec_holdingpen = False
    for position, coll in record.iterfield("710__g"):
        new, author = cleancoll(coll)
        if new:
            message = "%s changed %s -> %s\n" % (message, coll, new)
            record_modify_subfield(record, "710", "g", new,
                position[2], field_position_local=position[1])
            rec_modified = True
            if author:
                message = "%s found author: %s in %s\n" % (message, author, coll)
                if record.has_key("100"):
                    akey = "700"
                else:
                    akey = "100"
                record_add_field(record, akey, ' ', ' ', '', [('a', author)])
                rec_holdingpen = True
    if rec_modified:
        record.set_amended(message)
        if rec_holdingpen:
            record.holdingpen = True
Пример #4
0
def crossref_normalize_name(record):
    """
    Changes the format of author's name (often with initials) to the proper,
    unified one, using bibauthor_name_utils tools
    @return: changed record
    """
    # pattern for removing the spaces between two initials
    pattern_initials = '([A-Z]\\.)\\s([A-Z]\\.)'
    # first, change the main author
    for field in record_get_field_instances(record, '100'):
        main_author = field[0][0][1]
        new_author = create_normalized_name(split_name_parts(main_author))
        # remove spaces between initials
        # two iterations are required
        for _ in range(2):
            new_author = re.sub(pattern_initials, '\g<1>\g<2>', new_author)
        position = field[4]
        record_modify_subfield(rec=record, tag='100', subfield_code='a', \
        value=new_author, subfield_position=0, field_position_global=position)

    # then, change additional authors
    for field in record_get_field_instances(record, '700'):
        author = field[0][0][1]
        new_author = create_normalized_name(split_name_parts(author))
        for _ in range(2):
            new_author = re.sub(pattern_initials, '\g<1>\g<2>', new_author)
        position = field[4]
        record_modify_subfield(rec=record, tag='700', subfield_code='a', \
            value=new_author, subfield_position=0, field_position_global=position)
Пример #5
0
def translate_fieldvalues_from_latex(record, tag, code='', encoding='utf-8'):
    """
    Given a record and field tag, this function will modify the record by
    translating the subfield values of found fields from LaTeX to chosen
    encoding for all the subfields with given code (or all if no code is given).

    @param record: record to modify, in BibRec style structure
    @type record: dict

    @param tag: tag of fields to modify
    @type tag: string

    @param code: restrict the translation to a given subfield code
    @type code: string

    @param encoding: scharacter encoding for the new value. Defaults to UTF-8.
    @type encoding: string
    """
    field_list = record_get_field_instances(record, tag)
    for field in field_list:
        subfields = field[0]
        subfield_index = 0
        for subfield_code, subfield_value in subfields:
            if code == '' or subfield_code == code:
                newvalue = translate_latex2unicode(subfield_value).encode(encoding)
                record_modify_subfield(record, tag, subfield_code, newvalue, \
                                       subfield_index, field_position_global=field[4])
            subfield_index += 1
Пример #6
0
def translate_fieldvalues_from_latex(record, tag, code='', encoding='utf-8'):
    """
    Given a record and field tag, this function will modify the record by
    translating the subfield values of found fields from LaTeX to chosen
    encoding for all the subfields with given code (or all if no code is given).

    @param record: record to modify, in BibRec style structure
    @type record: dict

    @param tag: tag of fields to modify
    @type tag: string

    @param code: restrict the translation to a given subfield code
    @type code: string

    @param encoding: scharacter encoding for the new value. Defaults to UTF-8.
    @type encoding: string
    """
    field_list = record_get_field_instances(record, tag)
    for field in field_list:
        subfields = field[0]
        subfield_index = 0
        for subfield_code, subfield_value in subfields:
            if code == '' or subfield_code == code:
                newvalue = translate_latex2unicode(subfield_value).encode(
                    encoding)
                record_modify_subfield(record, tag, subfield_code, newvalue, \
                                       subfield_index, field_position_global=field[4])
            subfield_index += 1
Пример #7
0
def crossref_normalize_name(record):
    """
    Changes the format of author's name (often with initials) to the proper,
    unified one, using bibauthor_name_utils tools
    @return: changed record
    """
    # pattern for removing the spaces between two initials
    pattern_initials = '([A-Z]\\.)\\s([A-Z]\\.)'
    # first, change the main author
    for field in record_get_field_instances(record, '100'):
        main_author = field[0][0][1]
        new_author = create_normalized_name(split_name_parts(main_author))
        # remove spaces between initials
        # two iterations are required
        for _ in range(2):
            new_author = re.sub(pattern_initials, r'\g<1>\g<2>', new_author)
        position = field[4]
        record_modify_subfield(rec=record, tag='100', subfield_code='a',
        value=new_author, subfield_position=0, field_position_global=position)

    # then, change additional authors
    for field in record_get_field_instances(record, '700'):
        author = field[0][0][1]
        new_author = create_normalized_name(split_name_parts(author))
        for _ in range(2):
            new_author = re.sub(pattern_initials, r'\g<1>\g<2>', new_author)
        position = field[4]
        record_modify_subfield(rec=record, tag='700', subfield_code='a',
            value=new_author, subfield_position=0, field_position_global=position)
Пример #8
0
def check_record(record, source_field, new_code, pattern, complement, subfield_filter):
    """ Changes the code of a subfield to new_code """
    import re
    from invenio.bibrecord import record_modify_subfield

    assert len(source_field) == 6
    source_field = source_field.replace("_", " ")
    for pos, val in record.iterfield(source_field, subfield_filter):
        pattern_matches = re.search(pattern, val)
        if (pattern_matches and not complement) or (complement and not pattern_matches):
            record_modify_subfield(record, source_field[:3], new_code, val, pos[2], field_position_local=pos[1])
            record.set_amended("move from %s to %s: %s" % (source_field.replace(" ", "_"), new_code, val))
Пример #9
0
def check_record(record):
    """
    Move additional texkeys from $$a to $$z 
    """
    from invenio.bibrecord import record_modify_subfield
    message = ""
    all_a_keys = list(record.iterfield("035__a", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__a", ("9", "INSPIRETeX")))
    if len(all_a_keys)>1:
        message = "Move additional TexKeys from a to z:"
        for position, value in all_a_keys[:-1]:
            message += " %s" % value
            record_modify_subfield(record, "035", "z", value, 
                position[2], field_position_local=position[1])
            record.set_amended(message)
 def replace_text(record, tag, field_number, subfield_index):
     """Method for replacing the text, performed on
     all the matching fields."""
     #get the field value
     field_value = ""
     for field in record[tag]:
         if field[4] == field_number:
             subfields = field[0]
             (field_code, field_value) = subfields[subfield_index]
     #replace text
     new_value = field_value.replace(self._value, self._new_value)
     #update the subfield
     bibrecord.record_modify_subfield(record, tag,
                                      self._subfield, new_value,
                                      subfield_index,
                             field_position_global=field_number)
Пример #11
0
def crossref_translate_title(record):
    """
    Convert the record's title to the Inspire specific abbreviation
    of the title (using JOURNALS knowledge base)
    @return: changed record
    """
    # probably there is only one 773 field
    # but just in case let's treat it as a list
    for field in record_get_field_instances(record, '773'):
        title = field[0][0][1]
        new_title = get_kbr_values("JOURNALS", title, searchtype='e')
        if new_title:
            # returned value is a list, and we need only the first value
            new_title = new_title[0][0]
            position = field[4]
            record_modify_subfield(rec=record, tag='773', subfield_code='p', \
            value=new_title, subfield_position=0, field_position_global=position)
Пример #12
0
def crossref_translate_title(record):
    """
    Convert the record's title to the Inspire specific abbreviation
    of the title (using JOURNALS knowledge base)
    @return: changed record
    """
    # probably there is only one 773 field
    # but just in case let's treat it as a list
    for field in record_get_field_instances(record, '773'):
        title = field[0][0][1]
        new_title = get_kbr_values("JOURNALS", title, searchtype='e')
        if new_title:
            # returned value is a list, and we need only the first value
            new_title = new_title[0][0]
            position = field[4]
            record_modify_subfield(rec=record, tag='773', subfield_code='p', \
            value=new_title, subfield_position=0, field_position_global=position)
Пример #13
0
 def process_field(self, record, tag, field_number):
     """@see: BaseSubfieldCommand.process_field"""
     action = lambda record, tag, field_number, subfield_index: \
                 bibrecord.record_modify_subfield(record, tag,
                                                  self._subfield,
                                                  self._value,
                                                  subfield_index,
                                   field_position_global=field_number)
     self._perform_on_all_matching_subfields(record, tag, field_number,
                                             action)
Пример #14
0
 def replace_text(record, tag, field_number, subfield_index):
     """Method for replacing the text, performed on
     all the matching fields."""
     #get the field value
     field_value = ""
     for field in record[tag]:
         if field[4] == field_number:
             subfields = field[0]
             (field_code, field_value) = subfields[subfield_index]
     #replace text
     new_value = field_value.replace(self._value, self._new_value)
     #update the subfield
     bibrecord.record_modify_subfield(
         record,
         tag,
         self._subfield,
         new_value,
         subfield_index,
         field_position_global=field_number)
Пример #15
0
def check_record(record):
    """
    Move additional texkeys from $$a to $$z 
    """
    from invenio.bibrecord import record_modify_subfield
    message = ""
    all_a_keys = list(record.iterfield("035__a", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__a", ("9", "INSPIRETeX")))
    if len(all_a_keys) > 1:
        message = "Move additional TexKeys from a to z:"
        for position, value in all_a_keys[:-1]:
            message += " %s" % value
            record_modify_subfield(record,
                                   "035",
                                   "z",
                                   value,
                                   position[2],
                                   field_position_local=position[1])
            record.set_amended(message)
Пример #16
0
def check_record(record):
    """
    Move one texkey from $$z to $$a if there is no $$a
    """
    from invenio.bibrecord import record_modify_subfield
    message = ""
    all_a_keys = list(record.iterfield("035__a", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__a", ("9", "INSPIRETeX")))
    all_z_keys = list(record.iterfield("035__z", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__z", ("9", "INSPIRETeX")))

    if all_a_keys:
        pass
    elif all_z_keys:
        position, value = all_z_keys[0]
        message = "Move TexKey from z to a: %s" % value
        record_modify_subfield(record, "035", "a", value,
           position[2], field_position_local=position[1])
        record.set_amended(message)
 def process_field(self, record, tag, field_number):
     """@see: BaseSubfieldCommand.process_field"""
     action = lambda record, tag, field_number, subfield_index: \
                 bibrecord.record_modify_subfield(record, tag,
                                                  self._subfield,
                                                  self._value,
                                                  subfield_index,
                                   field_position_global=field_number)
     self._perform_on_all_matching_subfields(record,
                                             tag,
                                             field_number,
                                             action)
Пример #18
0
 def replace_text(record, tag, field_number, subfield_index):
     """Method for replacing the text, performed on
     all the matching fields."""
     #get the field value
     field_value = ""
     for field in record[tag]:
         if field[4] == field_number:
             subfields = field[0]
             (dummy_field_code, field_value) = subfields[subfield_index]
     replace_string = re.escape(self._value)
     for val in self._additional_values:
         replace_string += "|" + re.escape(val)
     #replace text
     new_value = re.sub(replace_string, self._new_value, field_value)
     #update the subfield if needed
     if new_value != field_value:
         bibrecord.record_modify_subfield(record, tag,
                                         self._subfield, new_value,
                                         subfield_index,
                                         field_position_global=field_number)
     else:
         #No modification ocurred, update modification counter
         self._modifications -= 1
Пример #19
0
def check_record(record):
    """
    Move one texkey from $$z to $$a if there is no $$a
    """
    from invenio.bibrecord import record_modify_subfield
    message = ""
    all_a_keys = list(record.iterfield("035__a", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__a", ("9", "INSPIRETeX")))
    all_z_keys = list(record.iterfield("035__z", ("9", "SPIRESTeX"))) \
               + list(record.iterfield("035__z", ("9", "INSPIRETeX")))

    if all_a_keys:
        pass
    elif all_z_keys:
        position, value = all_z_keys[0]
        message = "Move TexKey from z to a: %s" % value
        record_modify_subfield(record,
                               "035",
                               "a",
                               value,
                               position[2],
                               field_position_local=position[1])
        record.set_amended(message)
Пример #20
0
def check_record(record):
    """ Move 502 $$a, $$b, $$c to $$b, $$c, $$d """
    from invenio.bibrecord import record_modify_subfield

    degrees = ['Laurea', 'Diploma', 'PhD', 'Bachelor', 'Habilitation', 'Thesis', 'Master']
    new_code = {'a':'b', 'b':'c', 'c':'d'}
    message = ""
    tag = '502'
    if not record.has_key(tag):
        return
    for (local_position, field_obj) in enumerate(record[tag]):
        degree_ok = True
        year_ok = False
        mess = ''
        for subfield_code, value in field_obj[0]:
            if subfield_code == 'a' and not value in degrees:
                degree_ok = False
            if subfield_code == 'c':
                try:
                    year = int(value[:4])
                    if year > 1300 and year < 2050:
                        year_ok = True
                except:
                    pass
        if year_ok and degree_ok:
            for subfield_position, subfield_tuple in enumerate(field_obj[0]):
                subfield_code, value = subfield_tuple
                if new_code.has_key(subfield_code):
                    record_modify_subfield(record, tag,
                                           new_code[subfield_code], value,
                                           subfield_position,
                                           field_position_local=local_position)
                    mess = 'Updated %s , ' % record[tag][local_position][0]
        message += mess
    if message:
        record.set_amended(message)
Пример #21
0
def perform_request_update_record(request_type, recid, uid, cacheMTime, data, \
                                  hpChanges, undoRedoOp, isBulk=False):
    """Handle record update requests like adding, modifying, moving or deleting
    of fields or subfields. Possible common error situations:
    - Missing cache file
    - Cache file modified in other editor
    Explanation of some parameters:
       undoRedoOp - Indicates in "undo"/"redo"/undo_descriptor operation is
                    performed by a current request.
    """

    response = {}

    if not cache_exists(recid, uid):
        response['resultCode'] = 106
    elif not get_cache_mtime(recid, uid) == cacheMTime and isBulk == False:
        # In case of a bulk request, the changes are deliberately performed
        # imemdiately one after another
        response['resultCode'] = 107
    else:
        try:
            record_revision, record, pending_changes, deactivated_hp_changes, \
                undo_list, redo_list = get_cache_file_contents(recid, uid)[1:]
        except:
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV[ \
                'wrong_cache_file_format']
            return response

        # process all the Holding Pen changes operations ... regardles the
        # request type
#        import rpdb2;
#        rpdb2.start_embedded_debugger('password', fAllowRemote=True)
        if hpChanges.has_key("toDisable"):
            for changeId in hpChanges["toDisable"]:
                pending_changes[changeId]["applied_change"] = True

        if hpChanges.has_key("toEnable"):
            for changeId in hpChanges["toEnable"]:
                pending_changes[changeId]["applied_change"] = False

        if hpChanges.has_key("toOverride"):
            pending_changes = hpChanges["toOverride"]

        if hpChanges.has_key("changesetsToDeactivate"):
            for changesetId in hpChanges["changesetsToDeactivate"]:
                deactivated_hp_changes[changesetId] = True

        if hpChanges.has_key("changesetsToActivate"):
            for changesetId in hpChanges["changesetsToActivate"]:
                deactivated_hp_changes[changesetId] = False

        # processing the undo/redo entries
        if undoRedoOp == "undo":
            try:
                redo_list = [undo_list[-1]] + redo_list
                undo_list = undo_list[:-1]
            except:
                raise Exception("An exception occured when undoing previous" + \
                                " operation. Undo list: " + str(undo_list) + \
                                " Redo list " + str(redo_list))
        elif undoRedoOp == "redo":
            try:
                undo_list = undo_list + [redo_list[0]]
                redo_list = redo_list[1:]
            except:
                raise Exception("An exception occured when redoing previous" + \
                                " operation. Undo list: " + str(undo_list) + \
                                " Redo list " + str(redo_list))
        else:
            # This is a genuine operation - we have to add a new descriptor
            # to the undo list and cancel the redo unless the operation is
            # a bulk operation
            if undoRedoOp != None:
                undo_list = undo_list + [undoRedoOp]
                redo_list = []
            else:
                assert isBulk == True

        field_position_local = data.get('fieldPosition')
        if field_position_local is not None:
            field_position_local = int(field_position_local)
        if request_type == 'otherUpdateRequest':
            # An empty request. Might be useful if we want to perform
            # operations that require only the actions performed globally,
            # like modifying the holdingPen changes list
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV[ \
                'editor_modifications_changed']
        elif request_type == 'deactivateHoldingPenChangeset':
            # the changeset has been marked as processed ( user applied it in
            # the editor). Marking as used in the cache file.
            # CAUTION: This function has been implemented here because logically
            #          it fits with the modifications made to the cache file.
            #          No changes are made to the Holding Pen physically. The
            #          changesets are related to the cache because we want to
            #          cancel the removal every time the cache disappears for
            #          any reason
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV[ \
                'disabled_hp_changeset']
        elif request_type == 'addField':
            if data['controlfield']:
                record_add_field(record, data['tag'],
                                 controlfield_value=data['value'])
                response['resultCode'] = 20
            else:
                record_add_field(record, data['tag'], data['ind1'],
                                 data['ind2'], subfields=data['subfields'],
                                 field_position_local=field_position_local)
                response['resultCode'] = 21

        elif request_type == 'addSubfields':
            subfields = data['subfields']
            for subfield in subfields:
                record_add_subfield_into(record, data['tag'], subfield[0],
                    subfield[1], subfield_position=None,
                    field_position_local=field_position_local)
            if len(subfields) == 1:
                response['resultCode'] = 22
            else:
                response['resultCode'] = 23
        elif request_type == 'addFieldsSubfieldsOnPositions':
            #1) Sorting the fields by their identifiers
            fieldsToAdd = data['fieldsToAdd']
            subfieldsToAdd = data['subfieldsToAdd']
            for tag in fieldsToAdd.keys():
                positions = fieldsToAdd[tag].keys()
                positions.sort()
                for position in positions:
                    # now adding fields at a position

                    isControlfield = (len(fieldsToAdd[tag][position][0]) == 0)
                    # if there are n subfields, this is a control field
                    if isControlfield:
                        controlfieldValue = fieldsToAdd[tag][position][3]
                        record_add_field(record, tag, field_position_local = \
                                             int(position), \
                                             controlfield_value = \
                                                 controlfieldValue)
                    else:
                        subfields = fieldsToAdd[tag][position][0]
                        ind1 = fieldsToAdd[tag][position][1]
                        ind2 = fieldsToAdd[tag][position][2]
                        record_add_field(record, tag, ind1, ind2, subfields = \
                                             subfields, field_position_local = \
                                                int(position))
            # now adding the subfields
            for tag in subfieldsToAdd.keys():
                for fieldPosition in subfieldsToAdd[tag].keys(): #now the fields
                                                          #order not important !
                    subfieldsPositions = subfieldsToAdd[tag][fieldPosition]. \
                                           keys()
                    subfieldsPositions.sort()
                    for subfieldPosition in subfieldsPositions:
                        subfield = subfieldsToAdd[tag][fieldPosition]\
                            [subfieldPosition]
                        record_add_subfield_into(record, tag, subfield[0], \
                                                 subfield[1], \
                                                 subfield_position = \
                                                     int(subfieldPosition), \
                                                 field_position_local = \
                                                     int(fieldPosition))

            response['resultCode'] = \
                CFG_BIBEDIT_AJAX_RESULT_CODES_REV['added_positioned_subfields']

        elif request_type == 'modifyField': # changing the field structure
            # first remove subfields and then add new... change the indices
            subfields = data['subFields'] # parse the JSON representation of
                                          # the subfields here

            new_field = create_field(subfields, data['ind1'], data['ind2'])
            record_replace_field(record, data['tag'], new_field, \
                field_position_local = data['fieldPosition'])
            response['resultCode'] = 26

        elif request_type == 'modifyContent':
            if data['subfieldIndex'] != None:
                record_modify_subfield(record, data['tag'],
                    data['subfieldCode'], data['value'],
                    int(data['subfieldIndex']),
                    field_position_local=field_position_local)
            else:
                record_modify_controlfield(record, data['tag'], data["value"],
                  field_position_local=field_position_local)
            response['resultCode'] = 24

        elif request_type == 'moveSubfield':
            record_move_subfield(record, data['tag'],
                int(data['subfieldIndex']), int(data['newSubfieldIndex']),
                field_position_local=field_position_local)
            response['resultCode'] = 25

        elif request_type == 'moveField':
            if data['direction'] == 'up':
                final_position_local = field_position_local-1
            else: # direction is 'down'
                final_position_local = field_position_local+1
            record_move_fields(record, data['tag'], [field_position_local],
                final_position_local)
            response['resultCode'] = 32

        elif request_type == 'deleteFields':
            to_delete = data['toDelete']
            deleted_fields = 0
            deleted_subfields = 0
            for tag in to_delete:
                #Sorting the fields in a edcreasing order by the local position!
                fieldsOrder = to_delete[tag].keys()
                fieldsOrder.sort(lambda a, b: int(b) - int(a))
                for field_position_local in fieldsOrder:
                    if not to_delete[tag][field_position_local]:
                        # No subfields specified - delete entire field.
                        record_delete_field(record, tag,
                            field_position_local=int(field_position_local))
                        deleted_fields += 1
                    else:
                        for subfield_position in \
                                to_delete[tag][field_position_local][::-1]:
                            # Delete subfields in reverse order (to keep the
                            # indexing correct).
                            record_delete_subfield_from(record, tag,
                                int(subfield_position),
                                field_position_local=int(field_position_local))
                            deleted_subfields += 1
            if deleted_fields == 1 and deleted_subfields == 0:
                response['resultCode'] = 26
            elif deleted_fields and deleted_subfields == 0:
                response['resultCode'] = 27
            elif deleted_subfields == 1 and deleted_fields == 0:
                response['resultCode'] = 28
            elif deleted_subfields and deleted_fields == 0:
                response['resultCode'] = 29
            else:
                response['resultCode'] = 30
        response['cacheMTime'], response['cacheDirty'] = \
            update_cache_file_contents(recid, uid, record_revision, record, \
                                       pending_changes, \
                                       deactivated_hp_changes, \
                                       undo_list, redo_list), \
            True

    return response
Пример #22
0
def perform_request_update_record(request_type, recid, uid, cacheMTime, data, changeApplied, isBulk=False):
    """Handle record update requests like adding, modifying, moving or deleting
    of fields or subfields. Possible common error situations:
    - Missing cache file
    - Cache file modified in other editor
    """

    response = {}

    if not cache_exists(recid, uid):
        response['resultCode'] = 106
    elif not get_cache_mtime(recid, uid) == cacheMTime and isBulk == False:
        # In case of a bulk request, the changes are deliberately performed imemdiately one after another
        response['resultCode'] = 107
    else:
        try:
            record_revision, record, pending_changes, desactivated_hp_changes = get_cache_file_contents(recid, uid)[1:]
        except:
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV['wrong_cache_file_format']
            return response;

        if changeApplied != -1:
            pending_changes = pending_changes[:changeApplied] + pending_changes[changeApplied+1:]

        field_position_local = data.get('fieldPosition')
        if field_position_local is not None:
            field_position_local = int(field_position_local)
        if request_type == 'overrideChangesList':
            pending_changes = data['newChanges']
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV['editor_modifications_changed']
        elif request_type == 'removeChange':
            #the change is removed automatically by passing the changeApplied parameter
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV['editor_modifications_changed']
        elif request_type == 'desactivateHoldingPenChangeset':
            # the changeset has been marked as processed ( user applied it in the editor)
            # marking as used in the cache file
            # CAUTION: This function has been implemented here because logically it fits
            #          with the modifications made to the cache file. No changes are made to the
            #          Holding Pen physically. The changesets are related to the cache because
            #          we want to cancel the removal every time the cache disappears for any reason
            desactivated_hp_changes[data.get('desactivatedChangeset')] = True;
            response['resultCode'] = CFG_BIBEDIT_AJAX_RESULT_CODES_REV['disabled_hp_changeset']
        elif request_type == 'addField':
            if data['controlfield']:
                record_add_field(record, data['tag'],
                                 controlfield_value=data['value'])
                response['resultCode'] = 20
            else:
                record_add_field(record, data['tag'], data['ind1'],
                                 data['ind2'], subfields=data['subfields'],
                                 field_position_local=field_position_local)
                response['resultCode'] = 21

        elif request_type == 'addSubfields':
            subfields = data['subfields']
            for subfield in subfields:
                record_add_subfield_into(record, data['tag'], subfield[0],
                    subfield[1], subfield_position=None,
                    field_position_local=field_position_local)
            if len(subfields) == 1:
                response['resultCode'] = 22
            else:
                response['resultCode'] = 23
        elif request_type == 'modifyField': # changing the field structure
            # first remove subfields and then add new... change the indices
            subfields = data['subFields'] # parse the JSON representation of the subfields here

            new_field = create_field(subfields, data['ind1'], data['ind2']);
            record_replace_field(record, data['tag'], new_field, field_position_local = data['fieldPosition'])
            response['resultCode'] = 26
            #response['debuggingValue'] = data['subFields'];

        elif request_type == 'modifyContent':
            if data['subfieldIndex'] != None:
                record_modify_subfield(record, data['tag'],
                    data['subfieldCode'], data['value'],
                    int(data['subfieldIndex']),
                    field_position_local=field_position_local)
            else:
                record_modify_controlfield(record, data['tag'], data["value"],
                  field_position_local=field_position_local)
            response['resultCode'] = 24

        elif request_type == 'moveSubfield':
            record_move_subfield(record, data['tag'],
                int(data['subfieldIndex']), int(data['newSubfieldIndex']),
                field_position_local=field_position_local)
            response['resultCode'] = 25

        elif request_type == 'moveField':
            if data['direction'] == 'up':
                final_position_local = field_position_local-1
            else: # direction is 'down'
                final_position_local = field_position_local+1
            record_move_fields(record, data['tag'], [field_position_local],
                final_position_local)
            response['resultCode'] = 32

        elif request_type == 'deleteFields':
            to_delete = data['toDelete']
            deleted_fields = 0
            deleted_subfields = 0
            for tag in to_delete:
                # Sorting the fields in a edcreasing order by the local position !
                fieldsOrder = to_delete[tag].keys()
                fieldsOrder.sort(lambda a,b: int(b)-int(a))
                for field_position_local in fieldsOrder:
                    if not to_delete[tag][field_position_local]:
                        # No subfields specified - delete entire field.
                        record_delete_field(record, tag,
                            field_position_local=int(field_position_local))
                        deleted_fields += 1
                    else:
                        for subfield_position in \
                                to_delete[tag][field_position_local][::-1]:
                            # Delete subfields in reverse order (to keep the
                            # indexing correct).
                            record_delete_subfield_from(record, tag,
                                int(subfield_position),
                                field_position_local=int(field_position_local))
                            deleted_subfields += 1
            if deleted_fields == 1 and deleted_subfields == 0:
                response['resultCode'] = 26
            elif deleted_fields and deleted_subfields == 0:
                response['resultCode'] = 27
            elif deleted_subfields == 1 and deleted_fields == 0:
                response['resultCode'] = 28
            elif deleted_subfields and deleted_fields == 0:
                response['resultCode'] = 29
            else:
                response['resultCode'] = 30
        response['cacheMTime'], response['cacheDirty'] = \
            update_cache_file_contents(recid, uid, record_revision, record, \
                                       pending_changes, desactivated_hp_changes), \
            True

    return response
Пример #23
0
    def update_subfields(self,
                         fields,
                         pattern=None,
                         replace=None,
                         new_code=None,
                         complement=False,
                         subfield_filter=(None, None),
                         count=0):
        """
        Update subfield - various combinations:
        :param fields: Field(s) to make the substitution on
        :param pattern: Regular expression to look for (None = change all)
        :param replace: String to substitute. (None = keep value)
               Supports backreferences, unless complement = True
        :param new_code: Move to new subfield code (None = don't move)
        :param complement: Change fields not matching pattern (False)
        :param subfield_filter: Apply only to fields with additional (code, filter_value)
        :param count: Maximum number of replacements to make (0 = unlimited)

        Examples:
        update_subfields(fields=['035__a', ], pattern='^[A-Za-z]+:[12][0-9]{3}[a-z]{2,3}$',
                    new_code='z', complement=True, subfield_filter=('9', 'INSPIRETeX'))
            moves texkeys with wrong syntax to $$z
            035__ $$9INSPIRETeX$$a:2015fwa
            ->
            035__ $$9INSPIRETeX$$z:2015fwa

        update_subfields(fields=['100__i','700__i'], pattern='[jJ][aA][cC][oO][wW]\D*',
                         replace='JACoW-', new_code='j')
            moves corrected JACoW-IDs from $$i to $$j
            700__ $$iJACoW-00012345
            ->
            700__ $$jJACoW-00012345
        """

        import re

        for pos, val in self.iterfields(fields, subfield_filter):
            source_field = pos[0]
            message = source_field[0:5]
            if pattern:
                if replace:
                    if complement:
                        new_val = replace
                        pattern_matches = re.search(pattern, val)
                    else:
                        new_val = re.sub(pattern, replace, val, count)
                        if new_val == val:
                            pattern_matches = re.search(pattern, val)
                        else:
                            pattern_matches = True
                else:
                    new_val = val
                    pattern_matches = re.search(pattern, val)
            else:
                pattern_matches = True
                if replace:
                    new_val = replace
                else:
                    new_val = val

            if new_code:
                message += ': move from %s to %s' % (source_field[5], new_code)
            else:
                new_code = source_field[5]

            if not new_val == val:
                message += ': replace %s by %s' % (val, new_val)
            else:
                message += ': %s' % (val)

            if bool(pattern_matches) != bool(complement):
                record_modify_subfield(self,
                                       source_field[0:3],
                                       new_code,
                                       new_val,
                                       pos[2],
                                       field_position_local=pos[1])
                self.set_amended(message)