Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
*.gem
coverage/
log/
tmp/
.ruby-version
history.yml
11 changes: 6 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
language: ruby
rvm:
- 2.3.0
- 2.2.4
- 2.1.8

script: "rake test"
- 2.3.4
- 2.2.7
- 2.1.10
- jruby-19mode
- jruby-9.1.10.0
script: rake test
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $ cd my-project
# Install the bundle of project specific gems
$ bundle
# Start the example dashboard!
$ smashing start
$ puma
```

[Check out our wiki](https://github.com/Smashing/smashing/wiki).
Expand Down
3 changes: 2 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
test.pattern = 'test/**/*_test.rb'
test.warning = false
end

task :default => [:test]
task default: [:test]
78 changes: 42 additions & 36 deletions lib/dashing/app.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
require 'sinatra'
require 'sprockets'
require 'sinatra/content_for'
require 'rufus/scheduler'
require 'coffee-script'
require 'sass'
require 'json'
require 'rufus/scheduler'
require 'sass'
require 'sinatra'
require 'sinatra/content_for'
require 'sinatra/streaming'
require 'sprockets'
require 'yaml'
require 'thin'

SCHEDULER = Rufus::Scheduler.new

Expand Down Expand Up @@ -34,13 +34,14 @@ def authenticated?(token)
set :sprockets, Sprockets::Environment.new(settings.root)
set :assets_prefix, '/assets'
set :digest_assets, false
set :server, 'thin'
set :server, 'puma'
set :connections, []
set :history_file, 'history.yml'
set :public_folder, File.join(settings.root, 'public')
set :views, File.join(settings.root, 'dashboards')
set :default_dashboard, nil
set :auth_token, nil
set :template_languages, %i[html erb]

if File.exists?(settings.history_file)
set :history, YAML.load_file(settings.history_file)
Expand All @@ -57,7 +58,7 @@ def authenticated?(token)
end

not_found do
send_file File.join(settings.public_folder, '404.html'), :status => 404
send_file File.join(settings.public_folder, '404.html'), status: 404
end

at_exit do
Expand All @@ -72,21 +73,31 @@ def authenticated?(token)
redirect "/" + dashboard
end

get '/events', :provides => 'text/event-stream' do

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
stream do |out|
out << latest_events
out.callback { settings.connections.delete(out) }
settings.connections << connection = {out: out, mutex: Mutex.new, terminated: false}
terminated = false

loop do
connection[:mutex].synchronize do
terminated = true if connection[:terminated]
end
break if terminated
end

settings.connections.delete(connection)
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
settings.template_languages.each do |language|
file = File.join(settings.views, "#{params[:dashboard]}.#{language}")
return render(language, params[:dashboard].to_sym) if File.exist?(file)
end

halt 404
Expand Down Expand Up @@ -119,29 +130,31 @@ def authenticated?(token)

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
"Drats! Unable to find a widget file named: #{params[:widget]} to render."
end

Thin::Server.class_eval do
def stop_with_connection_closing
Sinatra::Application.settings.connections.dup.each(&:close)
stop_without_connection_closing
settings.template_languages.each do |language|
file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{language}")
return Tilt[language].new(file).render if File.exist?(file)
end

alias_method :stop_without_connection_closing, :stop
alias_method :stop, :stop_with_connection_closing
"Drats! Unable to find a widget file named: #{params[:widget]} to render."
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 }
Sinatra::Application.settings.connections.each do |connection|
connection[:mutex].synchronize do
begin
connection[:out] << event unless connection[:out].closed?
rescue Puma::ConnectionError
connection[:terminated] = true
rescue Exception => e
connection[:terminated] = true
puts e
end
end
end
end

def format_event(body, name=nil)
Expand All @@ -162,13 +175,6 @@ def first_dashboard
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

def require_glob(relative_glob)
Dir[File.join(settings.root, relative_glob)].each do |file|
require file
Expand Down
20 changes: 2 additions & 18 deletions lib/dashing/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,6 @@ def install(gist_id, *args)
say set_color("Could not find gist at #{public_url}"), :red
end

desc "start", "Starts the server in style!"
method_option :job_path, :desc => "Specify the directory where jobs are stored"
def start(*args)
port_option = args.include?('-p') ? '' : ' -p 3030'
args = args.join(' ')
command = "bundle exec thin -R config.ru start#{port_option} #{args}"
command.prepend "export JOB_PATH=#{options[:job_path]}; " if options[:job_path]
run_command(command)
end

desc "stop", "Stops the thin server"
def stop
command = "bundle exec thin stop"
run_command(command)
end

desc "job JOB_NAME AUTH_TOKEN(optional)", "Runs the specified job. Make sure to supply your auth token if you have one set."
def job(name, auth_token = "")
Dir[File.join(Dir.pwd, 'lib/**/*.rb')].each {|file| require_file(file) }
Expand All @@ -94,10 +78,10 @@ def install_widget_from_gist(gist, skip_overwrite)
if file =~ /\.(html|coffee|scss)\z/
widget_name = File.basename(file, '.*')
new_path = File.join(Dir.pwd, 'widgets', widget_name, file)
create_file(new_path, details['content'], :skip => skip_overwrite)
create_file(new_path, details['content'], skip: skip_overwrite)
elsif file.end_with?('.rb')
new_path = File.join(Dir.pwd, 'jobs', file)
create_file(new_path, details['content'], :skip => skip_overwrite)
create_file(new_path, details['content'], skip: skip_overwrite)
end
end
end
Expand Down
30 changes: 15 additions & 15 deletions smashing.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ Gem::Specification.new do |s|

s.files = Dir['README.md', 'javascripts/**/*', 'templates/**/*','templates/**/.[a-z]*', 'lib/**/*']

s.add_dependency('sass', '~> 3.2.12')
s.add_dependency('coffee-script', '~> 2.2.0')
s.add_dependency('execjs', '~> 2.0.2')
s.add_dependency('sinatra', '~> 1.4.4')
s.add_dependency('sinatra-contrib', '~> 1.4.2')
s.add_dependency('thin', '~> 1.6.1')
s.add_dependency('rufus-scheduler', '~> 2.0.24')
s.add_dependency('thor', '~> 0.19')
s.add_dependency('sprockets', '~> 2.10.1')
s.add_dependency('rack', '~> 1.5.4')
s.add_dependency('sass', '~> 3.4.24')
s.add_dependency('coffee-script', '~> 2.4.1')
s.add_dependency('execjs', '~> 2.7.0')
s.add_dependency('sinatra', '~> 2.0.0')
s.add_dependency('sinatra-contrib', '~> 2.0.0')
s.add_dependency('puma', '~> 3.8.2')
s.add_dependency('rufus-scheduler', '~> 3.4.2')
s.add_dependency('thor', '~> 0.19.4')
s.add_dependency('sprockets', '~> 3.7.1')

s.add_development_dependency('rake', '~> 10.1.0')
s.add_development_dependency('haml', '~> 4.0.4')
s.add_development_dependency('minitest', '~> 5.2.0')
s.add_development_dependency('mocha', '~> 0.14.0')
s.add_development_dependency('rake', '~> 12.0.0')
s.add_development_dependency('haml', '~> 5.0.1')
s.add_development_dependency('rack-test', '~> 0.6.3')
s.add_development_dependency('minitest', '~> 5.10.2')
s.add_development_dependency('mocha', '~> 1.2.1')
s.add_development_dependency('fakeweb', '~> 1.3.0')
s.add_development_dependency('simplecov', '~> 0.8.2')
s.add_development_dependency('simplecov', '~> 0.14.1')
end
4 changes: 2 additions & 2 deletions templates/job/%name%.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# :first_in sets how long it takes before the job is first run. In this case, it is run immediately
SCHEDULER.every '1m', :first_in => 0 do |job|
SCHEDULER.every '1m', first_in: 0 do |job|
send_event('widget_id', { })
end
end
4 changes: 4 additions & 0 deletions templates/project/config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ require 'dashing'
configure do
set :auth_token, 'YOUR_AUTH_TOKEN'

# See http://www.sinatrarb.com/intro.html > Available Template Languages on
# how to add additional template languages.
set :template_languages, %i[html erb]

helpers do
def protected!
# Put any authentication code you want in here.
Expand Down
42 changes: 42 additions & 0 deletions templates/project/config/puma.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# For a complete list of puma configuration parameters, please see
# https://github.com/puma/puma

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum.
#
threads_count = ENV.fetch("PUMA_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests, default is 2020.
#
port ENV.fetch("DASHING_PORT") { 3030 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RACK_ENV") { "production" }

# Daemonize the server into the background. Highly suggest that
# this be combined with "pidfile" and "stdout_redirect".
#
# The default is "false".
#
daemonize ENV.fetch("DAEMONIZE") { false }

# Store the pid of the server in the file at "path".
#
pidfile './tmp/pids/puma.pid'

# Use "path" as the file to store the server info state. This is
# used by "pumactl" to query and control the server.
#
state_path './tmp/pids/puma.state'

# Redirect STDOUT and STDERR to files specified. The 3rd parameter
# ("append") specifies whether the output is appended, the default is
# "false".
#
# stdout_redirect '/u/apps/lolcat/log/stdout', '/u/apps/lolcat/log/stderr'
# stdout_redirect '/u/apps/lolcat/log/stdout', '/u/apps/lolcat/log/stderr', true
4 changes: 2 additions & 2 deletions templates/project/jobs/twitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

search_term = URI::encode('#todayilearned')

SCHEDULER.every '10m', :first_in => 0 do |job|
SCHEDULER.every '10m', first_in: 0 do |job|
begin
tweets = twitter.search("#{search_term}")

Expand All @@ -25,4 +25,4 @@
rescue Twitter::Error
puts "\e[33mFor the twitter widget to work, you need to put in your twitter API keys in the jobs/twitter.rb file.\e[0m"
end
end
end
1 change: 1 addition & 0 deletions templates/project/tmp/pids/.empty_directory
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.empty_directory
Loading