def create_arc(collection, document, origin, target, type, old_type=None, old_target=None): directory = collection real_dir = real_directory(directory) mods = ModificationTracker() real_dir = real_directory(directory) projectconf = ProjectConfiguration(real_dir) document = path_join(real_dir, document) with TextAnnotations(document) as ann_obj: # Dirty hack to bail as quick as possible if read-only # TODO: why only here? The checking of readonly should be # consistent across the different editing functions. if ann_obj._read_only: raise AnnotationsIsReadOnlyError(ann_obj.get_document()) origin = ann_obj.get_ann_by_id(origin) target = ann_obj.get_ann_by_id(target) # Ugly check, but we really get no other information if type == "Equiv": # It is an Equiv if old_type == "Equiv": # "Change" from Equiv to Equiv is harmless # TODO: some message needed? pass else: assert old_type is None, "attempting to change Equiv, not supported" ann = EquivAnnotation(type, [unicode(origin.id), unicode(target.id)], "") ann_obj.add_annotation(ann) mods.addition(ann) elif type in projectconf.get_relation_types(): if old_type is not None or old_target is not None: assert type in projectconf.get_relation_types(), ( 'attempting to convert relation to non-relation "%s" ' % (target.type,) ) + ("(legit types: %s)" % (unicode(projectconf.get_relation_types()),)) sought_target = old_target if old_target is not None else target.id sought_type = old_type if old_type is not None else type # We are to change the type and/or target found = None for ann in ann_obj.get_relations(): if ann.arg2 == sought_target and ann.type == sought_type: found = ann break # Did it exist and is changed?, otherwise we do nothing if found is not None and (found.arg2 != target.id or found.type != type): before = unicode(found) found.arg2 = target.id found.type = type mods.change(before, found) else: # Create a new annotation # TODO: Assign a suitable letter new_id = ann_obj.get_new_id("R") rel = projectconf.get_relation_by_type(type) assert rel is not None and len(rel.arg_list) == 2 a1l, a2l = rel.arg_list ann = BinaryRelationAnnotation(new_id, type, a1l, origin.id, a2l, target.id, "\t") mods.addition(ann) ann_obj.add_annotation(ann) else: try: arg_tup = (type, unicode(target.id)) # Is this an addition or an update? if old_type is None and old_target is None: if arg_tup not in origin.args: before = unicode(origin) origin.args.append(arg_tup) mods.change(before, origin) else: # It already existed as an arg, we were called to do nothing... pass else: # Construct how the old arg would have looked like old_arg_tup = (type if old_type is None else old_type, target if old_target is None else old_target) if old_arg_tup in origin.args and arg_tup not in origin.args: before = unicode(origin) origin.args.remove(old_arg_tup) origin.args.append(arg_tup) mods.change(before, origin) else: # Collision etc. don't do anything pass except AttributeError: # The annotation did not have args, it was most likely an entity # thus we need to create a new Event... new_id = ann_obj.get_new_id("E") ann = EventAnnotation(origin.id, [arg_tup], new_id, origin.type, "") ann_obj.add_annotation(ann) mods.addition(ann) if DEBUG: mods_json = mods.json_response() else: mods_json = {} # Hack since we don't have the actual text, should use a factory? txt_file_path = ann_obj.get_document() + "." + TEXT_FILE_SUFFIX j_dic = _json_from_ann_and_txt(ann_obj, txt_file_path) mods_json["annotations"] = j_dic return mods_json
def create_arc(collection, document, origin, target, type, old_type=None, old_target=None): directory = collection real_dir = real_directory(directory) mods = ModificationTracker() real_dir = real_directory(directory) projectconf = ProjectConfiguration(real_dir) document = path_join(real_dir, document) with TextAnnotations(document) as ann_obj: # bail as quick as possible if read-only # TODO: make consistent across the different editing # functions, integrate ann_obj initialization and checks if ann_obj._read_only: raise AnnotationsIsReadOnlyError(ann_obj.get_document()) origin = ann_obj.get_ann_by_id(origin) target = ann_obj.get_ann_by_id(target) if projectconf.is_equiv_type(type): # It is an Equiv if projectconf.is_equiv_type(old_type): # "Change" from Equiv to Equiv is harmless # TODO: some message needed? pass else: assert old_type is None, 'attempting to change equiv relation to non-equiv relation, operation not supported' ann = EquivAnnotation(type, [unicode(origin.id), unicode(target.id)], '') ann_obj.add_annotation(ann) mods.addition(ann) elif projectconf.is_relation_type(type): if old_type is not None or old_target is not None: assert type in projectconf.get_relation_types(), ( ('attempting to convert relation to non-relation "%s" ' % (target.type, )) + ('(legit types: %s)' % (unicode(projectconf.get_relation_types()), ))) sought_target = (old_target if old_target is not None else target.id) sought_type = (old_type if old_type is not None else type) # We are to change the type and/or target found = None for ann in ann_obj.get_relations(): if ann.arg2 == sought_target and ann.type == sought_type: found = ann break # Did it exist and is changed?, otherwise we do nothing if found is not None and (found.arg2 != target.id or found.type != type): before = unicode(found) found.arg2 = target.id found.type = type mods.change(before, found) else: # Create a new annotation # TODO: Assign a suitable letter new_id = ann_obj.get_new_id('R') rel = projectconf.get_relation_by_type(type) assert rel is not None and len(rel.arg_list) == 2 a1l, a2l = rel.arg_list ann = BinaryRelationAnnotation(new_id, type, a1l, origin.id, a2l, target.id, '\t') mods.addition(ann) ann_obj.add_annotation(ann) else: try: arg_tup = (type, unicode(target.id)) # Is this an addition or an update? if old_type is None and old_target is None: if arg_tup not in origin.args: before = unicode(origin) origin.add_argument(type, unicode(target.id)) mods.change(before, origin) else: # It already existed as an arg, we were called to do nothing... pass else: # Construct how the old arg would have looked like old_arg_tup = (type if old_type is None else old_type, target if old_target is None else old_target) if old_arg_tup in origin.args and arg_tup not in origin.args: before = unicode(origin) origin.args.remove(old_arg_tup) origin.add_argument(type, unicode(target.id)) mods.change(before, origin) else: # Collision etc. don't do anything pass except AttributeError: # The annotation did not have args, it was most likely an entity # thus we need to create a new Event... new_id = ann_obj.get_new_id('E') ann = EventAnnotation( origin.id, [arg_tup], new_id, origin.type, '' ) ann_obj.add_annotation(ann) mods.addition(ann) mods_json = mods.json_response() mods_json['annotations'] = _json_from_ann(ann_obj) return mods_json