red_grape 0.0.13 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +35 -0
- data/bin/juicer +30 -3
- data/lib/red_grape.rb +1 -1
- data/public/cellar/graph.html +127 -16
- metadata +4 -4
data/README.md
CHANGED
@@ -96,6 +96,41 @@ In REPL, the `take' method which invokes all pipes is automatically called.
|
|
96
96
|
|
97
97
|
Changes on a graph are not committed until the put_graph method is called.
|
98
98
|
|
99
|
+
## REST API:
|
100
|
+
|
101
|
+
Start the server:
|
102
|
+
|
103
|
+
$ ./bin/juicer
|
104
|
+
[2012-06-30 02:03:01] INFO WEBrick 1.3.1
|
105
|
+
[2012-06-30 02:03:01] INFO ruby 1.9.3 (2011-10-30) [x86_64-darwin11.0.1]
|
106
|
+
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from WEBrick
|
107
|
+
[2012-06-30 02:03:01] INFO WEBrick::HTTPServer#start: pid=12098 port=4567
|
108
|
+
|
109
|
+
Access:
|
110
|
+
|
111
|
+
$ curl http://localhost:4567/graphs
|
112
|
+
{
|
113
|
+
"version": "0.1.0",
|
114
|
+
"name": "Juicer: A Graph Server",
|
115
|
+
"graphs": [
|
116
|
+
"tinkergraph"
|
117
|
+
]
|
118
|
+
}
|
119
|
+
$ curl http://localhost:4567/graphs/tinkergraph/vertices/1
|
120
|
+
{
|
121
|
+
"version": "0.1.0",
|
122
|
+
"results": {
|
123
|
+
"_type": "_vertex",
|
124
|
+
"_id": "1",
|
125
|
+
"name": "marko",
|
126
|
+
"age": 29
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
### Graph Viewer:
|
131
|
+
|
132
|
+
http://localhost:4567/cellar/index.html
|
133
|
+
|
99
134
|
## Requirements:
|
100
135
|
|
101
136
|
* Nokogiri (http://nokogiri.org/)
|
data/bin/juicer
CHANGED
@@ -52,10 +52,10 @@ get '/' do
|
|
52
52
|
],
|
53
53
|
POST: [
|
54
54
|
#'/graphs/[graph]/vertices',
|
55
|
-
|
56
|
-
|
55
|
+
'/graphs/[graph]/vertices/[vertex]',
|
56
|
+
'/graphs/[graph]/vertices/[vertex]?[key1]=[value1]&[key2]=[value2]',
|
57
57
|
#'/graphs/[graph]/edges?_outV=[vertex1]&_label=[label]&_inV=[vertex2]&[key1]=[value1]&=[key2]=[value2]',
|
58
|
-
|
58
|
+
'/graphs/[graph]/edges/[edge]?_outV=[vertex1]&_label=[label]&_inV=[vertex2]&[key1]=[value1]&=[key2]=[value2]',
|
59
59
|
#'/graphs/[graph]/edges/[edge]?[key1]=[key2]'
|
60
60
|
],
|
61
61
|
PUT: [
|
@@ -127,3 +127,30 @@ get %r{/graphs/([^/]+)/vertices/([^/]+)/(out_e|in_e|both_e|outE|inE|bothE)/?$} d
|
|
127
127
|
vertex.send(dir)[].map(&:to_h).to_pretty_json
|
128
128
|
end
|
129
129
|
end
|
130
|
+
|
131
|
+
=begin
|
132
|
+
post %r{/graphs/([^/]+)/vertices/?$} do |graph_id|
|
133
|
+
params['splat'] = nil
|
134
|
+
params['captures'] = nil
|
135
|
+
graph = graphs[graph_id]
|
136
|
+
end
|
137
|
+
=end
|
138
|
+
|
139
|
+
post %r{/graphs/([^/]+)/vertices/([^/]+)/?$} do |graph_id, vertex_id|
|
140
|
+
params.delete 'splat'
|
141
|
+
params.delete 'captures'
|
142
|
+
graph = graphs[graph_id]
|
143
|
+
vertex = graph.add_vertex vertex_id, params
|
144
|
+
vertex.to_h.to_pretty_json
|
145
|
+
end
|
146
|
+
|
147
|
+
post %r{/graphs/([^/]+)/edges/([^/]+)/?$} do |graph_id, edge_id|
|
148
|
+
params.delete 'splat'
|
149
|
+
params.delete 'captures'
|
150
|
+
label = params.delete '_label'
|
151
|
+
source = params.delete '_outV'
|
152
|
+
target = params.delete '_inV'
|
153
|
+
graph = graphs[graph_id]
|
154
|
+
edge = graph.add_edge edge_id, source, target, label, params
|
155
|
+
edge.to_h.to_pretty_json
|
156
|
+
end
|
data/lib/red_grape.rb
CHANGED
data/public/cellar/graph.html
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<title>Force-Directed Layout</title>
|
5
|
+
<script src="/js/jquery-1.7.2.min.js"></script>
|
5
6
|
<!--script type='text/javascript' src='/js/d3.v3.js'></script-->
|
6
7
|
<script type='text/javascript' src='/js/d3.v2.js'></script>
|
7
8
|
<style type='text/css'>
|
@@ -46,7 +47,7 @@ div.graph {
|
|
46
47
|
height:auto;
|
47
48
|
}
|
48
49
|
|
49
|
-
|
50
|
+
aside {
|
50
51
|
position:absolute;
|
51
52
|
top:0;
|
52
53
|
left:0;
|
@@ -57,7 +58,7 @@ div.inspector {
|
|
57
58
|
box-shadow: -2px 2px 3px #888 inset;
|
58
59
|
}
|
59
60
|
|
60
|
-
|
61
|
+
aside h2 {
|
61
62
|
margin:0;
|
62
63
|
padding-left:10px;
|
63
64
|
margin-top:10px;
|
@@ -67,7 +68,7 @@ div.inspector h2 {
|
|
67
68
|
color:white;
|
68
69
|
}
|
69
70
|
|
70
|
-
div.inspector dt {
|
71
|
+
aside div.inspector dt {
|
71
72
|
border-bottom:1px solid gray;
|
72
73
|
display:block;
|
73
74
|
width:80px;
|
@@ -76,23 +77,40 @@ div.inspector dt {
|
|
76
77
|
font-weight:bold;
|
77
78
|
}
|
78
79
|
|
79
|
-
div.inspector dd {
|
80
|
+
aside div.inspector dd {
|
80
81
|
border-bottom:1px solid gray;
|
81
82
|
display:block;
|
82
83
|
width:160px;
|
83
84
|
height:auto;
|
84
85
|
}
|
86
|
+
|
87
|
+
aside select {
|
88
|
+
margin:10px;
|
89
|
+
width:160px;
|
90
|
+
}
|
91
|
+
|
92
|
+
aside button {
|
93
|
+
margin-left:10px;
|
94
|
+
width:160px;
|
95
|
+
}
|
96
|
+
|
97
|
+
aside label {
|
98
|
+
margin-left:10px;
|
99
|
+
}
|
100
|
+
|
101
|
+
aside input {
|
102
|
+
margin-left:10px;
|
103
|
+
width:160px;
|
104
|
+
}
|
105
|
+
|
106
|
+
aside textarea {
|
107
|
+
margin-left:10px;
|
108
|
+
width:160px;
|
109
|
+
}
|
85
110
|
</style>
|
86
111
|
</head>
|
87
112
|
<body>
|
88
113
|
<script type='text/javascript'>
|
89
|
-
function isIn(array, key) {
|
90
|
-
for (var i in array) {
|
91
|
-
if (array[i] == key) return true
|
92
|
-
}
|
93
|
-
return false;
|
94
|
-
}
|
95
|
-
|
96
114
|
var height = window.document.body.scrollHeight;
|
97
115
|
var width = window.document.body.scrollWidth - 200;
|
98
116
|
var graphId = window.location.hash.substring(1);
|
@@ -108,6 +126,72 @@ var vis = d3.select('body').append('div')
|
|
108
126
|
.style('width', width + 'px')
|
109
127
|
.style('height', height + 'px');
|
110
128
|
|
129
|
+
$(function() {
|
130
|
+
$('#element').change(function(evt) {
|
131
|
+
if ($('#element').val() == 'vertex') {
|
132
|
+
$('#vertex').css('display', 'block');
|
133
|
+
$('#edge').css('display', 'none');
|
134
|
+
}
|
135
|
+
else {
|
136
|
+
$('#vertex').css('display', 'none');
|
137
|
+
$('#edge').css('display', 'block');
|
138
|
+
}
|
139
|
+
});
|
140
|
+
|
141
|
+
$('#vbutton').click(function(evt) {
|
142
|
+
var id = $('#vid').val();
|
143
|
+
if (!id) return; // TODO
|
144
|
+
var params = {};
|
145
|
+
var pairs = $('#vprop').val().split('\n')
|
146
|
+
for (var i in pairs) {
|
147
|
+
var kv = pairs[i].split('=');
|
148
|
+
params[kv[0]] = kv[1];
|
149
|
+
}
|
150
|
+
$.post(
|
151
|
+
'/graphs/' + 'tinkergraph' + '/vertices/' + id,
|
152
|
+
params,
|
153
|
+
function(data) {
|
154
|
+
window.location.reload(); // TODO
|
155
|
+
//vertices.push(data.results);
|
156
|
+
//force.stop();
|
157
|
+
//force.start();
|
158
|
+
}
|
159
|
+
);
|
160
|
+
});
|
161
|
+
|
162
|
+
$('#ebutton').click(function(evt) {
|
163
|
+
var id = $('#eid').val(); if (!id) return; // TODO
|
164
|
+
var label = $('#label').val(); if (!label) return; // TODO
|
165
|
+
var source = $('#source').val(); if (!source) return; // TODO
|
166
|
+
var target = $('#target').val(); if (!target) return; // TODO
|
167
|
+
var params = {
|
168
|
+
_outV:target,
|
169
|
+
_inV:source,
|
170
|
+
_label:label
|
171
|
+
};
|
172
|
+
var pairs = $('#eprop').val().split('\n')
|
173
|
+
for (var i in pairs) {
|
174
|
+
var kv = pairs[i].split('=');
|
175
|
+
params[kv[0]] = kv[1];
|
176
|
+
}
|
177
|
+
$.post(
|
178
|
+
'/graphs/' + 'tinkergraph' + '/edges/' + id,
|
179
|
+
params,
|
180
|
+
function(data) {
|
181
|
+
window.location.reload(); // TODO
|
182
|
+
}
|
183
|
+
);
|
184
|
+
});
|
185
|
+
});
|
186
|
+
|
187
|
+
|
188
|
+
function isIn(array, key) {
|
189
|
+
for (var i in array) {
|
190
|
+
if (array[i] == key) return true
|
191
|
+
}
|
192
|
+
return false;
|
193
|
+
}
|
194
|
+
|
111
195
|
/*
|
112
196
|
setTimeout(function() {
|
113
197
|
force.linkDistance(30);
|
@@ -171,7 +255,7 @@ d3.json('/graphs/' + graphId + '/vertices', function(json) {
|
|
171
255
|
props += '<dt>' + k + '</dt><dd>' + d[k] + '</dd>';
|
172
256
|
}
|
173
257
|
}
|
174
|
-
d3.select('.inspector').html('<
|
258
|
+
d3.select('.inspector').html('<dl>' + props + '</dl>');
|
175
259
|
})
|
176
260
|
.call(force.drag);
|
177
261
|
|
@@ -212,9 +296,36 @@ d3.json('/graphs/' + graphId + '/vertices', function(json) {
|
|
212
296
|
});
|
213
297
|
});
|
214
298
|
</script>
|
215
|
-
<
|
216
|
-
<h2>Properties</h2>
|
217
|
-
|
218
|
-
|
299
|
+
<aside>
|
300
|
+
<h2>View Properties</h2>
|
301
|
+
<div class='inspector'>
|
302
|
+
Click a node.
|
303
|
+
</div>
|
304
|
+
<h2>Add Element</h2>
|
305
|
+
<select id="element">
|
306
|
+
<option value="vertex" selected>Vertex</option>
|
307
|
+
<option value="edge">Edge</option>
|
308
|
+
</select>
|
309
|
+
<div id="vertex">
|
310
|
+
<label for="vid">ID</label><br/>
|
311
|
+
<input id="vid" name="vid"></input><br/>
|
312
|
+
<label for="vprop">Properties</label><br/>
|
313
|
+
<textarea id="vprop" name="vprop"></textarea>
|
314
|
+
<button id="vbutton">Create</button>
|
315
|
+
</div>
|
316
|
+
<div id="edge" style="display:none">
|
317
|
+
<label for="eid">ID</label><br/>
|
318
|
+
<input id="eid" name="eid"></input><br/>
|
319
|
+
<label for="label">Label<strong>*</strong></label><br/>
|
320
|
+
<input id="label" name="label"></input><br/>
|
321
|
+
<label for="source">Source<strong>*</strong></label><br/>
|
322
|
+
<input id="source" name="source"></input><br/>
|
323
|
+
<label for="target">Target<strong>*</strong></label><br/>
|
324
|
+
<input id="target" name="target"></input><br/>
|
325
|
+
<label for="eprop">Properties</label><br/>
|
326
|
+
<textarea id="eprop" name="eprop"></textarea>
|
327
|
+
<button id="ebutton">Create</button>
|
328
|
+
</div>
|
329
|
+
</aside>
|
219
330
|
</body>
|
220
331
|
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: red_grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &70331117724260 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70331117724260
|
25
25
|
description: RedGrape is an in-memory graph database written in ruby. I made this
|
26
26
|
in order to learn how graph databases work so that please do not use this for any
|
27
27
|
serious purpose.
|