-
Notifications
You must be signed in to change notification settings - Fork 56
/
neovigator.rb
155 lines (123 loc) · 4.8 KB
/
neovigator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
require 'rubygems'
require 'neography'
require 'sinatra/base'
require 'uri'
class Neovigator < Sinatra::Application
set :haml, :format => :html5
set :app_file, __FILE__
configure :test do
require 'net-http-spy'
Net::HTTP.http_logger_options = {:verbose => true}
end
helpers do
def link_to(url, text=url, opts={})
attributes = ""
opts.each { |key,value| attributes << key.to_s << "=\"" << value << "\" "}
"<a href=\"#{url}\" #{attributes}>#{text}</a>"
end
def neo
@neo = Neography::Rest.new(ENV["GRAPHENEDB_URL"] || "http://neo4j:swordfish@localhost:7474")
end
end
def hashify(results)
results["data"].map {|row| Hash[*results["columns"].zip(row).flatten] }
end
def create_graph
return if neo.execute_query("MATCH (n:Organization) RETURN COUNT(n)")["data"].first.first > 1
organizations = %w[Farm KFC Pepsi]
products = %w[chicken_raw chicken_fried softdrinks]
locations = %w[New\ York\ City Iowa]
cypher = "CREATE (n:Organization) SET n = {nodes} RETURN ID(n) AS id, n.name AS name"
nodes = []
organizations.each { |n| nodes << {"name" => n} }
organizations = hashify(neo.execute_query(cypher, {:nodes => nodes}))
cypher = "CREATE (n:Location) SET n = {nodes} RETURN ID(n) AS id, n.name AS name"
nodes = []
locations.each { |n| nodes << {"name" => n} }
locations = hashify(neo.execute_query(cypher, {:nodes => nodes}))
cypher = "CREATE (n:Product) SET n = {nodes} RETURN ID(n) AS id, n.name AS name"
nodes = []
products.each { |n| nodes << {"name" => n} }
products = hashify(neo.execute_query(cypher, {:nodes => nodes}))
neo.execute_query("CREATE INDEX ON :Organization(name)")
neo.execute_query("CREATE INDEX ON :Location(name)")
neo.execute_query("CREATE INDEX ON :Product(name)")
#C reating relationships manually:
commands = []
farm = organizations[0]
kfc = organizations[1]
pepsi = organizations[2]
nyc = locations[0]
iowa = locations[1]
chicken_raw = products[0]
chicken_fried = products[1]
softdrinks = products[2]
commands << [:create_relationship, "located_in", pepsi["id"], nyc["id"], nil]
commands << [:create_relationship, "located_in", kfc["id"], nyc["id"], nil]
commands << [:create_relationship, "located_in", farm["id"], iowa["id"], nil]
commands << [:create_relationship, "makes", farm["id"], chicken_raw["id"], nil]
commands << [:create_relationship, "makes", kfc["id"], chicken_fried["id"], nil]
commands << [:create_relationship, "makes", pepsi["id"], softdrinks["id"], nil]
commands << [:create_relationship, "buys", kfc["id"], chicken_raw["id"], nil]
commands << [:create_relationship, "buys", pepsi["id"], chicken_fried["id"], nil]
commands << [:create_relationship, "buys", kfc["id"], softdrinks["id"], nil]
commands << [:create_relationship, "buys", farm["id"], chicken_fried["id"], nil]
neo.batch *commands
end
helpers do
def link_to(url, text=url, opts={})
attributes = ""
opts.each { |key,value| attributes << key.to_s << "=\"" << value << "\" "}
"<a href=\"#{url}\" #{attributes}>#{text}</a>"
end
end
def node_id(node)
case node
when Hash
node["self"].split('/').last
when String
node.split('/').last
else
node
end
end
def get_properties(node)
properties = "<ul>"
node.each_pair do |key, value|
if key == "avatar_url"
properties << "<li><img src='#{value}'></li>"
else
properties << "<li><b>#{key}:</b> #{value}</li>"
end
end
properties + "</ul>"
end
get '/resources/show' do
content_type :json
cypher = "START me=node(#{params[:id]})
OPTIONAL MATCH me -[r]- related
RETURN me, r, related"
connections = neo.execute_query(cypher)["data"]
me = connections[0][0]["data"]
relationships = []
if connections[0][1]
connections.group_by{|group| group[1]["type"]}.each do |key,values|
relationships << {:id => key,
:name => key,
:values => values.collect{|n| n[2]["data"].merge({:id => node_id(n[2]) }) } }
end
end
relationships = [{"name" => "No Relationships","values" => [{"id" => "#{params[:id]}","name" => "No Relationships "}]}] if relationships.empty?
@node = {:details_html => "<h2>#{me["name"]}</h2>\n<p class='summary'>\n#{get_properties(me)}</p>\n",
:data => {:attributes => relationships,
:name => me["name"],
:id => params[:id]}
}
@node.to_json
end
get '/' do
create_graph
@neoid = params["neoid"] || 1
haml :index
end
end