def _get_attribute_type_info(nodes, project_conf, directory): items = [] for node in nodes: if node == 'SEPARATOR': continue else: item = {} _type = node.storage_form() item['name'] = project_conf.preferred_display_form(_type) item['type'] = _type item['unused'] = node.unused item['labels'] = get_labels_by_storage_form(directory, _type) # process "special" <GLYPH-POS> argument, specifying where # to place the glyph glyph_pos = None for k in node.arguments: # TODO: remove magic value if k == '<GLYPH-POS>': for v in node.arguments[k]: if v not in ('left', 'right'): display_message('Configuration error: "%s" is not a valid glyph position for %s' % (v,_type), 'warning') else: glyph_pos = v # TODO: "special" <DEFAULT> argument # check if there are any (normal) "arguments" args = [k for k in node.arguments if k != "Arg" and not match(r'^<.*>$', k)] if len(args) == 0: # no, assume binary and mark accordingly # TODO: get rid of special cases, grab style from config if _type == 'Negation': item['values'] = { _type : { 'box': u'crossed' } } else: item['values'] = { _type : { 'dasharray': '3,3' } } else: # has normal arguments, use these as possible values item['values'] = {} for k in args: for v in node.arguments[k]: item['values'][k] = { 'glyph':v } if glyph_pos is not None: item['values'][k]['position'] = glyph_pos items.append(item) return items
def _get_subtypes_for_type(nodes, project_conf, hotkey_by_type, directory): items = [] for node in nodes: if node == 'SEPARATOR': items.append(None) else: item = {} _type = node.storage_form() item['name'] = project_conf.preferred_display_form(_type) item['type'] = _type item['unused'] = node.unused # TODO: use project_conf item['labels'] = get_labels_by_storage_form(directory, _type) # TODO: avoid magic values span_drawing_conf = project_conf.get_drawing_config_by_type(_type) if span_drawing_conf is None: span_drawing_conf = project_conf.get_drawing_config_by_type("SPAN_DEFAULT") if span_drawing_conf is None: span_drawing_conf = {} for k in ('fgColor', 'bgColor', 'borderColor'): if k in span_drawing_conf: item[k] = span_drawing_conf[k] try: item['hotkey'] = hotkey_by_type[_type] except KeyError: pass arcs = [] # TODO: this whole bit makes very little sense for relations, # which are already "arcs" in the UI sense. This bit of the # protocol should be cleaned up. See issue #237. # Note: for client, relations are represented as "arcs" # attached to "spans" corresponding to entity annotations. for arc in chain(project_conf.relation_types_from(_type), node.arguments.keys()): curr_arc = {} curr_arc['type'] = arc arc_labels = get_labels_by_storage_form(directory, arc) curr_arc['labels'] = arc_labels if arc_labels is not None else [arc] try: curr_arc['hotkey'] = hotkey_by_type[arc] except KeyError: pass # TODO: avoid magic values arc_drawing_conf = project_conf.get_drawing_config_by_type(arc) if arc_drawing_conf is None: arc_drawing_conf = project_conf.get_drawing_config_by_type("ARC_DEFAULT") if arc_drawing_conf is None: arc_drawing_conf = {} for k in ('color', 'dashArray'): if k in arc_drawing_conf: curr_arc[k] = arc_drawing_conf[k] # Client needs also possible arc 'targets', # defined as the set of types (entity or event) that # the arc can connect to # This bit doesn't make sense for relations, which are # already "arcs" (see comment above). TODO cleanup. if project_conf.is_relation_type(_type): targets = [] else: targets = [] # TODO: should include this functionality in projectconf for ttype in project_conf.get_entity_types() + project_conf.get_event_types(): if arc in project_conf.arc_types_from_to(_type, ttype): targets.append(ttype) curr_arc['targets'] = targets arcs.append(curr_arc) # If we found any arcs, attach them if arcs: item['arcs'] = arcs item['children'] = _get_subtypes_for_type(node.children, project_conf, hotkey_by_type, directory) items.append(item) return items