From 780fe49f715c2fced88e958b02541bf8e7dca934 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Wed, 8 Aug 2012 18:02:56 -0400 Subject: Rename project to 'Dashing', and do some other cleanups --- lib/dashing.rb | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 lib/dashing.rb (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb new file mode 100644 index 0000000..8b2af2f --- /dev/null +++ b/lib/dashing.rb @@ -0,0 +1,126 @@ +require 'sinatra' +require 'sinatra/content_for' +require 'rufus/scheduler' +require 'coffee-script' +require 'sass' +require 'json' + +SCHEDULER = Rufus::Scheduler.start_new + +set server: 'thin', connections: [], history: {} +set :public_folder, File.join(Dir.pwd, 'public') +set :views, File.join(Dir.pwd, 'dashboards') +set :default_dashboard, nil +set :auth_token, nil + +helpers Sinatra::ContentFor +helpers do + def protected! + # override with auth logic + end +end + +get '/events', provides: 'text/event-stream' do + protected! + stream :keep_open do |out| + settings.connections << out + out << latest_events + out.callback { settings.connections.delete(out) } + end +end + +get '/' do + begin + redirect "/" + (settings.default_dashboard || first_dashboard).to_s + rescue NoMethodError => e + raise Exception.new("There are no dashboards in your dashboard directory.") + end +end + +get '/:dashboard' do + protected! + erb params[:dashboard].to_sym +end + +get '/views/:widget?.html' do + protected! + widget = params[:widget] + send_file File.join(Dir.pwd, 'widgets', widget, "#{widget}.html") +end + +post '/widgets/:id' do + request.body.rewind + body = JSON.parse(request.body.read) + auth_token = body.delete("auth_token") + if !settings.auth_token || settings.auth_token == auth_token + send_event(params['id'], body) + 204 # response without entity body + else + status 401 + "Invalid API key\n" + end +end + +def framework_javascripts + ['jquery.js', 'es5-shim.js', 'batman.js', 'batman.jquery.js', 'application.coffee', 'widget.coffee'].collect do |f| + File.join(File.expand_path('../../vendor/javascripts', __FILE__), f) + end +end + +def widget_javascripts + asset_paths("/widgets/**/*.coffee") +end + +def javascripts + (framework_javascripts + widget_javascripts).collect do |f| + if File.extname(f) == ".coffee" + begin + CoffeeScript.compile(File.read(f)) + rescue ExecJS::ProgramError => e + message = e.message + ": in #{f}" + raise ExecJS::ProgramError.new(message) + end + else + File.read(f) + end + end.join("\n") +end + +def stylesheets + asset_paths("/public/**/*.scss", "/widgets/**/*.scss").collect do |f| + Sass.compile File.read(f) + end.join("\n") +end + +def asset_paths(*paths) + paths.inject([]) { |arr, path| arr + Dir[File.join(Dir.pwd, path)] } +end + +def send_event(id, body) + body["id"] = id + event = format_event(JSON.unparse(body)) + settings.history[id] = event + settings.connections.each { |out| out << event } +end + +def format_event(body) + "data: #{body}\n\n" +end + +def latest_events + settings.history.inject("") do |str, (id, body)| + str << body + end +end + +def first_dashboard + files = Dir[File.join(settings.views, '*.erb')].collect { |f| f.match(/(\w*).erb/)[1] } + files -= ['layout'] + files.first +end + +Dir[File.join(Dir.pwd, 'lib', '**', '*.rb')].each {|file| require file } + +job_path = ENV["JOB_PATH"] || 'jobs' +files = Dir[File.join(Dir.pwd, job_path, '/*.rb')] +files.each { |job| require(job) } \ No newline at end of file -- cgit v1.2.3 From 16f51fd9dc454b26d9866b080caa17ffe2f8ce27 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Mon, 13 Aug 2012 23:36:38 -0400 Subject: Updated to use sprockets! Ah, much cleaner. --- lib/dashing.rb | 57 ++++++++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 37 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 8b2af2f..ee7cd1f 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -1,4 +1,5 @@ require 'sinatra' +require 'sprockets' require 'sinatra/content_for' require 'rufus/scheduler' require 'coffee-script' @@ -7,9 +8,18 @@ require 'json' SCHEDULER = Rufus::Scheduler.start_new +set :root, Dir.pwd + +set :sprockets, Sprockets::Environment.new(settings.root) +set :assets_prefix, '/assets' +set :digest_assets, false +['assets/javascripts', 'assets/stylesheets', 'assets/fonts', 'assets/images', 'widgets', File.expand_path('../../javascripts', __FILE__)]. each do |path| + settings.sprockets.append_path path +end + set server: 'thin', connections: [], history: {} -set :public_folder, File.join(Dir.pwd, 'public') -set :views, File.join(Dir.pwd, 'dashboards') +set :public_folder, File.join(settings.root, 'public') +set :views, File.join(settings.root, 'dashboards') set :default_dashboard, nil set :auth_token, nil @@ -45,7 +55,7 @@ end get '/views/:widget?.html' do protected! widget = params[:widget] - send_file File.join(Dir.pwd, 'widgets', widget, "#{widget}.html") + send_file File.join(settings.root, 'widgets', widget, "#{widget}.html") end post '/widgets/:id' do @@ -61,39 +71,12 @@ post '/widgets/:id' do end end -def framework_javascripts - ['jquery.js', 'es5-shim.js', 'batman.js', 'batman.jquery.js', 'application.coffee', 'widget.coffee'].collect do |f| - File.join(File.expand_path('../../vendor/javascripts', __FILE__), f) - end -end - -def widget_javascripts - asset_paths("/widgets/**/*.coffee") -end - -def javascripts - (framework_javascripts + widget_javascripts).collect do |f| - if File.extname(f) == ".coffee" - begin - CoffeeScript.compile(File.read(f)) - rescue ExecJS::ProgramError => e - message = e.message + ": in #{f}" - raise ExecJS::ProgramError.new(message) - end - else - File.read(f) - end - end.join("\n") -end - -def stylesheets - asset_paths("/public/**/*.scss", "/widgets/**/*.scss").collect do |f| - Sass.compile File.read(f) - end.join("\n") +def development? + ENV['RACK_ENV'] == 'development' end -def asset_paths(*paths) - paths.inject([]) { |arr, path| arr + Dir[File.join(Dir.pwd, path)] } +def production? + ENV['RACK_ENV'] == 'production' end def send_event(id, body) @@ -119,8 +102,8 @@ def first_dashboard files.first end -Dir[File.join(Dir.pwd, 'lib', '**', '*.rb')].each {|file| require file } +Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } job_path = ENV["JOB_PATH"] || 'jobs' -files = Dir[File.join(Dir.pwd, job_path, '/*.rb')] -files.each { |job| require(job) } \ No newline at end of file +files = Dir[File.join(settings.root, job_path, '/*.rb')] +files.each { |job| require(job) } -- cgit v1.2.3 From 372ee8475ef9b685e8cd3b8dea2e0475d5a4bd6b Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Fri, 24 Aug 2012 17:58:43 -0400 Subject: Keep track of updatedAt server side, instead of on widgets. --- lib/dashing.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index ee7cd1f..beb7eca 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -81,6 +81,7 @@ end def send_event(id, body) body["id"] = id + body["updatedAt"] = Time.now event = format_event(JSON.unparse(body)) settings.history[id] = event settings.connections.each { |out| out << event } -- cgit v1.2.3 From 4bf82f6303465bb74e9e6d2747d3053358ef83b7 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Tue, 28 Aug 2012 16:03:22 -0400 Subject: Added in a fix that forces your json codec to initialize before jobs are run. --- lib/dashing.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index beb7eca..7d066cc 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -82,7 +82,7 @@ end def send_event(id, body) body["id"] = id body["updatedAt"] = Time.now - event = format_event(JSON.unparse(body)) + event = format_event(body.to_json) settings.history[id] = event settings.connections.each { |out| out << event } end @@ -104,6 +104,7 @@ def first_dashboard end Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } +{}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. job_path = ENV["JOB_PATH"] || 'jobs' files = Dir[File.join(settings.root, job_path, '/*.rb')] -- cgit v1.2.3 From c39be899b629378c0a4e1dd4beab528ebcbffa6e Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Sat, 3 Nov 2012 13:18:40 +0800 Subject: Display 'last updated' using user's locale. Closes #10 --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 7d066cc..37dc54d 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -81,7 +81,7 @@ end def send_event(id, body) body["id"] = id - body["updatedAt"] = Time.now + body["updatedAt"] = Time.now.to_i event = format_event(body.to_json) settings.history[id] = event settings.connections.each { |out| out << event } -- cgit v1.2.3 From 17ef11ebf1ba22c63cfee4b668f314d69d9bd684 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Thu, 24 Jan 2013 17:14:26 -0500 Subject: Allow overriding the 'updatedAt' field. This is useful if you want to show the freshness of the data instead of when the job was last run. --- lib/dashing.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 37dc54d..04e4cee 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -80,8 +80,8 @@ def production? end def send_event(id, body) - body["id"] = id - body["updatedAt"] = Time.now.to_i + body[:id] = id + body[:updatedAt] ||= Time.now.to_i event = format_event(body.to_json) settings.history[id] = event settings.connections.each { |out| out << event } -- cgit v1.2.3 From 6dcda5d7cd26514cac1b18438af7913105e68f00 Mon Sep 17 00:00:00 2001 From: Daniel Beauchamp Date: Wed, 13 Feb 2013 21:32:34 -0500 Subject: Added the public directory for serving static assets. This allows for stuff like favicons and custom 404/500 pages. --- lib/dashing.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 04e4cee..bae4c29 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -49,7 +49,11 @@ end get '/:dashboard' do protected! - erb params[:dashboard].to_sym + if File.exist? File.join(settings.views, "#{params[:dashboard]}.erb") + erb params[:dashboard].to_sym + else + halt 404 + end end get '/views/:widget?.html' do @@ -71,6 +75,10 @@ post '/widgets/:id' do end end +not_found do + send_file File.join(settings.public_folder, '404.html') +end + def development? ENV['RACK_ENV'] == 'development' end -- cgit v1.2.3 From 98f326eab33ee741c2d95c1861fc5c9233f0b47d Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 26 Mar 2013 13:27:58 -0400 Subject: Send an X-Accel-Redirect in /events to disable nginx buffering. --- lib/dashing.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index bae4c29..949cfee 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -32,6 +32,7 @@ end get '/events', provides: 'text/event-stream' do protected! + response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx stream :keep_open do |out| settings.connections << out out << latest_events @@ -116,4 +117,4 @@ Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } job_path = ENV["JOB_PATH"] || 'jobs' files = Dir[File.join(settings.root, job_path, '/*.rb')] -files.each { |job| require(job) } +files.each { |job| require(job) } -- cgit v1.2.3 From 8ad8097ed22cb557a2b5d946d11158575e82cb94 Mon Sep 17 00:00:00 2001 From: Zachary Salzbank Date: Mon, 29 Apr 2013 20:49:02 -0300 Subject: allow send_event to be called from within modules resolves the error: undefined local variable or method `settings' when send_event is called from in a module --- lib/dashing.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 949cfee..952b614 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -92,8 +92,8 @@ def send_event(id, body) body[:id] = id body[:updatedAt] ||= Time.now.to_i event = format_event(body.to_json) - settings.history[id] = event - settings.connections.each { |out| out << event } + Sinatra::Application.settings.history[id] = event + Sinatra::Application.settings.connections.each { |out| out << event } end def format_event(body) -- cgit v1.2.3 From 8795505a06fe58dfb5f414078587349b7771af62 Mon Sep 17 00:00:00 2001 From: Aaron Peckham Date: Thu, 9 May 2013 23:27:44 -0700 Subject: use any Tilt-supported view engine for dashboards, including Haml --- lib/dashing.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 952b614..391095d 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -50,8 +50,12 @@ end get '/:dashboard' do protected! - if File.exist? File.join(settings.views, "#{params[:dashboard]}.erb") - erb params[:dashboard].to_sym + view_engine = Tilt.mappings.keys.find do |ext| + File.exist? File.join(settings.views, "#{params[:dashboard]}.#{ext}") + end + + if view_engine + render view_engine.to_sym, params[:dashboard].to_sym else halt 404 end @@ -107,7 +111,7 @@ def latest_events end def first_dashboard - files = Dir[File.join(settings.views, '*.erb')].collect { |f| f.match(/(\w*).erb/)[1] } + files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') } files -= ['layout'] files.first end -- cgit v1.2.3 From b1b0b3c18d6ee05e42a043dde8d48058841df35c Mon Sep 17 00:00:00 2001 From: Nathan Broadbent Date: Sat, 18 May 2013 11:48:22 +1200 Subject: Persist history at exit and load on start, so that server restarts don't lose all pushed events --- lib/dashing.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 952b614..63fdc37 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -5,6 +5,7 @@ require 'rufus/scheduler' require 'coffee-script' require 'sass' require 'json' +require 'yaml' SCHEDULER = Rufus::Scheduler.start_new @@ -17,7 +18,21 @@ set :digest_assets, false settings.sprockets.append_path path end -set server: 'thin', connections: [], history: {} +set server: 'thin', connections: [], history_file: 'tmp/history.yml' + +# Persist history in tmp file at exit +at_exit do + File.open(settings.history_file, 'w') do |f| + f.puts settings.history.to_yaml + end +end + +if File.exists?(settings.history_file) + set history: YAML.load_file(settings.history_file) +else + set history: {} +end + set :public_folder, File.join(settings.root, 'public') set :views, File.join(settings.root, 'dashboards') set :default_dashboard, nil -- cgit v1.2.3 From a6eea61f2a7cfbf67175583dd7dcb49a4c09da75 Mon Sep 17 00:00:00 2001 From: Aaron Peckham Date: Mon, 20 May 2013 12:19:35 -0700 Subject: allow widget views to be written in any Tilt-supported template language --- lib/dashing.rb | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 391095d..04921fe 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -50,21 +50,20 @@ end get '/:dashboard' do protected! - view_engine = Tilt.mappings.keys.find do |ext| - File.exist? File.join(settings.views, "#{params[:dashboard]}.#{ext}") + tilt_html_engines.each do |suffix, _| + file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}") + return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file end - if view_engine - render view_engine.to_sym, params[:dashboard].to_sym - else - halt 404 - end + halt 404 end get '/views/:widget?.html' do protected! - widget = params[:widget] - send_file File.join(settings.root, 'widgets', widget, "#{widget}.html") + tilt_html_engines.each do |suffix, engines| + file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}") + return engines.first.new(file).render if File.exist? file + end end post '/widgets/:id' do @@ -116,6 +115,13 @@ def first_dashboard files.first end +def tilt_html_engines + Tilt.mappings.select do |_, engines| + default_mime_type = engines.first.default_mime_type + default_mime_type.nil? || default_mime_type == 'text/html' + end +end + Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } {}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. -- cgit v1.2.3 From f609a409637d9586814d5f37e9a060e89eab8382 Mon Sep 17 00:00:00 2001 From: David Underwood Date: Fri, 21 Jun 2013 11:42:17 -0400 Subject: Changes history file location to avoid failing tests --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 24b191c..34e2cb5 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -18,7 +18,7 @@ set :digest_assets, false settings.sprockets.append_path path end -set server: 'thin', connections: [], history_file: 'tmp/history.yml' +set server: 'thin', connections: [], history_file: 'history.yml' # Persist history in tmp file at exit at_exit do -- cgit v1.2.3 From 86aac07d890c6ec87d9486e9580ecc87bc5dab26 Mon Sep 17 00:00:00 2001 From: David Underwood Date: Fri, 28 Jun 2013 12:37:52 -0400 Subject: Yo dawg, I heard you liked jobs so we added recursive loading to your job loader so you can have job subfolders in the job folder that contain jobs --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 34e2cb5..dc62395 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -141,5 +141,5 @@ Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } {}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. job_path = ENV["JOB_PATH"] || 'jobs' -files = Dir[File.join(settings.root, job_path, '/*.rb')] +files = Dir[File.join(settings.root, job_path, '**', '/*.rb')] files.each { |job| require(job) } -- cgit v1.2.3 From 3f58bbd626cd84d1cb24375b4d8fe6df75ce85ba Mon Sep 17 00:00:00 2001 From: Pieter van de Bruggen Date: Sun, 4 Nov 2012 17:10:36 -0800 Subject: Adding application messaging. While widgets are the most common target for events, there is good reason to sometimes target the application as a whole. This patch adds support for such events using the /-prefixed notation. (This convention is safe for use since it represents an extremely uncommon widget ID, and one which data could not be POSTed to.) Such events are NOT subject to replay, and are handled on the client-side by firing corresponding events on the Dashing application class. As a proof of concept (and to fufill a feature request), this patch also introduces a POST /reload endpoint, which when provided with a valid authkey (and optionally a dashboard name) fires the appropriate 'reload' event on all of the loaded dashboards. The 'reload' event handler then reloads the dashboard, unless a different dashboard was specified. --- lib/dashing.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index dc62395..4c1b44b 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -81,9 +81,22 @@ get '/views/:widget?.html' do end end +post '/reload' do + request.body.rewind + body = JSON.parse(request.body.read) + auth_token = body.delete("auth_token") + if !settings.auth_token || settings.auth_token == auth_token + send_event('/reload', body) + 204 # response without entity body + else + status 401 + "Invalid API key\n" + end +end + post '/widgets/:id' do request.body.rewind - body = JSON.parse(request.body.read) + body = JSON.parse(request.body.read) auth_token = body.delete("auth_token") if !settings.auth_token || settings.auth_token == auth_token send_event(params['id'], body) @@ -110,7 +123,7 @@ def send_event(id, body) body[:id] = id body[:updatedAt] ||= Time.now.to_i event = format_event(body.to_json) - Sinatra::Application.settings.history[id] = event + Sinatra::Application.settings.history[id] = event unless id =~ /^\// Sinatra::Application.settings.connections.each { |out| out << event } end -- cgit v1.2.3 From 5f8cbcb7debde027e79d87733b84cb852aa47dad Mon Sep 17 00:00:00 2001 From: Chad Jolly Date: Sun, 14 Jul 2013 18:36:19 -0600 Subject: dashboard events - use SSE event names --- lib/dashing.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 4c1b44b..935a031 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -81,12 +81,13 @@ get '/views/:widget?.html' do end end -post '/reload' do +post '/dashboards/:id' do request.body.rewind body = JSON.parse(request.body.read) + body['dashboard'] ||= params['id'] auth_token = body.delete("auth_token") if !settings.auth_token || settings.auth_token == auth_token - send_event('/reload', body) + send_event(params['id'], body, 'dashboards') 204 # response without entity body else status 401 @@ -119,16 +120,18 @@ def production? ENV['RACK_ENV'] == 'production' end -def send_event(id, body) +def send_event(id, body, target=nil) body[:id] = id body[:updatedAt] ||= Time.now.to_i - event = format_event(body.to_json) - Sinatra::Application.settings.history[id] = event unless id =~ /^\// + event = format_event(body.to_json, target) + Sinatra::Application.settings.history[id] = event unless target == 'dashboards' Sinatra::Application.settings.connections.each { |out| out << event } end -def format_event(body) - "data: #{body}\n\n" +def format_event(body, name=nil) + str = "" + str << "event: #{name}\n" if name + str << "data: #{body}\n\n" end def latest_events -- cgit v1.2.3 From 06ba2ea902bfd73a9c9437e7f44063b21611edb7 Mon Sep 17 00:00:00 2001 From: David Rubin Date: Wed, 31 Jul 2013 10:49:00 +0200 Subject: Authenticate / route as to not leak private dashboard url --- lib/dashing.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 935a031..f5b60ca 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -56,6 +56,7 @@ get '/events', provides: 'text/event-stream' do end get '/' do + protected! begin redirect "/" + (settings.default_dashboard || first_dashboard).to_s rescue NoMethodError => e -- cgit v1.2.3 From 7f2031512e5003d0d20d07bcebf248f76cfcd0a8 Mon Sep 17 00:00:00 2001 From: pushmatrix Date: Fri, 9 Aug 2013 18:23:00 +0200 Subject: The default dashboard is picked simply as the first one alphabetically across all OSes. Closes #97 --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index f5b60ca..2c3a810 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -144,7 +144,7 @@ end def first_dashboard files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') } files -= ['layout'] - files.first + files.sort.first end def tilt_html_engines -- cgit v1.2.3 From eb331a2fab101b93bce0a5b87e06927f324c96b8 Mon Sep 17 00:00:00 2001 From: Jordan Wheeler Date: Mon, 9 Sep 2013 15:34:08 -0400 Subject: add firebase gems --- lib/dashing.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 2c3a810..d4a8c11 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -6,6 +6,7 @@ require 'coffee-script' require 'sass' require 'json' require 'yaml' +require 'firebase' SCHEDULER = Rufus::Scheduler.start_new -- cgit v1.2.3 From b81273772effd5300bfd970abffedad3d0362dbf Mon Sep 17 00:00:00 2001 From: pushmatrix Date: Mon, 9 Sep 2013 21:38:53 +0200 Subject: Revert "Merge pull request #226 from jordanwheeler/use-firebase" This reverts commit a4cdeb81c2cba2b7028f342d56abac22f101bf78, reversing changes made to 2671d387e3c9b845431d41ab93d51cf2bd7b2cf8. --- lib/dashing.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index d4a8c11..2c3a810 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -6,7 +6,6 @@ require 'coffee-script' require 'sass' require 'json' require 'yaml' -require 'firebase' SCHEDULER = Rufus::Scheduler.start_new -- cgit v1.2.3 From 7ca9e828423d6e19a9b85fc3dbc8f5d8696e937e Mon Sep 17 00:00:00 2001 From: John Tajima Date: Wed, 30 Oct 2013 19:34:45 -0400 Subject: Define a KEYS constant --- lib/dashing.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 2c3a810..f1b18fc 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -8,6 +8,7 @@ require 'json' require 'yaml' SCHEDULER = Rufus::Scheduler.start_new +KEYS = {} set :root, Dir.pwd -- cgit v1.2.3 From 4177623a7a5e7967514a0d92095e0dcb32896026 Mon Sep 17 00:00:00 2001 From: John Tajima Date: Wed, 30 Oct 2013 19:57:07 -0400 Subject: require config/settings.rb if exists --- lib/dashing.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index f1b18fc..a8e9f33 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -8,7 +8,6 @@ require 'json' require 'yaml' SCHEDULER = Rufus::Scheduler.start_new -KEYS = {} set :root, Dir.pwd @@ -155,6 +154,11 @@ def tilt_html_engines end end +settings_file = File.join(settings.root, 'config/settings.rb') +if (File.exists?(settings_file)) + require settings_file +end + Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } {}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. -- cgit v1.2.3 From 4a042c5cfef6d29d509af12830d11304578fa6aa Mon Sep 17 00:00:00 2001 From: pseudomuto Date: Wed, 18 Dec 2013 15:43:46 -0500 Subject: adding pessimistic versioning for gem dependencies --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index a8e9f33..7c4f25a 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -7,7 +7,7 @@ require 'sass' require 'json' require 'yaml' -SCHEDULER = Rufus::Scheduler.start_new +SCHEDULER = Rufus::Scheduler.new set :root, Dir.pwd -- cgit v1.2.3 From d0eef2dbe9d1178111cd768116a66b32a3a4b2b5 Mon Sep 17 00:00:00 2001 From: pseudomuto Date: Wed, 18 Dec 2013 19:12:43 -0500 Subject: moving cli to lib and updating bin file --- lib/dashing.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 7c4f25a..54579dd 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -7,6 +7,9 @@ require 'sass' require 'json' require 'yaml' +require 'dashing/cli' +require 'dashing/downloader' + SCHEDULER = Rufus::Scheduler.new set :root, Dir.pwd -- cgit v1.2.3 From fbc9497dbb8ece970f21bc67164557bba8db2db7 Mon Sep 17 00:00:00 2001 From: pseudomuto Date: Wed, 18 Dec 2013 19:22:09 -0500 Subject: moving app to it's own file under lib/dashing --- lib/dashing.rb | 168 +-------------------------------------------------------- 1 file changed, 2 insertions(+), 166 deletions(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 54579dd..855aa36 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -1,170 +1,6 @@ -require 'sinatra' -require 'sprockets' -require 'sinatra/content_for' -require 'rufus/scheduler' -require 'coffee-script' -require 'sass' -require 'json' -require 'yaml' - require 'dashing/cli' require 'dashing/downloader' +require 'dashing/app' -SCHEDULER = Rufus::Scheduler.new - -set :root, Dir.pwd - -set :sprockets, Sprockets::Environment.new(settings.root) -set :assets_prefix, '/assets' -set :digest_assets, false -['assets/javascripts', 'assets/stylesheets', 'assets/fonts', 'assets/images', 'widgets', File.expand_path('../../javascripts', __FILE__)]. each do |path| - settings.sprockets.append_path path -end - -set server: 'thin', connections: [], history_file: 'history.yml' - -# Persist history in tmp file at exit -at_exit do - File.open(settings.history_file, 'w') do |f| - f.puts settings.history.to_yaml - end -end - -if File.exists?(settings.history_file) - set history: YAML.load_file(settings.history_file) -else - set history: {} -end - -set :public_folder, File.join(settings.root, 'public') -set :views, File.join(settings.root, 'dashboards') -set :default_dashboard, nil -set :auth_token, nil - -helpers Sinatra::ContentFor -helpers do - def protected! - # override with auth logic - end -end - -get '/events', provides: 'text/event-stream' do - protected! - response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx - stream :keep_open do |out| - settings.connections << out - out << latest_events - out.callback { settings.connections.delete(out) } - end -end - -get '/' do - protected! - begin - redirect "/" + (settings.default_dashboard || first_dashboard).to_s - rescue NoMethodError => e - raise Exception.new("There are no dashboards in your dashboard directory.") - end -end - -get '/:dashboard' do - protected! - tilt_html_engines.each do |suffix, _| - file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}") - return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file - end - - halt 404 -end - -get '/views/:widget?.html' do - protected! - tilt_html_engines.each do |suffix, engines| - file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}") - return engines.first.new(file).render if File.exist? file - end -end - -post '/dashboards/:id' do - request.body.rewind - body = JSON.parse(request.body.read) - body['dashboard'] ||= params['id'] - auth_token = body.delete("auth_token") - if !settings.auth_token || settings.auth_token == auth_token - send_event(params['id'], body, 'dashboards') - 204 # response without entity body - else - status 401 - "Invalid API key\n" - end +module Dashing end - -post '/widgets/:id' do - request.body.rewind - body = JSON.parse(request.body.read) - auth_token = body.delete("auth_token") - if !settings.auth_token || settings.auth_token == auth_token - send_event(params['id'], body) - 204 # response without entity body - else - status 401 - "Invalid API key\n" - end -end - -not_found do - send_file File.join(settings.public_folder, '404.html') -end - -def development? - ENV['RACK_ENV'] == 'development' -end - -def production? - ENV['RACK_ENV'] == 'production' -end - -def send_event(id, body, target=nil) - body[:id] = id - body[:updatedAt] ||= Time.now.to_i - event = format_event(body.to_json, target) - Sinatra::Application.settings.history[id] = event unless target == 'dashboards' - Sinatra::Application.settings.connections.each { |out| out << event } -end - -def format_event(body, name=nil) - str = "" - str << "event: #{name}\n" if name - str << "data: #{body}\n\n" -end - -def latest_events - settings.history.inject("") do |str, (id, body)| - str << body - end -end - -def first_dashboard - files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') } - files -= ['layout'] - files.sort.first -end - -def tilt_html_engines - Tilt.mappings.select do |_, engines| - default_mime_type = engines.first.default_mime_type - default_mime_type.nil? || default_mime_type == 'text/html' - end -end - -settings_file = File.join(settings.root, 'config/settings.rb') -if (File.exists?(settings_file)) - require settings_file -end - -Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file } -{}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start. - -job_path = ENV["JOB_PATH"] || 'jobs' -files = Dir[File.join(settings.root, job_path, '**', '/*.rb')] -files.each { |job| require(job) } -- cgit v1.2.3 From d3ccecb096821b2df3b492dd349e5c650929a591 Mon Sep 17 00:00:00 2001 From: pushmatrix Date: Fri, 30 May 2014 14:28:51 -0400 Subject: Don't start the dashing app when you run the bin file. --- lib/dashing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/dashing.rb') diff --git a/lib/dashing.rb b/lib/dashing.rb index 855aa36..3527034 100644 --- a/lib/dashing.rb +++ b/lib/dashing.rb @@ -3,4 +3,4 @@ require 'dashing/downloader' require 'dashing/app' module Dashing -end +end \ No newline at end of file -- cgit v1.2.3