# HG changeset patch # User casties # Date 1443703196 -7200 # Node ID 45dad9e38c825674a64d8116912e17b829a3400d # Parent aeef1fedd899da8e65e803d6fc01003e453e6116 first functional version of commentary visualisation. diff -r aeef1fedd899 -r 45dad9e38c82 ismi-python-neo4jrestclient/ismi-vis.py --- a/ismi-python-neo4jrestclient/ismi-vis.py Mon Sep 28 18:15:35 2015 +0200 +++ b/ismi-python-neo4jrestclient/ismi-vis.py Thu Oct 01 14:39:56 2015 +0200 @@ -3,7 +3,7 @@ from flask import Flask, Response, request -from neo4jrestclient.client import GraphDatabase, Node +from neo4jrestclient.client import GraphDatabase, Node, Relationship app = Flask(__name__, static_url_path='/static/') gdb = GraphDatabase("http://localhost:7474", username="neo4j", password="neo5j") @@ -16,27 +16,41 @@ @app.route("/graph") def get_graph(): - query = ("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) " - "RETURN m.title as movie, collect(a.name) as cast " - "LIMIT {limit}") - results = gdb.query(query, - params={"limit": request.args.get("limit", 100)}) + query = ("match (t1:TEXT)-[r:is_commentary_on]->(t2:TEXT) return t1,r,t2") + results = gdb.query(query, returns=(Node,Relationship,Node)) + n4j_nodes = {} + node_idx = {} nodes = [] rels = [] i = 0 - for movie, cast in results: - nodes.append({"title": movie, "label": "movie"}) - target = i - i += 1 - for name in cast: - actor = {"title": name, "label": "actor"} - try: - source = nodes.index(actor) - except ValueError: - nodes.append(actor) - source = i - i += 1 - rels.append({"source": source, "target": target}) + for node1, rel, node2 in results: + # source node + id1 = node1['ismi_id'] + if id1 not in n4j_nodes: + n4j_nodes[id1] = node1 + nodes.append({"title": node1['label'], "label": "TEXT"}) + node_idx[id1] = i + source = i + i += 1 + + else: + source = node_idx[id1] + + # target node + id2 = node2['ismi_id'] + if id2 not in n4j_nodes: + n4j_nodes[id2] = node2 + nodes.append({"title": node2['label'], "label": "TEXT"}) + node_idx[id2] = i + target = i + i += 1 + + else: + target = node_idx[id2] + + # relation + rels.append({"source": source, "target": target}) + return Response(dumps({"nodes": nodes, "links": rels}), mimetype="application/json") @@ -48,32 +62,27 @@ except KeyError: return [] else: - query = ("MATCH (movie:Movie) " - "WHERE movie.title =~ {title} " - "RETURN movie") + query = ("MATCH (text:TEXT) " + "WHERE text.label =~ {title} " + "RETURN text") results = gdb.query( query, returns=Node, params={"title": "(?i).*" + q + ".*"} ) - return Response(dumps([{"movie": row.properties} - for [row] in results]), + return Response(dumps([{"text": row.properties} for [row] in results]), mimetype="application/json") -@app.route("/movie/") -def get_movie(title): - query = ("MATCH (movie:Movie {title:{title}}) " - "OPTIONAL MATCH (movie)<-[r]-(person:Person) " - "RETURN movie.title as title," - "collect([person.name, " - " head(split(lower(type(r)), '_')), r.roles]) as cast " - "LIMIT 1") - results = gdb.query(query, params={"title": title}) - title, cast = results[0] - return Response(dumps({"title": title, - "cast": [dict(zip(("name", "job", "role"), member)) - for member in cast]}), +@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") diff -r aeef1fedd899 -r 45dad9e38c82 ismi-python-neo4jrestclient/static/index.html --- a/ismi-python-neo4jrestclient/static/index.html Mon Sep 28 18:15:35 2015 +0200 +++ b/ismi-python-neo4jrestclient/static/index.html Thu Oct 01 14:39:56 2015 +0200 @@ -16,7 +16,7 @@ <li> <form role="search" class="navbar-form" id="search"> <div class="form-group"> - <input type="text" value="Matrix" placeholder="Search for Movie Title" class="form-control" name="search"> + <input type="text" value="Qushji" placeholder="Search for Title" class="form-control" name="search"> </div> <button class="btn btn-default" type="submit">Search</button> </form> @@ -30,7 +30,7 @@ </a> </div> <div class="navbar-brand"> - <div class="brand">ISMI Texts</div> + <div class="brand">ISMI Commentary relations between Texts</div> </div> </div> </div> @@ -44,9 +44,9 @@ <table id="results" class="table table-striped table-hover"> <thead> <tr> - <th>Movie</th> - <th>Released</th> - <th>Tagline</th> + <th>Title (translit)</th> + <th>ismi_id</th> + <th>Title (arabic)</th> </tr> </thead> <tbody> @@ -58,12 +58,12 @@ <div class="panel panel-default"> <div class="panel-heading" id="title">Details</div> <div class="row"> - <div class="col-sm-4 col-md-4"> + <!-- <div class="col-sm-4 col-md-4"> <img src="" class="well" id="poster"/> - </div> + </div> --> <div class="col-md-8 col-sm-8"> - <h4>Crew</h4> - <ul id="crew"> + <h4>Details</h4> + <ul id="info"> </ul> </div> </div> @@ -72,7 +72,7 @@ </div> <style type="text/css"> .node { stroke: #222; stroke-width: 1.5px; } - .node.actor { fill: #888; } + .node.TEXT { fill: #888; } .node.movie { fill: #BBB; } .link { stroke: #999; stroke-opacity: .6; stroke-width: 1px; } </style> @@ -81,16 +81,16 @@ <script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { - function showMovie(title) { - $.get("/movie/" + encodeURIComponent(title), + function showMovie(text_id) { + $.get("/text/" + encodeURIComponent(text_id), function (data) { if (!data) return; $("#title").text(data.title); - $("#poster").attr("src","http://neo4j-contrib.github.io/developer-resources/language-guides/assets/posters/"+encodeURIComponent(data.title)+".jpg"); - var $list = $("#crew").empty(); - data.cast.forEach(function (cast) { - $list.append($("<li>" + cast.name + " " +cast.job + (cast.job == "acted"?" as " + cast.role : "") + "</li>")); - }); + // $("#poster").attr("src","http://neo4j-contrib.github.io/developer-resources/language-guides/assets/posters/"+encodeURIComponent(data.title)+".jpg"); + var $list = $("#info").empty(); + for (key in data.attrs) { + $list.append($("<li>" + key + ": " + data.attrs[key] + "</li>")); + }; }, "json"); return false; } @@ -101,11 +101,11 @@ var t = $("table#results tbody").empty(); if (!data || data.length == 0) return; data.forEach(function (row) { - var movie = row.movie; - $("<tr><td class='movie'>" + movie.title + "</td><td>" + movie.released + "</td><td>" + movie.tagline + "</td></tr>").appendTo(t) - .click(function() { showMovie($(this).find("td.movie").text());}) + var text = row.text; + $("<tr><td>" + text.label + "</td><td>" + text.full_title + "</td><td class='text_id'>" + text.ismi_id + "</td></tr>").appendTo(t) + .click(function() { showMovie($(this).find("td.text_id").text());}) }); - showMovie(data[0].movie.title); + showMovie(data[0].text.ismi_id); }, "json"); return false; }