|
1 |
| -require 'sinatra' |
2 |
| -require 'sprockets' |
3 |
| -require 'sinatra/content_for' |
4 |
| -require 'rufus/scheduler' |
5 |
| -require 'coffee-script' |
6 |
| -require 'sass' |
7 |
| -require 'json' |
8 |
| -require 'yaml' |
9 |
| - |
10 | 1 | require 'dashing/cli'
|
11 | 2 | require 'dashing/downloader'
|
| 3 | +require 'dashing/app' |
12 | 4 |
|
13 |
| -SCHEDULER = Rufus::Scheduler.new |
14 |
| - |
15 |
| -set :root, Dir.pwd |
16 |
| - |
17 |
| -set :sprockets, Sprockets::Environment.new(settings.root) |
18 |
| -set :assets_prefix, '/assets' |
19 |
| -set :digest_assets, false |
20 |
| -['assets/javascripts', 'assets/stylesheets', 'assets/fonts', 'assets/images', 'widgets', File.expand_path('../../javascripts', __FILE__)]. each do |path| |
21 |
| - settings.sprockets.append_path path |
22 |
| -end |
23 |
| - |
24 |
| -set server: 'thin', connections: [], history_file: 'history.yml' |
25 |
| - |
26 |
| -# Persist history in tmp file at exit |
27 |
| -at_exit do |
28 |
| - File.open(settings.history_file, 'w') do |f| |
29 |
| - f.puts settings.history.to_yaml |
30 |
| - end |
31 |
| -end |
32 |
| - |
33 |
| -if File.exists?(settings.history_file) |
34 |
| - set history: YAML.load_file(settings.history_file) |
35 |
| -else |
36 |
| - set history: {} |
37 |
| -end |
38 |
| - |
39 |
| -set :public_folder, File.join(settings.root, 'public') |
40 |
| -set :views, File.join(settings.root, 'dashboards') |
41 |
| -set :default_dashboard, nil |
42 |
| -set :auth_token, nil |
43 |
| - |
44 |
| -helpers Sinatra::ContentFor |
45 |
| -helpers do |
46 |
| - def protected! |
47 |
| - # override with auth logic |
48 |
| - end |
49 |
| -end |
50 |
| - |
51 |
| -get '/events', provides: 'text/event-stream' do |
52 |
| - protected! |
53 |
| - response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx |
54 |
| - stream :keep_open do |out| |
55 |
| - settings.connections << out |
56 |
| - out << latest_events |
57 |
| - out.callback { settings.connections.delete(out) } |
58 |
| - end |
59 |
| -end |
60 |
| - |
61 |
| -get '/' do |
62 |
| - protected! |
63 |
| - begin |
64 |
| - redirect "/" + (settings.default_dashboard || first_dashboard).to_s |
65 |
| - rescue NoMethodError => e |
66 |
| - raise Exception.new("There are no dashboards in your dashboard directory.") |
67 |
| - end |
68 |
| -end |
69 |
| - |
70 |
| -get '/:dashboard' do |
71 |
| - protected! |
72 |
| - tilt_html_engines.each do |suffix, _| |
73 |
| - file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}") |
74 |
| - return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file |
75 |
| - end |
76 |
| - |
77 |
| - halt 404 |
78 |
| -end |
79 |
| - |
80 |
| -get '/views/:widget?.html' do |
81 |
| - protected! |
82 |
| - tilt_html_engines.each do |suffix, engines| |
83 |
| - file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}") |
84 |
| - return engines.first.new(file).render if File.exist? file |
85 |
| - end |
86 |
| -end |
87 |
| - |
88 |
| -post '/dashboards/:id' do |
89 |
| - request.body.rewind |
90 |
| - body = JSON.parse(request.body.read) |
91 |
| - body['dashboard'] ||= params['id'] |
92 |
| - auth_token = body.delete("auth_token") |
93 |
| - if !settings.auth_token || settings.auth_token == auth_token |
94 |
| - send_event(params['id'], body, 'dashboards') |
95 |
| - 204 # response without entity body |
96 |
| - else |
97 |
| - status 401 |
98 |
| - "Invalid API key\n" |
99 |
| - end |
| 5 | +module Dashing |
100 | 6 | end
|
101 |
| - |
102 |
| -post '/widgets/:id' do |
103 |
| - request.body.rewind |
104 |
| - body = JSON.parse(request.body.read) |
105 |
| - auth_token = body.delete("auth_token") |
106 |
| - if !settings.auth_token || settings.auth_token == auth_token |
107 |
| - send_event(params['id'], body) |
108 |
| - 204 # response without entity body |
109 |
| - else |
110 |
| - status 401 |
111 |
| - "Invalid API key\n" |
112 |
| - end |
113 |
| -end |
114 |
| - |
115 |
| -not_found do |
116 |
| - send_file File.join(settings.public_folder, '404.html') |
117 |
| -end |
118 |
| - |
119 |
| -def development? |
120 |
| - ENV['RACK_ENV'] == 'development' |
121 |
| -end |
122 |
| - |
123 |
| -def production? |
124 |
| - ENV['RACK_ENV'] == 'production' |
125 |
| -end |
126 |
| - |
127 |
| -def send_event(id, body, target=nil) |
128 |
| - body[:id] = id |
129 |
| - body[:updatedAt] ||= Time.now.to_i |
130 |
| - event = format_event(body.to_json, target) |
131 |
| - Sinatra::Application.settings.history[id] = event unless target == 'dashboards' |
132 |
| - Sinatra::Application.settings.connections.each { |out| out << event } |
133 |
| -end |
134 |
| - |
135 |
| -def format_event(body, name=nil) |
136 |
| - str = "" |
137 |
| - str << "event: #{name}\n" if name |
138 |
| - str << "data: #{body}\n\n" |
139 |
| -end |
140 |
| - |
141 |
| -def latest_events |
142 |
| - settings.history.inject("") do |str, (id, body)| |
143 |
| - str << body |
144 |
| - end |
145 |
| -end |
146 |
| - |
147 |
| -def first_dashboard |
148 |
| - files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') } |
149 |
| - files -= ['layout'] |
150 |
| - files.sort.first |
151 |
| -end |
152 |
| - |
153 |
| -def tilt_html_engines |
154 |
| - Tilt.mappings.select do |_, engines| |
155 |
| - default_mime_type = engines.first.default_mime_type |
156 |
| - default_mime_type.nil? || default_mime_type == 'text/html' |
157 |
| - end |
158 |
| -end |
159 |
| - |
160 |
| -settings_file = File.join(settings.root, 'config/settings.rb') |
161 |
| -if (File.exists?(settings_file)) |
162 |
| - require settings_file |
163 |
| -end |
164 |
| - |
165 |
| -Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } |
166 |
| -{}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. |
167 |
| - |
168 |
| -job_path = ENV["JOB_PATH"] || 'jobs' |
169 |
| -files = Dir[File.join(settings.root, job_path, '**', '/*.rb')] |
170 |
| -files.each { |job| require(job) } |
0 commit comments