1
+ require 'sinatra'
2
+ require 'sinatra/content_for'
3
+ require 'rufus/scheduler'
4
+ require 'coffee-script'
5
+ require 'sass'
6
+ require 'json'
7
+
8
+ Dir [ File . join ( Dir . pwd , 'lib/**/*.rb' ) ] . each { |file | require file }
9
+
10
+ SCHEDULER = Rufus ::Scheduler . start_new
11
+
12
+ set server : 'thin' , connections : [ ] , history : { }
13
+ helpers Sinatra ::ContentFor
14
+
15
+ def configure ( &block )
16
+ set :public_folder , Dir . pwd + '/public'
17
+ set :views , Dir . pwd + '/dashboards'
18
+ set :default_dashboard , nil
19
+ instance_eval ( &block )
20
+ end
21
+
22
+ get '/events' , provides : 'text/event-stream' do
23
+ stream :keep_open do |out |
24
+ settings . connections << out
25
+ out << latest_events
26
+ out . callback { settings . connections . delete ( out ) }
27
+ end
28
+ end
29
+
30
+ get '/' do
31
+ begin
32
+ redirect "/" + ( settings . default_dashboard || first_dashboard ) . to_s
33
+ rescue NoMethodError => e
34
+ raise Exception . new ( "There are no dashboards in your dashboard directory." )
35
+ end
36
+ end
37
+
38
+ get '/:dashboard' do
39
+ erb params [ :dashboard ] . to_sym
40
+ end
41
+
42
+ get '/views/:widget?.html' do
43
+ widget = params [ :widget ]
44
+ send_file File . join ( Dir . pwd , "widgets/#{ widget } /#{ widget } .html" )
45
+ end
46
+
47
+ post '/widgets/:id' do
48
+ request . body . rewind
49
+ body = JSON . parse ( request . body . read )
50
+ auth_token = body . delete ( "auth_token" )
51
+ if auth_token == settings . auth_token
52
+ send_event ( params [ 'id' ] , body )
53
+ 204 # response without entity body
54
+ else
55
+ status 401
56
+ "Invalid API key\n "
57
+ end
58
+ end
59
+
60
+ def framework_javascripts
61
+ [ 'jquery.js' , 'es5-shim.js' , 'batman.js' , 'batman.jquery.js' , 'application.coffee' , 'widget.coffee' ] . collect do |f |
62
+ File . join ( File . expand_path ( "../../vendor/javascripts" , __FILE__ ) , f )
63
+ end
64
+ end
65
+
66
+ def widget_javascripts
67
+ asset_paths ( "/widgets/**/*.coffee" )
68
+ end
69
+
70
+ def javascripts
71
+ ( framework_javascripts + widget_javascripts ) . collect do |f |
72
+ if File . extname ( f ) == ".coffee"
73
+ begin
74
+ CoffeeScript . compile ( File . read ( f ) )
75
+ rescue ExecJS ::ProgramError => e
76
+ message = e . message + ": in #{ f } "
77
+ raise ExecJS ::ProgramError . new ( message )
78
+ end
79
+ else
80
+ File . read ( f )
81
+ end
82
+ end . join ( "\n " )
83
+ end
84
+
85
+ def stylesheets
86
+ asset_paths ( "/public/**/*.scss" , "/widgets/**/*.scss" ) . collect do |f |
87
+ Sass . compile File . read ( f )
88
+ end . join ( "\n " )
89
+ end
90
+
91
+ def asset_paths ( *paths )
92
+ paths . inject ( [ ] ) { |arr , path | arr + Dir [ File . join ( Dir . pwd , path ) ] }
93
+ end
94
+
95
+ def send_event ( id , body )
96
+ body [ "id" ] = id
97
+ event = format_event ( JSON . unparse ( body ) )
98
+ settings . history [ id ] = event
99
+ settings . connections . each { |out | out << event }
100
+ end
101
+
102
+ def format_event ( body )
103
+ "data: #{ body } \n \n "
104
+ end
105
+
106
+ def latest_events
107
+ settings . history . inject ( "" ) do |str , ( id , body ) |
108
+ str << body
109
+ end
110
+ end
111
+
112
+ def first_dashboard
113
+ files = Dir [ settings . views + "/*.erb" ] . collect { |f | f . match ( /(\w *).erb/ ) [ 1 ] }
114
+ files -= [ 'layout' ]
115
+ files . first
116
+ end
117
+
118
+ files = Dir [ Dir . pwd + '/jobs/*.rb' ]
119
+ files . each { |job | require ( job ) }
0 commit comments