def update_context_link(self, child_uuid, new_parent_uuid): """ updates a containment relationship so the child item gets a new parent item """ output = False p_ass = Assertion.objects\ .filter(predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=child_uuid) for bad_ass in p_ass: new_ass = bad_ass new_ass.uuid = new_parent_uuid # now delete the assertion with the old parent Assertion.objects\ .filter(hash_id=bad_ass.hash_id).delete() # now try to save the new assertion with the new parent try: new_ass.save() except: # if there's a problem, we'll just assume its a duplicate somehow pass # update all of the context paths in the Subjects table sub_gen = SubjectGeneration() output = sub_gen.generate_save_context_path_from_uuid(object_uuid) return output
def merge_by_uuid(self, delete_uuid, merge_into_uuid): """ Merges an item. The delete_uuid will be destroyed, but all of it's associated data will be merged into the 'merge_into_uuid' which will be retained. Returns a dictionary about what happened """ self.delete_uuid = delete_uuid self.merge_into_uuid = merge_into_uuid ok_delete = self.prep_delete_uuid(delete_uuid) ok_merge = self.prep_merge_uuid(merge_into_uuid) output = {} output['done'] = False if ok_delete and ok_merge and delete_uuid != merge_into_uuid: output['assertions'] = self.alter_assertions(delete_uuid, merge_into_uuid) output['annotations'] = self.alter_annotations(delete_uuid, merge_into_uuid) output['geospace'] = self.alter_geospace(delete_uuid, merge_into_uuid) self.delete_self_containment(merge_into_uuid) # changes oc_subjects path information to reflect new reality sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(merge_into_uuid, True) output['message'] = 'Merged item. Deleted - ' output['message'] += self.delete_manifest_obj.label + '(' + delete_uuid + ')' output['message'] = ', merged into - ' output['message'] += self.merge_manifest_obj.label + '(' + merge_into_uuid + ')' self.delete_manifest_obj.delete() # deletes object from the manifest self.delete_type_records(delete_uuid, self.delete_manifest_obj.item_type) output['done'] = True return output
def add_change_containment_assertion(self, parent_uuid, child_uuid): """ adds or changes a containment assertion """ contain_pred = Assertion.PREDICATES_CONTAINS del_old = Assertion.objects\ .filter(predicate_uuid=contain_pred, object_uuid=child_uuid)\ .delete() new_ass = Assertion() new_ass.uuid = parent_uuid new_ass.subject_type = 'subjects' new_ass.project_uuid = self.project_uuid new_ass.source_id = self.source_id new_ass.obs_node = '#contents-' + str(1) new_ass.obs_num = 1 new_ass.sort = 1 new_ass.visibility = 1 new_ass.predicate_uuid = contain_pred new_ass.object_type = 'subjects' new_ass.object_uuid = child_uuid new_ass.save() # now alter the subject item, regenerating its path # for new containment sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(child_uuid, True)
def recontextualize_import( project_uuid, child_class_uri, source_id, child_prefix, child_field, parent_prefix, parent_field, over_write_existing_context=True): """Adds context assertions to existing items in the manifest """ mans = Manifest.objects\ .filter(item_type='subjects', class_uri=child_class_uri, source_id=source_id, project_uuid=project_uuid)\ .order_by('sort') changed_uuids = [] p_subs = {} for man_obj in mans: if over_write_existing_context: Assertion.objects.filter(predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=man_obj.uuid).delete() cont_asses = [] else: cont_asses = Assertion.objects.filter(predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=man_obj.uuid)[:1] if len(cont_asses): continue # need to fix missing context association changed_uuids.append(man_obj.uuid) act_id = man_obj.label.replace(child_prefix, '') ch_cell = ImportCell.objects.filter(source_id=source_id, record=act_id, field_num=child_field)[:1][0] par_cell = ImportCell.objects.get(source_id=source_id, field_num=parent_field, row_num=ch_cell.row_num) p_context = parent_prefix + par_cell.record print('Find Context: {} for {} import row: {}'.format(p_context, man_obj.label, ch_cell.row_num)) if p_context not in p_subs: parent_sub = Subject.objects.get(context__endswith=p_context, project_uuid=project_uuid) p_subs[p_context] = parent_sub else: parent_sub = p_subs[p_context] print('Adding Context: {} : {}'.format(parent_sub.uuid, parent_sub.context)) new_ass = Assertion() new_ass.uuid = parent_sub.uuid new_ass.subject_type = 'subjects' new_ass.project_uuid = man_obj.project_uuid new_ass.source_id = source_id + '-fix' new_ass.obs_node = '#contents-' + str(1) new_ass.obs_num = 1 new_ass.sort = 1 new_ass.visibility = 1 new_ass.predicate_uuid = Assertion.PREDICATES_CONTAINS new_ass.object_type = man_obj.item_type new_ass.object_uuid = man_obj.uuid new_ass.save() sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(man_obj.uuid) return changed_uuids
def update_children_subjects(self, contents): """ Updates the paths for children items """ alter_count = 0 if contents is not False: if len(contents) > 0: for tree_node, children_list in contents.items(): for child_uuid in children_list: sg = SubjectGeneration() altered = sg.generate_save_context_path_from_uuid(child_uuid) if altered is not False: alter_count += 0 return alter_count
def update_label(self, label, post_data): """ Updates an item's label. Generally straightforward except for subjects """ ok = True old_label = self.manifest.label self.manifest.label = label self.manifest.save() self.manifest.revised_save() note = '' if self.manifest.item_type == 'projects': try: cobj = Project.objects.get(uuid=self.manifest.uuid) cobj.label = label cobj.save() ok = True except Project.DoesNotExist: self.errors['uuid'] = self.manifest.uuid + ' not in projects' ok = False elif self.manifest.item_type == 'subjects': # we need to adjust context paths for this subject + its children subj_gen = SubjectGeneration() subj_gen.generate_save_context_path_from_uuid(self.manifest.uuid) note = str(subj_gen.changes) + ' items affected' elif self.manifest.item_type == 'persons': # we need to adjust person's combined name try: cobj = Person.objects.get(uuid=self.manifest.uuid) cobj.combined_name = label if 'given_name' in post_data: cobj.given_name = post_data['given_name'] if 'surname' in post_data: cobj.surname = post_data['surname'] if 'initials' in post_data: cobj.initials = post_data['initials'] cobj.save() ok = True except Person.DoesNotExist: self.errors['uuid'] = self.manifest.uuid + ' not in projects' ok = False # now reindex for solr, including child items impacted by the changes sri = SolrReIndex() sri.reindex_related(self.manifest.uuid) self.response = {'action': 'update-label', 'ok': ok, 'change': {'prop': 'label', 'new': label, 'old': old_label, 'note': note}} return self.response
def delete_specific_link(self, subject_uuid, predicate_uuid, object_uuid): """ Deletes a linking assertion between two items """ output = True Assertion.objects\ .filter(uuid=subject_uuid, predicate_uuid=predicate_uuid, object_uuid=object_uuid)\ .delete() if predicate_uuid == Assertion.PREDICATES_CONTAINS: # just changed a containment relationship # update all of the context paths in the Subjects table sub_gen = SubjectGeneration() output = sub_gen.generate_save_context_path_from_uuid(object_uuid) return output
def update_required_make_data(self, item_man, required_make_data): """ updates items based on required make data we don't need to have these data complete if the item already exists. Required fields get some special handling We don't update with the other (not required) fields NOTE: the required fields list can be empty without an error since this is for update only, not creation """ for req_field in required_make_data: if req_field['predicate_uuid'] == 'oc-gen:label': item_man.label = req_field['value'] item_man.save() if item_man.item_type == 'subjects': subj_gen = SubjectGeneration() subj_gen.generate_save_context_path_from_uuid( item_man.uuid) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:content': # string content, as in for documents content = req_field['value'] if item_man.item_type == 'documents': # save the content to the document try: doc = OCdocument.objects.get(uuid=item_man.uuid) except OCdocument.DoesNotExist: doc = OCdocument() doc.uuid = item_man.uuid doc.project_uuid = item_man.project_uuid doc.source_id = item_man.source_id doc.content = content doc.save() elif req_field['predicate_uuid'] == 'oc-gen:contained-in': context_uuid = req_field['value'] if item_man.item_type == 'subjects': self.save_contained_subject(context_uuid, item_man) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:subjects-link': subject_uuid = req_field['value'] self.save_subject_link(subject_uuid, item_man) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:class_uri': item_man.class_uri = req_field['value'] item_man.save()
def update_required_make_data(self, item_man, required_make_data): """ updates items based on required make data we don't need to have these data complete if the item already exists. Required fields get some special handling We don't update with the other (not required) fields NOTE: the required fields list can be empty without an error since this is for update only, not creation """ for req_field in required_make_data: if req_field['predicate_uuid'] == 'oc-gen:label': item_man.label = req_field['value'] item_man.save() if item_man.item_type == 'subjects': subj_gen = SubjectGeneration() subj_gen.generate_save_context_path_from_uuid(item_man.uuid) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:content': # string content, as in for documents content = req_field['value'] if item_man.item_type == 'documents': # save the content to the document try: doc = OCdocument.objects.get(uuid=item_man.uuid) except OCdocument.DoesNotExist: doc = OCdocument() doc.uuid = item_man.uuid doc.project_uuid = item_man.project_uuid doc.source_id = item_man.source_id doc.content = content doc.save() elif req_field['predicate_uuid'] == 'oc-gen:contained-in': context_uuid = req_field['value'] if item_man.item_type == 'subjects': self.save_contained_subject(context_uuid, item_man) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:subjects-link': subject_uuid = req_field['value'] self.save_subject_link(subject_uuid, item_man) # now get uuids for solr reindexing, including child items impacted by the changes self.collect_solr_reindex_uuids(item_man.uuid) elif req_field['predicate_uuid'] == 'oc-gen:class_uri': item_man.class_uri = req_field['value'] item_man.save()
def save_contained_subject(self, context_uuid, item_man): """ create a containment relationship and a subject item """ try: parent = Manifest.objects.get(uuid=context_uuid) except Manifest.DoesNotExist: parent = False self.ok = False self.errors['context_uuid'] = 'The parent context: ' + str( context_uuid) + ' does not exist.' if parent is not False: if parent.item_type == 'subjects' \ and item_man.item_type == 'subjects': # the parent context exists, so we can create a containment relationship with it. # first delete any existing containment relations Assertion.objects\ .filter(predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=item_man.uuid)\ .delete() # now create the new containment assertion con_ass = Assertion() con_ass.uuid = parent.uuid con_ass.subject_type = parent.item_type con_ass.project_uuid = self.project_uuid con_ass.source_id = self.make_source_id() con_ass.obs_node = self.contain_obs_node con_ass.obs_num = self.contain_obs_num con_ass.sort = self.contain_sort con_ass.visibility = self.visibility con_ass.predicate_uuid = Assertion.PREDICATES_CONTAINS con_ass.object_uuid = item_man.uuid con_ass.object_type = item_man.item_type con_ass.save() # now make or update the subject record with context path for this item subgen = SubjectGeneration() subgen.generate_save_context_path_from_uuid(item_man.uuid) else: self.ok = False self.errors[ 'context'] = 'Parent context ' + parent.label + ' (' + parent.uuid + ') is: ' self.errors['context'] += parent.item_type + ', and ' self.errors[ 'context'] += 'child item ' + item_man.label + ' (' + item_man.uuid + ') is: ' self.errors[ 'context'] += item_man.item_type + '. Both need to be "subjects" items.'
def fix_trench_year_labels(self): """ make trench year labels with the year in the label """ unit_objs = Manifest.objects\ .filter(item_type='subjects', class_uri='oc-gen:cat-exc-unit') for unit_obj in unit_objs: y_asses = Assertion.objects\ .filter(uuid=unit_obj.uuid, predicate_uuid='2C7FE888-C431-4FBD-39F4-38B7D969A811')\ .order_by('data_num')[:1] if len(y_asses) > 0: year = int(float(y_asses[0].data_num)) if str(year) not in unit_obj.label: new_label = str(year) + ', ' + unit_obj.label unit_obj.label = new_label unit_obj.label = unit_obj.label.replace(', Tr-ID ', ', ID:') unit_obj.save() subj_gen = SubjectGeneration() subj_gen.generate_save_context_path_from_uuid(unit_obj.uuid)
def load_context_row(project_uuid, source_id, row): """Loads a context record row into the database""" parent_man_obj = Manifest.objects.filter(uuid=row['parent_uuid']).first() if parent_man_obj is None: print('Cannot find parent_uuid {} for uuid {}'.format( row['parent_uuid'], row['context_uuid'])) # Skip the rest. return False # OK to continue man_obj = Manifest.objects.filter(uuid=row['context_uuid']).first() if man_obj is None: man_obj = Manifest() # Set up the new item in the Manifest man_obj.uuid = row['context_uuid'] man_obj.source_id = source_id man_obj.label = row['label'] man_obj.project_uuid = project_uuid man_obj.item_type = 'subjects' man_obj.class_uri = row['class_uri'] man_obj.save() # Just to be sure, make sure this item does not # have any existing parent relations. Assertion.objects.filter( predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=man_obj.uuid, ).delete() # Now add a context relation to it. ass = Assertion() ass.uuid = parent_man_obj.uuid ass.subject_type = parent_man_obj.item_type ass.project_uuid = parent_man_obj.project_uuid ass.source_id = source_id ass.obs_node = '#contents-{}'.format(DEFAULT_OBS_NUM) ass.obs_num = DEFAULT_OBS_NUM ass.sort = 1 ass.visibility = 1 ass.predicate_uuid = Assertion.PREDICATES_CONTAINS ass.object_uuid = man_obj.uuid ass.object_type = man_obj.item_type ass.save() sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(man_obj.uuid) return True
def alter_spatial_hierarchy(self): """ alters the spatial hieratchy if the item to be deleted has spatial children items """ num_changed = 0 sp_child_count = self.count_spatial_children() if sp_child_count > 0: # item has spatial containment children # get the current item's parent. By default, the item's children # will then get associated with the current item's parent, # unless the user specified a valid "merge_into_uuid" if self.merge_into_uuid is None: # OK the user did not specify a merge_into_uuid, so # add default to the parent of the item to be deleted as the new # parent of the item-to-be-deleted's children self.get_parent_merge_into_manifest_obj() if isinstance(self.merge_into_uuid, str): dm = DeleteMerge() dm.source_id = self.editorial_uuid # so editorial uuid associated with change num_changed = dm.alter_assertions_by_role( 'subjects', self.uuid, self.merge_into_uuid, Assertion.PREDICATES_CONTAINS) # now change the path information for the Subjects sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(self.merge_into_uuid, True) # now check to see it the item to be deleted links to any # subjects, media, or document items that would be orphaned count_orphans = self.count_and_alter_unqiue_rel_to_subject() if count_orphans > 0: # we will orphan subjects, media, or documents with deletion # so link the orphaned items to the new_parent_uuid num_changed += self.count_and_alter_unqiue_rel_to_subject(self.merge_into_uuid) # delete self containment dm = DeleteMerge() dm.delete_self_containment(self.uuid) return num_changed
def save_contained_subject(self, context_uuid, item_man): """ create a containment relationship and a subject item """ try: parent = Manifest.objects.get(uuid=context_uuid) except Manifest.DoesNotExist: parent = False self.ok = False self.errors['context_uuid'] = 'The parent context: ' + str(context_uuid) + ' does not exist.' if parent is not False: if parent.item_type == 'subjects' \ and item_man.item_type == 'subjects': # the parent context exists, so we can create a containment relationship with it. # first delete any existing containment relations Assertion.objects\ .filter(predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=item_man.uuid)\ .delete() # now create the new containment assertion con_ass = Assertion() con_ass.uuid = parent.uuid con_ass.subject_type = parent.item_type con_ass.project_uuid = self.project_uuid con_ass.source_id = self.make_source_id() con_ass.obs_node = self.contain_obs_node con_ass.obs_num = self.contain_obs_num con_ass.sort = self.contain_sort con_ass.visibility = self.visibility con_ass.predicate_uuid = Assertion.PREDICATES_CONTAINS con_ass.object_uuid = item_man.uuid con_ass.object_type = item_man.item_type con_ass.save() # now make or update the subject record with context path for this item subgen = SubjectGeneration() subgen.generate_save_context_path_from_uuid(item_man.uuid) else: self.ok = False self.errors['context'] = 'Parent context ' + parent.label + ' (' + parent.uuid + ') is: ' self.errors['context'] += parent.item_type + ', and ' self.errors['context'] += 'child item ' + item_man.label + ' (' + item_man.uuid + ') is: ' self.errors['context'] += item_man.item_type + '. Both need to be "subjects" items.'
def alter_spatial_hierarchy(self): """ alters the spatial hieratchy if the item to be deleted has spatial children items """ num_changed = 0 sp_child_count = self.count_spatial_children() if sp_child_count > 0: # item has spatial containment children # get the current item's parent. By default, the item's children # will then get associated with the current item's parent, # unless the user specified a valid "merge_into_uuid" if self.merge_into_uuid is None: # OK the user did not specify a merge_into_uuid, so # add default to the parent of the item to be deleted as the new # parent of the item-to-be-deleted's children self.get_parent_merge_into_manifest_obj() if isinstance(self.merge_into_uuid, str): dm = DeleteMerge() dm.source_id = self.editorial_uuid # so editorial uuid associated with change num_changed = dm.alter_assertions_by_role( 'subjects', self.uuid, self.merge_into_uuid, Assertion.PREDICATES_CONTAINS) # now change the path information for the Subjects sg = SubjectGeneration() sg.generate_save_context_path_from_uuid( self.merge_into_uuid, True) # now check to see it the item to be deleted links to any # subjects, media, or document items that would be orphaned count_orphans = self.count_and_alter_unqiue_rel_to_subject() if count_orphans > 0: # we will orphan subjects, media, or documents with deletion # so link the orphaned items to the new_parent_uuid num_changed += self.count_and_alter_unqiue_rel_to_subject( self.merge_into_uuid) # delete self containment dm = DeleteMerge() dm.delete_self_containment(self.uuid) return num_changed
def update_label(self, label, post_data): """ Updates an item's label. Generally straightforward except for subjects """ ok = True note = '' old_label = self.manifest.label if 'language' in post_data: language = post_data['language'] else: language = Languages.DEFAULT_LANGUAGE if 'script' in post_data: script = post_data['script'] else: script = None if language != Languages.DEFAULT_LANGUAGE: # editing another language, not the default lan_obj = Languages() key = lan_obj.get_language_script_key(language, script) self.manifest.localized_json = lan_obj.modify_localization_json(self.manifest.localized_json, key, label) self.manifest.save() self.manifest.revised_save() else: # editing the default language self.manifest.label = label self.manifest.save() self.manifest.revised_save() # only do additional label changes in default language if self.manifest.item_type == 'projects': try: cobj = Project.objects.get(uuid=self.manifest.uuid) cobj.label = label cobj.save() ok = True except Project.DoesNotExist: self.errors['uuid'] = self.manifest.uuid + ' not in projects' ok = False elif self.manifest.item_type == 'subjects': # we need to adjust context paths for this subject + its children subj_gen = SubjectGeneration() subj_gen.generate_save_context_path_from_uuid(self.manifest.uuid) note = str(subj_gen.changes) + ' items affected' elif self.manifest.item_type == 'tables': ex_id = ExpTableIdentifiers() ex_id.make_all_identifiers(self.manifest.uuid) try: cobj = ExpTable.objects.get(table_id=ex_id.table_id) cobj.label = label cobj.save() ok = True except ExpTable.DoesNotExist: self.errors['uuid'] = ex_id.table_id + ' not in tables' ok = False elif self.manifest.item_type == 'persons': # we need to adjust person's combined name try: cobj = Person.objects.get(uuid=self.manifest.uuid) cobj.combined_name = label if 'given_name' in post_data: cobj.given_name = post_data['given_name'] if 'surname' in post_data: cobj.surname = post_data['surname'] if 'initials' in post_data: cobj.initials = post_data['initials'] if 'mid_init' in post_data: cobj.mid_init = post_data['mid_init'] cobj.save() ok = True except Person.DoesNotExist: self.errors['uuid'] = self.manifest.uuid + ' not in persons' ok = False # now reindex for solr, including child items impacted by the changes if self.manifest.item_type != 'tables' and self.edit_status > 0: if 'reindex' in post_data: sri = SolrReIndex() sri.reindex_related(self.manifest.uuid) if ok: # now clear the cache a change was made self.clear_caches() self.response = {'action': 'update-label', 'ok': ok, 'change': {'prop': 'label', 'new': label, 'old': old_label, 'note': note}} return self.response
def add_edit_containment(self, field_data, item_man=False): """ adds or edits containment data """ pred_uuid = Assertion.PREDICATES_CONTAINS self.ok = True note = '' if item_man is False: item_man = self.get_manifest_item(self.uuid) if item_man is False: self.ok = False label = 'Item not found' self.errors['uuid'] = 'Cannot find the item for editing assertions: ' + str(self.uuid) note = self.errors['uuid'] else: label = item_man.label self.uuid = item_man.uuid if item_man.item_type != 'subjects': self.ok = False self.errors['uuid'] = 'Can only add containment to "subjects" items: ' + str(self.uuid) else: for field_key, field in field_data.items(): new_field_data = [] if 'id' in field: field_id = field['id'] else: field_id = field_key if 'predicate_uuid' not in field: self.ok = False self.errors[field_key] = 'Missing a predicate_uuid for the field' elif field['predicate_uuid'] != 'oc-gen:contained-in': self.ok = False self.errors[field_key] = 'Must have predicate_uuid with "oc-gen:contained-in".' else: parent_uuid = False if 'label' not in field: field['label'] = 'Containment' if 'sort' not in field: field['sort'] = 1 if 'values' in field: for field_value_dict in field['values']: if 'id' in field_value_dict: parent_uuid = field_value_dict['id'] if parent_uuid != 'ROOT': parent = self.get_manifest_item(parent_uuid) if parent is not False: if parent.item_type != 'subjects': parent_uuid = False self.ok = False self.errors[field_key] = 'Parent must be a "subjects" item.' else: self.ok = True else: parent_uuid = False if parent_uuid is False: self.ok = False note = 'Could not find parent' self.errors[field_key] = 'Missing the parent_uuid in manifest' else: self.errors[field_key] = 'Missing a "id" for parent_uuid' if self.ok and parent_uuid is not False: # first delete the old containment relationship drev = DeletionRevision() drev.project_uuid = item_man.project_uuid drev.uuid = item_man.uuid drev.item_type = item_man.item_type drev.user_id = self.user_id rev_label = 'Updated ' + item_man.label rev_label += ', field: ' + field['label'] # delete prior containment relationship del_objs = Assertion.objects\ .filter(object_uuid=item_man.uuid, predicate_uuid=pred_uuid) for del_obj in del_objs: drev.assertion_keys.append(del_obj.hash_id) del_obj.delete() drev.save_delete_revision(rev_label, '') if parent_uuid != 'ROOT': # now add the new containment relationship new_ass = Assertion() new_ass.uuid = parent_uuid new_ass.subject_type = 'subjects' new_ass.project_uuid = item_man.project_uuid new_ass.source_id = 'web-form' new_ass.obs_node = '#contents-' + str(1) new_ass.obs_num = 1 new_ass.sort = 1 new_ass.visibility = 1 new_ass.predicate_uuid = pred_uuid new_ass.object_type = item_man.item_type new_ass.object_uuid = item_man.uuid try: new_ass.save() except: self.ok = False self.errors[error_key] = 'Same containment assertion ' self.errors[error_key] += 'already exists.' if self.ok: # now change the path information for the Subjects sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(item_man.uuid, True) if self.ok: # now clear the cache a change was made self.clear_caches() self.response = {'action': 'add-edit-item-containment', 'ok': self.ok, 'data': {'parent_uuid': parent_uuid}, 'change': {'uuid': self.uuid, 'label': label, 'note': note}} return self.response
def recontextualize_import(project_uuid, child_class_uri, source_id, child_prefix, child_field, parent_prefix, parent_field, over_write_existing_context=True): """Adds context assertions to existing items in the manifest """ mans = Manifest.objects\ .filter(item_type='subjects', class_uri=child_class_uri, source_id=source_id, project_uuid=project_uuid)\ .order_by('sort') changed_uuids = [] p_subs = {} for man_obj in mans: if over_write_existing_context: Assertion.objects.filter( predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=man_obj.uuid).delete() cont_asses = [] else: cont_asses = Assertion.objects.filter( predicate_uuid=Assertion.PREDICATES_CONTAINS, object_uuid=man_obj.uuid)[:1] if len(cont_asses): continue # need to fix missing context association changed_uuids.append(man_obj.uuid) act_id = man_obj.label.replace(child_prefix, '') ch_cell = ImportCell.objects.filter(source_id=source_id, record=act_id, field_num=child_field)[:1][0] par_cell = ImportCell.objects.get(source_id=source_id, field_num=parent_field, row_num=ch_cell.row_num) p_context = parent_prefix + par_cell.record print('Find Context: {} for {} import row: {}'.format( p_context, man_obj.label, ch_cell.row_num)) if p_context not in p_subs: parent_sub = Subject.objects.get(context__endswith=p_context, project_uuid=project_uuid) p_subs[p_context] = parent_sub else: parent_sub = p_subs[p_context] print('Adding Context: {} : {}'.format(parent_sub.uuid, parent_sub.context)) new_ass = Assertion() new_ass.uuid = parent_sub.uuid new_ass.subject_type = 'subjects' new_ass.project_uuid = man_obj.project_uuid new_ass.source_id = source_id + '-fix' new_ass.obs_node = '#contents-' + str(1) new_ass.obs_num = 1 new_ass.sort = 1 new_ass.visibility = 1 new_ass.predicate_uuid = Assertion.PREDICATES_CONTAINS new_ass.object_type = man_obj.item_type new_ass.object_uuid = man_obj.uuid new_ass.save() sg = SubjectGeneration() sg.generate_save_context_path_from_uuid(man_obj.uuid) return changed_uuids
def add_subjects_from_table(self, source_id, old_table): """ adds subjects from a table """ proj_mappings = { 'Petra Great Temple Excavations': 'A5DDBEA2-B3C8-43F9-8151-33343CBDC857', 'Hazor: Zooarchaeology': 'HazorZooPRJ0000000010', 'San Diego Archaeological Center': '3FAAA477-5572-4B05-8DC1-CA264FE1FC10' } class_mappings = { 'Small Find': 'oc-gen:cat-object', 'Arch. Element': 'oc-gen:cat-arch-element', 'Locus': 'oc-gen:cat-locus', 'Non Diag. Bone': 'oc-gen:cat-non-diag-bone' } filename = old_table + '.csv' tab_obj = self.load_csv_file(self.table_dir, filename) missing_parents = {} if tab_obj is not False: i = -1 context_cells_indexes = [] label_index = False category_index = False for row in tab_obj: i += 1 if i == 0: cc = 0 for cell in row: if 'Context (' in cell: context_cells_indexes.append(cc) if 'Item name' == cell: label_index = cc if 'Category' == cell: category_index = cc cc += 1 elif i > 0 and label_index is not False \ and category_index is not False: # OK to generate a new item uuid = row[0] label = row[label_index] tab_source = row[1] if row[3] in proj_mappings \ and row[category_index] in class_mappings: class_uri = class_mappings[row[category_index]] project_uuid = proj_mappings[row[3]] parent_contexts = [] for context_cell_index in context_cells_indexes: parent_contexts.append(row[context_cell_index]) parent_context = '/'.join(parent_contexts) par_sub = Subject.objects\ .filter(project_uuid=project_uuid, context=parent_context)[:1] if len(par_sub) < 1: print('Cannot find parent: ' + parent_context) else: print('Found parent: ' + parent_context) parent_uuid = par_sub[0].uuid try: parent_ok = Manifest.objects.get(uuid=parent_uuid) except Manifest.DoesNotExist: parent_ok = False if parent_ok is not False: # we have a parent, so make the bone man = Manifest() m_ass = ManageAssertions() m_ass.source_id = source_id su_gen = SubjectGeneration() man.uuid = uuid man.label = label man.source_id = source_id man.item_type = 'subjects' man.class_uri = class_uri man.project_uuid = project_uuid man.save() m_ass.add_containment_assertion(parent_uuid, man.uuid) su_gen.generate_save_context_path_from_manifest_obj(man) print('Added: ' + uuid + ' from ' + tab_source) else: missing_parents[parent_uuid] = {'label': parent_label, 'tab': tab_source} else: if i > 0: print('Strange problems...') raise('Check: ' + str(row)) print('Missing parents: ' + str(missing_parents))
def add_edit_containment(self, field_data, item_man=False): """ adds or edits containment data """ pred_uuid = Assertion.PREDICATES_CONTAINS self.ok = True note = '' if item_man is False: item_man = self.get_manifest_item(self.uuid) if item_man is False: self.ok = False label = 'Item not found' self.errors[ 'uuid'] = 'Cannot find the item for editing assertions: ' + str( self.uuid) note = self.errors['uuid'] else: label = item_man.label self.uuid = item_man.uuid if item_man.item_type != 'subjects': self.ok = False self.errors[ 'uuid'] = 'Can only add containment to "subjects" items: ' + str( self.uuid) else: for field_key, field in field_data.items(): new_field_data = [] if 'id' in field: field_id = field['id'] else: field_id = field_key if 'predicate_uuid' not in field: self.ok = False self.errors[ field_key] = 'Missing a predicate_uuid for the field' elif field['predicate_uuid'] != 'oc-gen:contained-in': self.ok = False self.errors[ field_key] = 'Must have predicate_uuid with "oc-gen:contained-in".' else: parent_uuid = False if 'label' not in field: field['label'] = 'Containment' if 'sort' not in field: field['sort'] = 1 if 'values' in field: for field_value_dict in field['values']: if 'id' in field_value_dict: parent_uuid = field_value_dict['id'] if parent_uuid != 'ROOT': parent = self.get_manifest_item( parent_uuid) if parent is not False: if parent.item_type != 'subjects': parent_uuid = False self.ok = False self.errors[ field_key] = 'Parent must be a "subjects" item.' else: self.ok = True else: parent_uuid = False if parent_uuid is False: self.ok = False note = 'Could not find parent' self.errors[ field_key] = 'Missing the parent_uuid in manifest' else: self.errors[ field_key] = 'Missing a "id" for parent_uuid' if self.ok and parent_uuid is not False: # first delete the old containment relationship drev = DeletionRevision() drev.project_uuid = item_man.project_uuid drev.uuid = item_man.uuid drev.item_type = item_man.item_type drev.user_id = self.user_id rev_label = 'Updated ' + item_man.label rev_label += ', field: ' + field['label'] # delete prior containment relationship del_objs = Assertion.objects\ .filter(object_uuid=item_man.uuid, predicate_uuid=pred_uuid) for del_obj in del_objs: drev.assertion_keys.append(del_obj.hash_id) del_obj.delete() drev.save_delete_revision(rev_label, '') if parent_uuid != 'ROOT': # now add the new containment relationship new_ass = Assertion() new_ass.uuid = parent_uuid new_ass.subject_type = 'subjects' new_ass.project_uuid = item_man.project_uuid new_ass.source_id = 'web-form' new_ass.obs_node = '#contents-' + str(1) new_ass.obs_num = 1 new_ass.sort = 1 new_ass.visibility = 1 new_ass.predicate_uuid = pred_uuid new_ass.object_type = item_man.item_type new_ass.object_uuid = item_man.uuid try: new_ass.save() except: self.ok = False self.errors[ error_key] = 'Same containment assertion ' self.errors[error_key] += 'already exists.' if self.ok: # now change the path information for the Subjects sg = SubjectGeneration() sg.generate_save_context_path_from_uuid( item_man.uuid, True) if self.ok: # now clear the cache a change was made self.clear_caches() self.response = { 'action': 'add-edit-item-containment', 'ok': self.ok, 'data': { 'parent_uuid': parent_uuid }, 'change': { 'uuid': self.uuid, 'label': label, 'note': note } } return self.response