mouth 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +7 -0
  2. data/Capfile +26 -0
  3. data/Gemfile +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +138 -0
  6. data/Rakefile +19 -0
  7. data/TODO +32 -0
  8. data/bin/mouth +77 -0
  9. data/bin/mouth-console +18 -0
  10. data/bin/mouth-endoscope +18 -0
  11. data/lib/mouth.rb +61 -0
  12. data/lib/mouth/dashboard.rb +25 -0
  13. data/lib/mouth/endoscope.rb +120 -0
  14. data/lib/mouth/endoscope/public/222222_256x240_icons_icons.png +0 -0
  15. data/lib/mouth/endoscope/public/application.css +464 -0
  16. data/lib/mouth/endoscope/public/application.js +938 -0
  17. data/lib/mouth/endoscope/public/backbone.js +1158 -0
  18. data/lib/mouth/endoscope/public/d3.js +4707 -0
  19. data/lib/mouth/endoscope/public/d3.time.js +687 -0
  20. data/lib/mouth/endoscope/public/jquery-ui-1.8.16.custom.min.js +177 -0
  21. data/lib/mouth/endoscope/public/jquery.js +4 -0
  22. data/lib/mouth/endoscope/public/json2.js +480 -0
  23. data/lib/mouth/endoscope/public/keymaster.js +163 -0
  24. data/lib/mouth/endoscope/public/linen.js +46 -0
  25. data/lib/mouth/endoscope/public/seven.css +68 -0
  26. data/lib/mouth/endoscope/public/seven.js +291 -0
  27. data/lib/mouth/endoscope/public/underscore.js +931 -0
  28. data/lib/mouth/endoscope/views/dashboard.erb +67 -0
  29. data/lib/mouth/graph.rb +58 -0
  30. data/lib/mouth/instrument.rb +56 -0
  31. data/lib/mouth/record.rb +72 -0
  32. data/lib/mouth/runner.rb +89 -0
  33. data/lib/mouth/sequence.rb +284 -0
  34. data/lib/mouth/source.rb +76 -0
  35. data/lib/mouth/sucker.rb +235 -0
  36. data/lib/mouth/version.rb +3 -0
  37. data/mouth.gemspec +28 -0
  38. data/test/sequence_test.rb +163 -0
  39. data/test/sucker_test.rb +55 -0
  40. data/test/test_helper.rb +5 -0
  41. metadata +167 -0
@@ -0,0 +1,120 @@
1
+ require 'sinatra/base'
2
+ require 'erb'
3
+ require 'yajl'
4
+
5
+ require 'mouth/sequence'
6
+ require 'mouth/record'
7
+ require 'mouth/graph'
8
+ require 'mouth/dashboard'
9
+ require 'mouth/source'
10
+
11
+ module Mouth
12
+ class Endoscope < Sinatra::Base
13
+
14
+ dir = File.dirname(File.expand_path(__FILE__))
15
+
16
+ set :views, "#{dir}/endoscope/views"
17
+ set :public_folder, "#{dir}/endoscope/public"
18
+
19
+ get '/' do
20
+ erb :dashboard
21
+ end
22
+
23
+ ##
24
+ ## Dashboard API
25
+ ##
26
+
27
+ # Returns all dashboards and all associated graphs.
28
+ # If a dashboard does not exist, creates one
29
+ get '/dashboards' do
30
+ dashboards = Dashboard.all
31
+ if dashboards.length == 0
32
+ dashboards = [Dashboard.create(:name => "Main")]
33
+ end
34
+
35
+ render_json(dashboards)
36
+ end
37
+
38
+ get '/dashboards/:id' do
39
+ erb :dashboard
40
+ end
41
+
42
+ post '/dashboards' do
43
+ d = Dashboard.create(json_input)
44
+ render_json(d)
45
+ end
46
+
47
+ put '/dashboards/:id' do
48
+ d = Dashboard.find(params[:id])
49
+ d.update(json_input)
50
+ render_json(d)
51
+ end
52
+
53
+ delete '/dashboards/:id' do
54
+ d = Dashboard.find(params[:id])
55
+ d.destroy
56
+ render_json(d)
57
+ end
58
+
59
+ ##
60
+ ## Graph API
61
+ ##
62
+
63
+ post '/graphs' do
64
+ g = Graph.create(json_input)
65
+ render_json(g)
66
+ end
67
+
68
+ put '/graphs/:id' do
69
+ g = Graph.find(params[:id])
70
+ g.update(json_input)
71
+ render_json(g)
72
+ end
73
+
74
+ get '/graphs/:id/data' do
75
+ opts = {
76
+ :start_time => params[:start_time] ? Time.at(params[:start_time].to_i) : Time.now - (119 * 60),
77
+ :end_time => params[:end_time] ? Time.at(params[:end_time].to_i) : Time.now,
78
+ :granularity_in_minutes => params[:granularity_in_minutes] ? params[:granularity_in_minutes].to_i : 1
79
+ }
80
+
81
+ d = Graph.find(params[:id]).data(opts)
82
+ content_type 'application/json'
83
+ Yajl::Encoder.encode(d)
84
+ end
85
+
86
+ delete '/graphs/:id' do
87
+ g = Graph.find(params[:id])
88
+ g.destroy
89
+ render_json(g)
90
+ end
91
+
92
+ ##
93
+ ## Data
94
+ ##
95
+
96
+ get '/sources' do
97
+ s = Source.all
98
+ render_json(s)
99
+ end
100
+
101
+ ##
102
+ ## Helpers
103
+ ##
104
+
105
+ def json_input
106
+ Yajl::Parser.parse(request.env["rack.input"].read)
107
+ end
108
+
109
+ def render_json(attributables)
110
+ content_type 'application/json'
111
+ encodable = if attributables.is_a?(Array)
112
+ attributables.collect(&:all_attributes)
113
+ else
114
+ attributables.all_attributes
115
+ end
116
+ Yajl::Encoder.encode(encodable)
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,464 @@
1
+ /* reset/_utilities.scss */
2
+ html, body, div, span, applet, object, iframe,
3
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
4
+ a, abbr, acronym, address, big, cite, code,
5
+ del, dfn, em, img, ins, kbd, q, s, samp,
6
+ small, strike, strong, sub, sup, tt, var,
7
+ b, u, i, center,
8
+ dl, dt, dd, ol, ul, li,
9
+ fieldset, form, label, legend,
10
+ table, caption, tbody, tfoot, thead, tr, th, td,
11
+ article, aside, canvas, details, embed,
12
+ figure, figcaption, footer, header, hgroup,
13
+ menu, nav, output, ruby, section, summary,
14
+ time, mark, audio, video {
15
+ margin: 0;
16
+ padding: 0;
17
+ border: 0;
18
+ font-size: 100%;
19
+ font: inherit;
20
+ vertical-align: baseline;
21
+ }
22
+
23
+ body {
24
+ line-height: 1;
25
+ }
26
+
27
+ ol, ul {
28
+ list-style: none;
29
+ }
30
+
31
+ table {
32
+ border-collapse: collapse;
33
+ border-spacing: 0;
34
+ }
35
+
36
+ caption, th, td {
37
+ text-align: left;
38
+ font-weight: normal;
39
+ vertical-align: middle;
40
+ }
41
+
42
+ q, blockquote {
43
+ quotes: none;
44
+ }
45
+
46
+ q:before, q:after, blockquote:before, blockquote:after {
47
+ content: "";
48
+ content: none;
49
+ }
50
+
51
+ a img {
52
+ border: none;
53
+ }
54
+
55
+ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
56
+ display: block;
57
+ }
58
+
59
+ /* typography/_vertical_rhythm.scss */
60
+ body {
61
+ font-size: 87.5%;
62
+ line-height: 1.571em;
63
+ }
64
+
65
+ /* typography/_vertical_rhythm.scss */
66
+ html > body {
67
+ font-size: 14px;
68
+ }
69
+
70
+ body {
71
+ font-family: sans-serif;
72
+ font-weight: 400;
73
+ color: #555;
74
+ background: #032b36;
75
+ }
76
+
77
+ /* jQuery resizeable styles */
78
+ .ui-resizable-handle {
79
+ position: absolute;
80
+ font-size: 0.1px;
81
+ z-index: 99999;
82
+ display: block;
83
+ }
84
+
85
+ .ui-resizable-e {
86
+ cursor: e-resize;
87
+ width: 7px;
88
+ right: -5px;
89
+ top: 0;
90
+ height: 100%;
91
+ }
92
+
93
+ .ui-resizable-s {
94
+ cursor: s-resize;
95
+ height: 7px;
96
+ width: 100%;
97
+ bottom: -5px;
98
+ left: 0;
99
+ }
100
+
101
+ .ui-icon-gripsmall-diagonal-se {
102
+ width: 16px;
103
+ height: 16px;
104
+ background-image: url(/222222_256x240_icons_icons.png);
105
+ background-position: -64px -224px;
106
+ cursor: se-resize;
107
+ right: 1px;
108
+ bottom: 1px;
109
+ text-indent: -99999px;
110
+ overflow: hidden;
111
+ background-repeat: no-repeat;
112
+ }
113
+
114
+ #mouth-header {
115
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #241200), color-stop(50%, #331a00), color-stop(100%, #241200));
116
+ background-image: -webkit-linear-gradient(top center, #241200, #331a00, #241200);
117
+ background-image: -moz-linear-gradient(top center, #241200, #331a00, #241200);
118
+ background-image: -o-linear-gradient(top center, #241200, #331a00, #241200);
119
+ background-image: -ms-linear-gradient(top center, #241200, #331a00, #241200);
120
+ background-image: linear-gradient(top center, #241200, #331a00, #241200);
121
+ color: #eee8d5;
122
+ padding: 5px 20px;
123
+ /* overflow: hidden;*/
124
+ *zoom: 1;
125
+ }
126
+
127
+ #mouth-header h1 {
128
+ float: left;
129
+ font-size: 1.429em;
130
+ line-height: 2.2em;
131
+ margin-right: 20px;
132
+ }
133
+
134
+ .add-dashboard {
135
+ color: #f2f2f2;
136
+ font-size: 1.429em;
137
+ line-height: 2.2em;
138
+ text-decoration: none;
139
+ text-shadow: 0 1px 0 black;
140
+ }
141
+
142
+ #dashboards ul {
143
+ float: left;
144
+ }
145
+
146
+ .dashboard-item {
147
+ float: left;
148
+ margin-right: 20px;
149
+ }
150
+
151
+ .dashboard-item-edit {
152
+ background-color: white;
153
+ border: 2px solid #212a3d;
154
+ position: relative;
155
+ height: 45px;
156
+ z-index: 3;
157
+ padding: 5px;
158
+ color: #555;
159
+ }
160
+
161
+ .dashboard-item-edit input {
162
+ border: 1px solid #CCCCCC;
163
+ border-radius: 3px 3px 3px 3px;
164
+ color: #555555;
165
+ display: inline-block;
166
+ font-size: 13px;
167
+ line-height: 18px;
168
+ }
169
+
170
+ .dashboard-item-edit .delete {
171
+ position:absolute;
172
+ height: 15px;
173
+ right: 3px;
174
+ bottom: 0px;
175
+ font-size: 11px;
176
+ line-height: 11px;
177
+ color: #222222;
178
+ text-decoration: underline;
179
+ text-shadow: none;
180
+ }
181
+
182
+ .dashboard-item-edit .cancel {
183
+ font-size: 12px;
184
+ line-height: 12px;
185
+ color: #222222;
186
+ text-decoration: underline;
187
+ text-shadow: none;
188
+ }
189
+
190
+ .dashboard-item a, .dashboard-item span {
191
+ color: #f2f2f2;
192
+ font-size: 1.429em;
193
+ line-height: 2.2em;
194
+ text-decoration: none;
195
+ text-shadow: 0 1px 0 black;
196
+ }
197
+
198
+ .dashboard-item.selected span {
199
+ color: #EEE8D5;
200
+ }
201
+
202
+ .dashboard-item .chooser {
203
+ cursor:pointer;
204
+ }
205
+
206
+ #info-panel {
207
+ border-top: 1px solid black;
208
+ position: absolute;
209
+ top: 53px;
210
+ left: 0;
211
+ bottom: 0;
212
+ width: 150px;
213
+ background-color: tan;
214
+ }
215
+
216
+ #date-range-picker .if-current {
217
+ display:none;
218
+ }
219
+ #date-range-picker .unless-current {
220
+ display:block;
221
+ }
222
+
223
+ #date-range-picker.current .if-current {
224
+ display:block;
225
+ }
226
+ #date-range-picker.current .unless-current {
227
+ display:none;
228
+ }
229
+
230
+ #date-range-picker {
231
+ -webkit-box-sizing: border-box;
232
+ -moz-box-sizing: border-box;
233
+ box-sizing: border-box;
234
+ padding: 4px;
235
+ color: black;
236
+ }
237
+
238
+ #date-range-picker h2 {
239
+ font-weight: bolder;
240
+ }
241
+
242
+ #date-range-picker .example {
243
+ font-size: 11px;
244
+ color: #666;
245
+ }
246
+
247
+ #current-dashboard {
248
+ border-top: 1px solid black;
249
+ position: absolute;
250
+ top: 53px;
251
+ left: 150px;
252
+ right: 0;
253
+ bottom: 0;
254
+ -moz-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.5);
255
+ -webkit-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.5);
256
+ -o-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.5);
257
+ box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.5);
258
+ }
259
+
260
+ #current-dashboard #grid {
261
+ position: absolute;
262
+ width: 100%;
263
+ height: 100%;
264
+ }
265
+ #grid .graph {
266
+ background: white;
267
+ background: #2e3a4f;
268
+ background: -moz-linear-gradient(top, #62769b 0%, #2e3a4f 35%, #2e3a4f 65%, #212a3d 100%);
269
+ }
270
+
271
+ #grid .graph.dimmed {
272
+ opacity: 0.7;
273
+ }
274
+
275
+ .graph-inner {
276
+ position: absolute;
277
+ top: 2px;
278
+ left: 2px;
279
+ bottom: 2px;
280
+ right: 2px;
281
+ background: white;
282
+
283
+ }
284
+
285
+ .graph-header {
286
+ cursor: move;
287
+ color: #330000;
288
+ font-weight: 700;
289
+ font-size: 11px;
290
+ line-height: 12px;
291
+ padding: 4px;
292
+ position: relative;
293
+ }
294
+
295
+ .graph-header .edit {
296
+ cursor: default;
297
+ position: absolute;
298
+ right: 5px;
299
+ text-decoration: none;
300
+ color: #222222;
301
+ }
302
+
303
+ .graph-body, .graph-back {
304
+ position: absolute;
305
+ top: 20px;
306
+ left: 0;
307
+ right: 0;
308
+ bottom: 0;
309
+ overflow:hidden;
310
+ }
311
+
312
+ .graph-body {
313
+ }
314
+
315
+ .graph-back .kind {
316
+ position: absolute;
317
+ top: 0; left: 0; width: 100%; height: 20px;
318
+ }
319
+
320
+ .graph-back .graph-sources {
321
+ position: absolute;
322
+ top: 20px; left: 0; width: 100%; bottom: 0px;
323
+ }
324
+
325
+ .graph-back .kind .kind-label, .graph-back .graph-sources .graph-sources-label {
326
+ float: left;
327
+ width: 70px;
328
+ text-align:right;
329
+ padding-right:10px;
330
+ }
331
+ .graph-back .kind .kind-value {
332
+ float: left;
333
+ }
334
+
335
+ .graph-back .graph-sources ul {
336
+ overflow-y: auto;
337
+ position:absolute;
338
+ min-width: 200px;
339
+ top: 0;
340
+ bottom: 20px;
341
+ left: 80px;
342
+ clear:both;
343
+ }
344
+
345
+ .graph-back .graph-sources .pick-item {
346
+ }
347
+
348
+ .graph-back .delete {
349
+ position: absolute;
350
+ height: 22px;
351
+ left: 0;
352
+ bottom: 0;
353
+ width: 60px;
354
+ }
355
+
356
+ .add-graph {
357
+ display: block;
358
+ position: absolute;
359
+ bottom: 10px;
360
+ right: 10px;
361
+ text-decoration: none;
362
+ color: #eee8d5;
363
+ }
364
+
365
+ .source-list {
366
+ -webkit-box-sizing: border-box;
367
+ -moz-box-sizing: border-box;
368
+ box-sizing: border-box;
369
+ border: 2px solid #212a3d;
370
+ display: block;
371
+ position: absolute;
372
+ top: 0px;
373
+ width: 40%;
374
+ min-height: 200px;
375
+ background-color: white;
376
+ color: #555;
377
+ }
378
+
379
+ .source-list.left {
380
+ left: 0;
381
+ }
382
+ .source-list.right {
383
+ right: 0;
384
+ }
385
+
386
+ .source-list .head {
387
+ position: relative;
388
+ -webkit-box-sizing: border-box;
389
+ -moz-box-sizing: border-box;
390
+ box-sizing: border-box;
391
+ padding: 4px;
392
+ height: 26px;
393
+ }
394
+
395
+ .source-list .head h2 {
396
+
397
+ }
398
+
399
+ .source-list a.cancel {
400
+ display: block;
401
+ position: absolute;
402
+ width: 23px;
403
+ height: 23px;
404
+ padding-right: 4px;
405
+ text-align: right;
406
+ top: 0;
407
+ right: 0;
408
+ }
409
+
410
+
411
+ .source-list .head input {
412
+ -webkit-box-sizing: border-box;
413
+ -moz-box-sizing: border-box;
414
+ box-sizing: border-box;
415
+ border: 1px solid #CCCCCC;
416
+ border-radius: 3px 3px 3px 3px;
417
+ color: #555555;
418
+ display: inline-block;
419
+ font-size: 13px;
420
+ height: 26px;
421
+ line-height: 18px;
422
+ padding: 4px;
423
+ width: 100%;
424
+ }
425
+
426
+ .source-list ul {
427
+ overflow-y: auto;
428
+ position: absolute;
429
+ width: 100%;
430
+ top: 26px;
431
+ bottom: 30px;
432
+ }
433
+
434
+ .source-list ul .source-item {
435
+ padding: 2px;
436
+ }
437
+
438
+ .source-list ul .source-item.no-data {
439
+ padding: 6px;
440
+ color: #CCC;
441
+ }
442
+
443
+
444
+ .source-list ul label {
445
+ display: block;
446
+ }
447
+ .source-list ul label:hover {
448
+ background-color: #DDF;
449
+ }
450
+
451
+ .source-list .foot {
452
+ -webkit-box-sizing: border-box;
453
+ -moz-box-sizing: border-box;
454
+ box-sizing: border-box;
455
+ position: absolute;
456
+ bottom: 0px;
457
+ width: 100%;
458
+ height: 30px;
459
+ padding: 4px;
460
+ }
461
+
462
+ .source-list .foot button {
463
+ float: right;
464
+ }