def mf_do_nothing( cls, record_instance_IN, merge_from_person_IN, merge_into_person_IN, logger_name_IN = None, *args, **kwargs ): ''' merge function, does nothing. ''' # return reference status_OUT = StatusContainer() # declare variables me = "mf_do_nothing" debug_message = "" my_logger_name = "" # set logger name. if ( ( logger_name_IN is not None ) and ( logger_name_IN != "" ) ): # got one - use it. my_logger_name = logger_name_IN else: # not set. Use default. my_logger_name = cls.LOGGER_NAME #-- END check to see if loger name passed in. --# debug_message = "Doing nothing with record: " + str( record_instance_IN ) + "; merge from person = " + str( merge_from_person_IN ) + "; merge into person = " + str( merge_into_person_IN ) LoggingHelper.output_debug( debug_message, method_IN = me, logger_name_IN = my_logger_name ) # init status. status_OUT = status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) return status_OUT
def build_index_info( self, *args, **kwargs ): ''' Creates any helpful derived information on this index that can be used for processing. Includes: - self.m_coder_id_to_instance_map - map coder's User ID to their User instance. - self.m_coder_id_to_priority_map - map coder's User ID to their priority. - self.m_prioritized_coder_list - list of coder User instances for this index, in order of their priority, from highest to lowest. Postconditions: Returns StatusContainer. ''' # return reference status_OUT = StatusContainer() # declare variables me = "build_index_info" status_message = None coder_info_map = None coder_user_id = None coder_info = None coder_list = None # init status status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) # ! ----> clear out existing derived information self.m_coder_id_to_instance_map = {} self.m_coder_id_to_priority_map = {} self.m_prioritized_coder_list = None # ! ----> loop over coder info records. coder_info_map = self.get_coder_id_to_info_map() for coder_user_id, coder_info in six.iteritems( coder_info_map ): # update information for current coder: # ! --------> update id-to-instance map # ! --------> update id-to-priority map self.update_index_info_for_coder( coder_info ) #-- END loop over coder info records --# # ! ----> rebuild coder list for index. coder_list = self.get_prioritized_coder_list( rebuild_IN = True ) return status_OUT
def set_index_to_info_map( self, map_IN, *args, **kwargs ): ''' Accepts index_to_info_map, stores it internally. ''' # return reference status_OUT = StatusContainer() # declare variables me = "set_index_to_info_map" # init status status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) # store whatever is passed in. self.m_index_to_info_map = map_IN return status_OUT
def set_coder_priority( self, coder_id_IN, priority_IN, *args, **kwargs ): ''' Accepts a coder User ID, an integer priority for that coder. Checks to make sure coder ID and priority are passed in. If so, adds entry to map of coder IDs to priorities for the coder. Returns StatusContainer instance. ''' # return reference status_OUT = StatusContainer() # declare variables me = "set_coder_priority" coder_to_priority_dict = {} coder_index = -1 index_priority_map = {} status_message = "" # init status status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) # got a coder ID? if ( ( coder_id_IN is not None ) and ( isinstance( coder_id_IN, six.integer_types ) == True ) and ( coder_id_IN > 0 ) ): # got a coder ID - got a priority? if ( ( priority_IN is not None ) and ( isinstance( priority_IN, six.integer_types ) == True ) and ( priority_IN > 0 ) ): # add to coder_to_priority_dict coder_to_priority_dict = self.get_coder_id_to_priority_map() coder_to_priority_dict[ coder_id_IN ] = priority_IN else: # ERROR - must have a priority passed in. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) status_message = "In " + me + ": No coder priority passed in ( value = \"" + str( priority_IN ) + "\" ), so can't set priority." status_OUT.add_message( status_message ) #-- END check to see if priority passed in --# else: # ERROR - must have a coder ID passed in. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) status_message = "In " + me + ": No coder User ID passed in ( value = \"" + str( coder_id_IN ) + "\" ), so can't set priority." status_OUT.add_message( status_message ) #-- END check to see if coder User ID passed in. --# return status_OUT
def copy_m2m_values( cls, attr_name_IN, copy_from_IN, copy_to_IN, *args, **kwargs ): ''' Accepts the name of the ManyToMany (m2m) field you want to copy from one instance of a given model class to another, the instance you want to copy from, and the instance you want to copy to. Loops over items in the from instance for the field and adds each to the field in the to instance. If error returns status of error and message that describes the problem. Postconditions: the copy-to instance is updated, but not saved. If error returned, the copy-to instance is not updated. ''' # return reference status_OUT = None # declare variables me = "copy_m2m_values" status_message = "" copy_m2m_from = None copy_m2m_to = None m2m_qs = None m2m_instance = None # init status container status_OUT = StatusContainer() status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) # got an attribute name? if ( ( attr_name_IN is not None ) and ( attr_name_IN != "" ) ): # got copy_from_IN instance? if ( copy_from_IN is not None ): # got copy_to_IN instance? if ( copy_to_IN is not None ): # ! ----> ManyToMany - topics copy_m2m_from = getattr( copy_from_IN, attr_name_IN ) copy_m2m_to = getattr( copy_to_IN, attr_name_IN ) # loop over existing items m2m_qs = copy_m2m_from.all() for m2m_instance in m2m_qs: # add to new. copy_m2m_to.add( m2m_instance ) #-- END loop over m2m instances --# else: # error - must have attribute name. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) # add a status message status_message = "No instance passed in to copy TO." status_OUT.add_message( status_message ) #-- END check to see if copy_to_IN --# else: # error - must have attribute name. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) # add a status message status_message = "No instance passed in to copy FROM." status_OUT.add_message( status_message ) #-- END check to see if copy_from_IN --# else: # error - must have attribute name. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) # add a status message status_message = "No attribute name passed in ( " + str( attr_name_IN ) + " )" status_OUT.add_message( status_message ) #-- END check for attribute name --# #-- END class method copy_m2m_values() --# #-- END class DjangoModelHelper --#
def merge_persons( cls, from_person_id_list_IN, into_person_id_IN, do_updates_IN = True, delete_from_IN = False, logger_name_IN = None, *args, **kwargs ): ''' Have to account for references: - reliability_names_set - article_author_set - person_organization_set - sourcenet_article_author_original_person_set - person_newspaper_set - alternate_author_match_set - sourcenet_article_subject_original_person_set - person_external_uuid_set - alternate_name_set - reliability_ties_to_set - reliability_ties_from_set - alternate_subject_match_set - article_subject_set ''' # return reference status_OUT = StatusContainer() # declare variables me = "switch_persons_in_data" debug_message = "" my_logger_name = "" status_message = "" from_person_id = -1 from_person_instance = None reverse_lookup_attribute_names = None attribute_name = "" reverse_lookup_attribute = None reverse_lookup_qs = None record_merge_status = None persons_to_delete_list = [] delete_person_id = -1 delete_person = None # set logger name. if ( ( logger_name_IN is not None ) and ( logger_name_IN != "" ) ): # got one - use it. my_logger_name = logger_name_IN else: # not set. Use default. my_logger_name = cls.LOGGER_NAME #-- END check to see if loger name passed in. --# # init status container status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) # get list of person "*_set"s. # got a list passed in? if ( ( from_person_id_list_IN is not None ) and ( isinstance( from_person_id_list_IN, list ) == True ) and ( len( from_person_id_list_IN ) > 0 ) ): # make sure there is a person to merge to... if ( ( into_person_id_IN is not None ) and ( isinstance( into_person_id_IN, six.integer_types ) == True ) and ( into_person_id_IN > 0 ) ): # loop over person list. for from_person_id in from_person_id_list_IN: # get person instance. from_person_instance = Person.objects.get( pk = from_person_id ) # get list of names of reverse lookup sets. reverse_lookup_attribute_names = cls.get_person_related_set_attribute_names() # loop over attribute names. For each, get QuerySet of # related records, then call merge_records(). for attribute_name in reverse_lookup_attribute_names: # get model reverse lookup set for FROM Person. reverse_lookup_attribute = getattr( from_person_instance, attribute_name ) # get QuerySet reverse_lookup_qs = reverse_lookup_attribute.all() # call merge_records() record_merge_status = cls.merge_records( reverse_lookup_qs, from_person_id, into_person_id_IN, do_delete_IN = delete_from_IN, logger_name_IN = logger_name_IN ) #-- END loop over reverse lookup set names. --# # finally, do we delete the from person? if ( delete_from_IN == True ): # yes. Add ID to list. persons_to_delete_list.append( from_person_instance ) #-- END check to see if we delete. --# #-- END loop over persons. --# # are we deleting? if ( delete_from_IN == True ): # anything in the list of person IDs to delete? if ( ( persons_to_delete_list is not None ) and ( isinstance( persons_to_delete_list, list ) == True ) and ( len( persons_to_delete_list ) > 0 ) ): # yup. Delete them. for delete_person in persons_to_delete_list: # delete. status_OUT.add_message( "Deleting Person: " + str( delete_person ) ) delete_person.delete() #-- END loop over persons to delete. --# #-- END check to see if we delete anyone. --# #-- END check to see if we are deleting. --# # status is success. status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) else: # no person ID to merge into - nothing to merge. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) status_message = "No person ID to merge into, so nothing to merge." status_OUT.add_message( status_message ) #-- END check to see if ID to merge into. --# else: # no list of from person IDs - nothing to merge. status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) status_message = "No person IDs in list of persons to merge passed in, so nothing to merge." status_OUT.add_message( status_message ) #-- END check to see if list of person to merge. --# return status_OUT
def merge_records( cls, record_qs_IN, merge_from_id_IN, merge_into_id_IN, do_delete_IN = False, logger_name_IN = None, *args, **kwargs ): ''' accepts a QuerySet of related records of a specific type for the person we are merging INTO another person (the FROM user). Loops over them to get a list of their IDs, so we can interact with them independent of the RelatedManager (not sure if this is necessary, but an overabundance of caution). For the type, uses a dictionary that maps class name to function pointers to find and call a function to merge that class's rows. Then, we loop over the rows once again to delete() each of them. preconditions: Deletes the merge_from person's data. BE CAREFUL. postconditions: merges all the rows from the merge from person into the rows that belong to the merge into person, then deletes the rows for the merge_from person. Again, deletes the merge_from person's data. BE CAREFUL. ''' # return reference status_OUT = StatusContainer() # declare variables me = "delete_records" my_logger_name = "" debug_message = "" from_person = None into_person = None current_record = None related_class = None related_id = "" related_id_list = [] merge_function = None related_qs = None related_record = None merge_status = None # set logger name. if ( ( logger_name_IN is not None ) and ( logger_name_IN != "" ) ): # got one - use it. my_logger_name = logger_name_IN else: # not set. Use default. my_logger_name = cls.LOGGER_NAME #-- END check to see if loger name passed in. --# # got a QuerySet? if ( isinstance( record_qs_IN, QuerySet ) == True ): # yes. anything in it? if ( record_qs_IN.count() > 0 ): debug_message = "QuerySet IS NOT empty." LoggingHelper.output_debug( debug_message, method_IN = me, logger_name_IN = my_logger_name ) # load Person instances for the from and the into. from_person = Person.objects.get( pk = merge_from_id_IN ) into_person = Person.objects.get( pk = merge_into_id_IN ) # loop over records in related set to get class and get IDs. # Don't make changes here yet. Wait so we aren't looping # inside a related for current_record in record_qs_IN: debug_message = "Current record: " + str( current_record ) LoggingHelper.output_debug( debug_message, method_IN = me, indent_with_IN = "====> ", logger_name_IN = my_logger_name ) # is related class set? if ( related_class is None ): related_class = type( current_record ) #-- END check to see if we have related class --# # get ID and add it to list. record_id = current_record.id record_id_list.append( record_id ) #-- END loop over records to get ID list. --# # look up the record merge function for this class. merge_function = cls.get_merge_function( related_class ) # now, use the class to get a result set of the same rows that # is not related to one of the persons. related_qs = related_class.objects.filter( id__in = record_id_list ) # in theory, we now have a QuerySet of the related records for # the person we are merging from. Loop and call the merge # function on each. for related_record in related_qs: # call the merge_function (just merge, don't delete). merge_status = merge_function( related_record, from_person, into_person ) #-- END merge loop --# # do we delete? if ( do_delete_IN == True ): # OK... for related_record in related_qs: # delete() related_record.delete() debug_message = "DELETED!!!" LoggingHelper.output_debug( debug_message, method_IN = me, indent_with_IN = "========> ", logger_name_IN = my_logger_name ) #-- END merge loop --# #-- END check to see if we delete. --# # status is success. status_OUT.set_status_code( StatusContainer.STATUS_CODE_SUCCESS ) else: debug_message = "QuerySet is EMPTY." LoggingHelper.output_debug( debug_message, method_IN = me, indent_with_IN = "====> ", logger_name_IN = my_logger_name ) #-- END check to see if anything in list. --# else: debug_message = "record_qs_IN is not a QuerySet: " + str( record_qs_IN ) LoggingHelper.output_debug( debug_message, method_IN = me, indent_with_IN = "====> ", logger_name_IN = my_logger_name ) status_OUT.set_status_code( StatusContainer.STATUS_CODE_ERROR ) status_OUT.add_message( debug_message ) #-- END check to see if QuerySet instance passed in. --# return status_OUT