view ismi-python-neo4jrestclient/ismi-vis.py @ 17:09c0a9ceb778

more pimping of commentaries_authors.
author casties
date Wed, 07 Oct 2015 15:41:00 +0200
parents ad3eefa2cb80
children d8bbf6d5920b
line wrap: on
line source

#!/usr/bin/env python
from json import dumps

from flask import Flask, Response, request, send_from_directory

from neo4jrestclient.client import GraphDatabase, Node, Relationship

app = Flask(__name__, static_url_path='/static/')
app.debug = True
gdb = GraphDatabase("http://localhost:7474", username="neo4j", password="neo5j")


@app.route("/")
def get_index():
    return app.send_static_file('commentaries.html')

@app.route("/commentaries.html")
def get_commentaries():
    return app.send_static_file('commentaries.html')

@app.route("/commentaries_authors.html")
def get_commentaries_authors():
    return app.send_static_file('commentaries_authors2.html')

@app.route('/static/<filename>')
def get_file(filename):
    return send_from_directory('static', filename)

@app.route("/graph")
def get_graph_commentaries():
    query = ("match (t1:TEXT)-[r:is_commentary_on]->(t2:TEXT)"
             " return t1,t2"
             " limit {limit}")
    results = gdb.query(query, returns=(Node,Node),
                        params={"limit": int(request.args.get("limit", 100))})

    n4j_nodes = {}
    node_idx = {}
    nodes = []
    rels = []
    i = 0
    for text1, text2 in results:
        # source text
        id1 = text1['ismi_id']
        if id1 not in n4j_nodes:
            n4j_nodes[id1] = text1
            nodes.append({"title": "%s [%s]"%(text1['label'],id1), "label": "TEXT", "ismi_id": id1})
            node_idx[id1] = i
            source = i
            i += 1

        else:
            source = node_idx[id1]

        # target text
        id2 = text2['ismi_id']
        if id2 not in n4j_nodes:
            n4j_nodes[id2] = text2
            nodes.append({"title": "%s [%s]"%(text2['label'],id2), "label": "TEXT", "ismi_id": id2})
            node_idx[id2] = i
            target = i
            i += 1

        else:
            target = node_idx[id2]

        # relation is_commentary_on
        rels.append({"source": source, "target": target})

    return Response(dumps({"nodes": nodes, "links": rels}),
                    mimetype="application/json")


@app.route("/graph_commentaries_authors")
def get_graph_commentaries_authors():
    query = ("match (a1:PERSON)<-[:was_created_by]-(t1:TEXT)-[r:is_commentary_on]->(t2:TEXT)-[:was_created_by]->(a2:PERSON)"
             " return a1,t1,t2,a2"
             " limit 100")
    results = gdb.query(query, returns=(Node,Node,Node,Node))
    n4j_nodes = {}
    node_idx = {}
    nodes = []
    rels = []
    i = 0
    for author1, text1, text2, author2 in results:
        # source text
        id1 = text1['ismi_id']
        if id1 not in n4j_nodes:
            n4j_nodes[id1] = text1
            nodes.append({"title": "%s [%s]"%(text1['label'],id1), "label": "TEXT"})
            node_idx[id1] = i
            source = i
            i += 1

        else:
            source = node_idx[id1]

        # target text
        id2 = text2['ismi_id']
        if id2 not in n4j_nodes:
            n4j_nodes[id2] = text2
            nodes.append({"title": "%s [%s]"%(text2['label'],id2), "label": "TEXT"})
            node_idx[id2] = i
            target = i
            i += 1

        else:
            target = node_idx[id2]

        # relation is_commentary_on
        rels.append({"source": source, "target": target})

        # source author
        id3 = author1['ismi_id']
        if id3 not in n4j_nodes:
            n4j_nodes[id3] = author1
            nodes.append({"title": "%s [%s]"%(author1['label'],id3), "label": "PERSON"})
            node_idx[id3] = i
            s_author = i
            i += 1

        else:
            s_author = node_idx[id3]

        # relation was_created_by
        rels.append({"source": source, "target": s_author})

        # target author
        id4 = author1['ismi_id']
        if id4 not in n4j_nodes:
            n4j_nodes[id4] = author2
            nodes.append({"title": "%s [%s]"%(author2['label'],id4), "label": "PERSON"})
            node_idx[id4] = i
            t_author = i
            i += 1

        else:
            t_author = node_idx[id4]

        # relation was_created_by
        rels.append({"source": source, "target": t_author})

    return Response(dumps({"nodes": nodes, "links": rels}),
                    mimetype="application/json")


@app.route("/search")
def get_search():
    try:
        q = request.args["q"]
    except KeyError:
        return []
    else:
        query = ("MATCH (t:TEXT)-[:was_created_by]->(p:PERSON {ismi_id: {id}})"
                 " RETURN t,p,exists((t)-[:is_commentary_on]->()),exists(()-[:is_commentary_on]->(t))")
        results = gdb.query(
            query,
            returns=(Node,Node,bool,bool),
            params={"id": int(q)}
        )
        # {"name": "(?i).*" + q + ".*"}
        print("search for %s returned %s results"%(repr(q),len(results)))
        data = [{"text": t.properties, 
                 "author": a.properties, 
                 "is_commentary": is_com, 
                 "has_commentaries": has_com} 
                for [t,a,is_com,has_com] in results]
        return Response(dumps(data),
                        mimetype="application/json")


@app.route("/text/<text_id>")
def get_text(text_id):
    query = ("MATCH (text:TEXT {ismi_id:{text_id}}) "
             " RETURN text"
             " LIMIT 1")
    results = gdb.query(query, returns=Node, params={"text_id": int(text_id)})
    node = results[0][0]
    print("node:%s"%repr(node))
    return Response(dumps({"title": node['label'], "attrs": node.properties}),
                    mimetype="application/json")

@app.route("/textandcommentaries/<text_id>")
def get_textandcommentaries(text_id):
    query = ("match (t:TEXT {ismi_id:{text_id}})"
             " optional match (t)-[:was_created_by]->(a:PERSON)"
             " optional match (s:TEXT)<-[:is_commentary_on]-(t)"
             " optional match (s)-[:was_created_by]->(sa:PERSON)"
             " optional match (t)<-[:is_commentary_on]-(c:TEXT)" 
             " optional match (c)-[:was_created_by]->(ca:PERSON)"
             " return t,a.label,s.label,s.ismi_id,sa.label,c.label,c.ismi_id,ca.label")
    print("query:%s"%query)
    results = gdb.query(query, returns=(Node,str,str,str,str,str,str,str), 
                        params={"text_id": int(text_id)})
    
    print("result:%s"%results)
    text = None
    author = None
    scs = {}
    cs = {}
    for [t,a_label,s_label,s_id,sa_label,c_label,c_id,ca_label] in results:
        text = t
        author = a_label
        if s_id is not None and s_id != "None":
            scs[int(s_id)] = {"title": s_label, "author":sa_label}
            
        if c_id is not None and c_id != "None":
            cs[int(c_id)] = {"title": c_label, "author":ca_label}
        
    print("text:%s scs:%s cs:%s"%(text, scs, cs))
    return Response(dumps({"title": text['label'], "attrs": text.properties, 
                           "author": author,
                           "commenting": scs, "commentaries": cs}),
                    mimetype="application/json")


if __name__ == '__main__':
    app.run(port=8080)