def __init__(self, rdf_node): global _node_json_number subj_str = str(rdf_node) entity_label, entity_graphic_class, entity_id = lib_naming.ParseEntityUri( subj_str, long_display=False, force_entity_ip_addr=None) self.m_label = entity_label.strip() self.m_class = entity_graphic_class array_graph_params = lib_patterns.TypeToGraphParams(self.m_class) # "Graphic_shape","Graphic_colorfill","Graphic_colorbg","Graphic_border","Graphic_is_rounded" self.m_color = array_graph_params[1] # TODO: Display the doc in the module with FromModuleToDoc(importedMod,filDfltText): self.m_info_list = [entity_graphic_class] self.m_info_dict = dict() self.m_index = _node_json_number the_survol_url = lib_util.survol_unescape(rdf_node) self.m_survol_url = the_survol_url self.m_survol_universal_alias = lib_exports.NodeToUniversalAlias( rdf_node) _node_json_number += 1 # One more node.
def _custom_decode_hex(the_str): the_str = lib_util.survol_unescape(the_str) return the_str.replace("%25", "%").replace("%2F", "/").replace( "%5C", "\\").replace("%3A", ":")
def output_rdf_graph_as_json_d3(page_title, error_msg, parameters, grph): """ Transforms a RDF graph into a JSON document. This returns a graph made of Json objects which are suitable for visualisation in the Javascript interface to Survol, which is based on D3. """ # Must be reset to zero between several executions, when run by WSGI. global _node_json_number _node_json_number = 0 # It contains a cache because the same nodes may appear several times. def node_to_json_obj(the_nod): try: return node_to_json_obj.dictNod2Json[the_nod] except KeyError: json_obj = NodeJson(the_nod) node_to_json_obj.dictNod2Json[the_nod] = json_obj return json_obj node_to_json_obj.dictNod2Json = dict() links = [] for subj, pred, obj in grph: # This applies only to entity.py : In rendering based on Json, scripts are not displayed as nodes, # but in hierarchical menus. The node must not appear at all. # TODO: Should probably also eliminate pc.property_rdf_data_nolist2 etc ... See lib_client. if pred == pc.property_script: logging.debug("continue subj=%s obj=%s", subj, obj) continue # Normal data scripts are not accepted. This should apply only to file_directory.py and file_to_mime.py if not _script_for_json(subj): continue if not _script_for_json(obj): continue subj_obj = node_to_json_obj(subj) subj_id = subj_obj.m_survol_url prop_nam = lib_exports.PropToShortPropNam(pred) # TODO: BUG: If several nodes for the same properties, only the last one is kept. if lib_kbase.IsLink(obj): obj_obj = node_to_json_obj(obj) obj_id = obj_obj.m_survol_url links.extend([{ 'source': subj_id, 'target': obj_id, 'survol_link_prop': prop_nam }]) # TODO: Add the name corresponding to the URL, in m_info_dict so that some elements # of the tooltip would be clickable. On the other hand, one just need to merge # the nodes relative to the object, by right-clicking. elif lib_kbase.IsLiteral(obj): if pred == pc.property_information: try: subj_obj.m_info_list.append(str(obj.value)) except UnicodeEncodeError: # 'ascii' codec can't encode character u'\xf3' in position 17: ordinal not in range(128) # https://stackoverflow.com/questions/9942594/unicodeencodeerror-ascii-codec-cant-encode-character-u-xa0-in-position-20 subj_obj.m_info_list.append(obj.value.encode('utf-8')) else: if isinstance(obj.value, six.integer_types) or isinstance( obj.value, six.string_types): subj_obj.m_info_dict[prop_nam] = obj.value else: # If the value cannot be serializable to JSON. subj_obj.m_info_dict[prop_nam] = type(obj.value).__name__ else: raise Exception(__file__ + " Cannot happen here") # Now, this creates the nodes sent as json objects. num_nodes = len(node_to_json_obj.dictNod2Json) nodes = [None] * num_nodes for nod in node_to_json_obj.dictNod2Json: nod_obj = node_to_json_obj.dictNod2Json[nod] nod_titl = nod_obj.m_label nod_id = nod_obj.m_index # The URL must not contain any HTML entities when in a XML or SVG document, # and therefore must be escaped. Therefore they have to be unescaped when transmitted in JSON. # This is especially needed for RabbitMQ because the parameter defining its connection name # has the form: "Url=LOCALHOST:12345,Connection=127.0.0.1:51748 -> 127.0.0.1:5672" # HTTP_MIME_URL the_survol_nam = lib_util.survol_unescape( nod_titl) # MUST UNESCAPE HTML ENTITIES ! # TODO: Use the same object for lookup and Json. nodes[nod_id] = { 'id': nod_obj.m_survol_url, # Required by D3 'name': the_survol_nam, # Theoretically, this URL should be HTML unescaped then CGI escaped. 'survol_url': nod_obj.m_survol_url, # Duplicate of 'id' 'survol_universal_alias': nod_obj.m_survol_universal_alias, 'survol_fill': nod_obj.m_color, 'entity_class': nod_obj. m_class, # TODO: Maybe not needed because also in the URL ? 'survol_info_list': nod_obj.m_info_list, 'survol_info_dict': nod_obj.m_info_dict } # This is the graph displayed by D3. graph = {"page_title": page_title, "nodes": nodes, "links": links} _write_json_header(json.dumps(graph, indent=2))