dashing 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15cdc02c7ee61ffa4187b9475163278fc7e0428e
4
- data.tar.gz: 7b7bff7f96d852ba09729423446a062494f0c485
3
+ metadata.gz: e7c59e687451b697ac161b49e89e26ed71b62dcf
4
+ data.tar.gz: dce2b7d38136bc5330b770b49ca49ae32cc2b0e9
5
5
  SHA512:
6
- metadata.gz: 71bda5fe1849ccf6a614e79adbce22a79c9b073f8336ecff9787e86a2ac4121fa0aaeb6ab5807cfd13dd29f285df9c20994e684eb4e851358701ad9b0d2ed32b
7
- data.tar.gz: a400efcfd996663171d73c018572a09322ceb45679e5b781fa5b4d0ba7ab0bb8cb9c0347c16b15590c1684aa76a98a47c0642e8e5b6de50db9d86dcf3dbfe542
6
+ metadata.gz: cb422e90480391126aea639a2a6da7c646d80bcdc8e6459c6d41c12263a198f9acf0abf7ef025445f1899503ec0eac070ee97d45f9834874248bc76c4423758e
7
+ data.tar.gz: 0f19a88567bfcb2b00bda112650f812c4414abc9396502913e93078e79704f2f35a6913e8cb2a59f5bed8fedaabeae20666c10f372aace016ac78ff751ec4ad4
Binary file
Binary file
@@ -1,112 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ require "pathname"
3
+ bin_file = Pathname.new(__FILE__).realpath
4
+ $:.unshift File.expand_path("../../lib", bin_file)
2
5
 
3
- require 'thor'
4
- require 'net/http'
5
- require 'json'
6
- require 'open-uri'
7
-
8
- class MockScheduler
9
- def method_missing(*args)
10
- yield
11
- end
12
- end
13
-
14
- SCHEDULER = MockScheduler.new
15
-
16
- module Dashing
17
-
18
- class CLI < Thor
19
- include Thor::Actions
20
-
21
- class << self
22
- attr_accessor :auth_token
23
-
24
- def hyphenate(str)
25
- return str.downcase if str =~ /^[A-Z-]+$/
26
- str.gsub('_', '-').gsub(/\B[A-Z]/, '-\&').squeeze('-').downcase
27
- end
28
- end
29
-
30
- attr_accessor :name
31
-
32
- no_tasks do
33
- ['widget', 'dashboard', 'job'].each do |type|
34
- define_method "generate_#{type}" do |name|
35
- @name = Thor::Util.snake_case(name)
36
- directory type.to_sym, File.join("#{type}s")
37
- end
38
- end
39
- end
40
-
41
- def self.source_root
42
- File.expand_path('../../templates', __FILE__)
43
- end
44
-
45
- desc "new PROJECT_NAME", "Sets up ALL THE THINGS needed for your dashboard project."
46
- def new(name)
47
- @name = Thor::Util.snake_case(name)
48
- directory :project, @name
49
- end
50
-
51
- desc "generate (widget/dashboard/job) NAME", "Creates a new widget, dashboard, or job."
52
- def generate(type, name)
53
- send("generate_#{type}".to_sym, name)
54
- rescue NoMethodError => e
55
- puts "Invalid generator. Either use widget, dashboard, or job"
56
- end
57
- map "g" => :generate
58
-
59
- desc "install GIST_ID", "Installs a new widget from a gist."
60
- def install(gist_id)
61
- public_url = "https://gist.github.com/#{gist_id}"
62
- gist = JSON.parse(open("https://api.github.com/gists/#{gist_id}").read)
63
-
64
- gist['files'].each do |filename, contents|
65
- if filename.end_with?(".rb")
66
- create_file File.join(Dir.pwd, 'jobs', filename), contents['content']
67
- elsif filename.end_with?(".coffee", ".html", ".scss")
68
- widget_name = File.basename(filename, '.*')
69
- create_file File.join(Dir.pwd, 'widgets', widget_name, filename), contents['content']
70
- end
71
- end
72
-
73
- print set_color("Don't forget to edit the ", :yellow)
74
- print set_color("Gemfile ", :yellow, :bold)
75
- print set_color("and run ", :yellow)
76
- print set_color("bundle install ", :yellow, :bold)
77
- say set_color("if needed. More information for this widget can be found at #{public_url}", :yellow)
78
-
79
- rescue OpenURI::HTTPError => e
80
- say set_color("Could not find gist at #{public_url}"), :red
81
- end
82
- map "i" => :install
83
-
84
- desc "start", "Starts the server in style!"
85
- method_option :job_path, :desc => "Specify the directory where jobs are stored"
86
- def start(*args)
87
- port_option = args.include?('-p')? '' : ' -p 3030'
88
- args = args.join(" ")
89
- command = "bundle exec thin -R config.ru start #{port_option} #{args}"
90
- command.prepend "export JOB_PATH=#{options[:job_path]}; " if options[:job_path]
91
- system(command)
92
- end
93
- map "s" => :start
94
-
95
- desc "stop", "Stops the thin server"
96
- def stop
97
- command = "bundle exec thin stop"
98
- system(command)
99
- end
100
-
101
- desc "job JOB_NAME AUTH_TOKEN(optional)", "Runs the specified job. Make sure to supply your auth token if you have one set."
102
- def job(name, auth_token = "")
103
- Dir[File.join(Dir.pwd, 'lib/**/*.rb')].each {|file| require file }
104
- self.class.auth_token = auth_token
105
- f = File.join(Dir.pwd, "jobs", "#{name}.rb")
106
- require f
107
- end
108
-
109
- end
110
- end
111
-
112
- Dashing::CLI.start
6
+ require 'dashing'
7
+ Dashing::CLI.source_root(File.expand_path('../../templates', bin_file))
8
+ Dashing::CLI.start(ARGV)
@@ -1,167 +1,6 @@
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'
1
+ require 'dashing/cli'
2
+ require 'dashing/downloader'
3
+ require 'dashing/app'
9
4
 
10
- SCHEDULER = Rufus::Scheduler.start_new
11
-
12
- set :root, Dir.pwd
13
-
14
- set :sprockets, Sprockets::Environment.new(settings.root)
15
- set :assets_prefix, '/assets'
16
- set :digest_assets, false
17
- ['assets/javascripts', 'assets/stylesheets', 'assets/fonts', 'assets/images', 'widgets', File.expand_path('../../javascripts', __FILE__)]. each do |path|
18
- settings.sprockets.append_path path
19
- end
20
-
21
- set server: 'thin', connections: [], history_file: 'history.yml'
22
-
23
- # Persist history in tmp file at exit
24
- at_exit do
25
- File.open(settings.history_file, 'w') do |f|
26
- f.puts settings.history.to_yaml
27
- end
28
- end
29
-
30
- if File.exists?(settings.history_file)
31
- set history: YAML.load_file(settings.history_file)
32
- else
33
- set history: {}
34
- end
35
-
36
- set :public_folder, File.join(settings.root, 'public')
37
- set :views, File.join(settings.root, 'dashboards')
38
- set :default_dashboard, nil
39
- set :auth_token, nil
40
-
41
- helpers Sinatra::ContentFor
42
- helpers do
43
- def protected!
44
- # override with auth logic
45
- end
46
- end
47
-
48
- get '/events', provides: 'text/event-stream' do
49
- protected!
50
- response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx
51
- stream :keep_open do |out|
52
- settings.connections << out
53
- out << latest_events
54
- out.callback { settings.connections.delete(out) }
55
- end
56
- end
57
-
58
- get '/' do
59
- protected!
60
- begin
61
- redirect "/" + (settings.default_dashboard || first_dashboard).to_s
62
- rescue NoMethodError => e
63
- raise Exception.new("There are no dashboards in your dashboard directory.")
64
- end
65
- end
66
-
67
- get '/:dashboard' do
68
- protected!
69
- tilt_html_engines.each do |suffix, _|
70
- file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}")
71
- return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file
72
- end
73
-
74
- halt 404
5
+ module Dashing
75
6
  end
76
-
77
- get '/views/:widget?.html' do
78
- protected!
79
- tilt_html_engines.each do |suffix, engines|
80
- file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}")
81
- return engines.first.new(file).render if File.exist? file
82
- end
83
- end
84
-
85
- post '/dashboards/:id' do
86
- request.body.rewind
87
- body = JSON.parse(request.body.read)
88
- body['dashboard'] ||= params['id']
89
- auth_token = body.delete("auth_token")
90
- if !settings.auth_token || settings.auth_token == auth_token
91
- send_event(params['id'], body, 'dashboards')
92
- 204 # response without entity body
93
- else
94
- status 401
95
- "Invalid API key\n"
96
- end
97
- end
98
-
99
- post '/widgets/:id' do
100
- request.body.rewind
101
- body = JSON.parse(request.body.read)
102
- auth_token = body.delete("auth_token")
103
- if !settings.auth_token || settings.auth_token == auth_token
104
- send_event(params['id'], body)
105
- 204 # response without entity body
106
- else
107
- status 401
108
- "Invalid API key\n"
109
- end
110
- end
111
-
112
- not_found do
113
- send_file File.join(settings.public_folder, '404.html')
114
- end
115
-
116
- def development?
117
- ENV['RACK_ENV'] == 'development'
118
- end
119
-
120
- def production?
121
- ENV['RACK_ENV'] == 'production'
122
- end
123
-
124
- def send_event(id, body, target=nil)
125
- body[:id] = id
126
- body[:updatedAt] ||= Time.now.to_i
127
- event = format_event(body.to_json, target)
128
- Sinatra::Application.settings.history[id] = event unless target == 'dashboards'
129
- Sinatra::Application.settings.connections.each { |out| out << event }
130
- end
131
-
132
- def format_event(body, name=nil)
133
- str = ""
134
- str << "event: #{name}\n" if name
135
- str << "data: #{body}\n\n"
136
- end
137
-
138
- def latest_events
139
- settings.history.inject("") do |str, (id, body)|
140
- str << body
141
- end
142
- end
143
-
144
- def first_dashboard
145
- files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') }
146
- files -= ['layout']
147
- files.sort.first
148
- end
149
-
150
- def tilt_html_engines
151
- Tilt.mappings.select do |_, engines|
152
- default_mime_type = engines.first.default_mime_type
153
- default_mime_type.nil? || default_mime_type == 'text/html'
154
- end
155
- end
156
-
157
- settings_file = File.join(settings.root, 'config/settings.rb')
158
- if (File.exists?(settings_file))
159
- require settings_file
160
- end
161
-
162
- Dir[File.join(settings.root, 'lib', '**', '*.rb')].each {|file| require file }
163
- {}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start.
164
-
165
- job_path = ENV["JOB_PATH"] || 'jobs'
166
- files = Dir[File.join(settings.root, job_path, '**', '/*.rb')]
167
- files.each { |job| require(job) }
@@ -0,0 +1,167 @@
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
+ SCHEDULER = Rufus::Scheduler.new
11
+
12
+ def development?
13
+ ENV['RACK_ENV'] == 'development'
14
+ end
15
+
16
+ def production?
17
+ ENV['RACK_ENV'] == 'production'
18
+ end
19
+
20
+ helpers Sinatra::ContentFor
21
+ helpers do
22
+ def protected!
23
+ # override with auth logic
24
+ end
25
+ end
26
+
27
+ set :root, Dir.pwd
28
+ set :sprockets, Sprockets::Environment.new(settings.root)
29
+ set :assets_prefix, '/assets'
30
+ set :digest_assets, false
31
+ set server: 'thin', connections: [], history_file: 'history.yml'
32
+ set :public_folder, File.join(settings.root, 'public')
33
+ set :views, File.join(settings.root, 'dashboards')
34
+ set :default_dashboard, nil
35
+ set :auth_token, nil
36
+
37
+ if File.exists?(settings.history_file)
38
+ set history: YAML.load_file(settings.history_file)
39
+ else
40
+ set history: {}
41
+ end
42
+
43
+ %w(javascripts stylesheets fonts images).each do |path|
44
+ settings.sprockets.append_path("assets/#{path}")
45
+ end
46
+
47
+ ['widgets', File.expand_path('../../../javascripts', __FILE__)]. each do |path|
48
+ settings.sprockets.append_path(path)
49
+ end
50
+
51
+ not_found do
52
+ send_file File.join(settings.public_folder, '404.html')
53
+ end
54
+
55
+ at_exit do
56
+ File.write(settings.history_file, settings.history.to_yaml)
57
+ end
58
+
59
+ get '/' do
60
+ protected!
61
+ dashboard = settings.default_dashboard || first_dashboard
62
+ raise Exception.new('There are no dashboards available') if not dashboard
63
+
64
+ redirect "/" + dashboard
65
+ end
66
+
67
+ get '/events', provides: 'text/event-stream' do
68
+ protected!
69
+ response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx
70
+ stream :keep_open do |out|
71
+ settings.connections << out
72
+ out << latest_events
73
+ out.callback { settings.connections.delete(out) }
74
+ end
75
+ end
76
+
77
+ get '/:dashboard' do
78
+ protected!
79
+ tilt_html_engines.each do |suffix, _|
80
+ file = File.join(settings.views, "#{params[:dashboard]}.#{suffix}")
81
+ return render(suffix.to_sym, params[:dashboard].to_sym) if File.exist? file
82
+ end
83
+
84
+ halt 404
85
+ end
86
+
87
+ post '/dashboards/:id' do
88
+ request.body.rewind
89
+ body = JSON.parse(request.body.read)
90
+ body['dashboard'] ||= params['id']
91
+ auth_token = body.delete("auth_token")
92
+ if !settings.auth_token || settings.auth_token == auth_token
93
+ send_event(params['id'], body, 'dashboards')
94
+ 204 # response without entity body
95
+ else
96
+ status 401
97
+ "Invalid API key\n"
98
+ end
99
+ end
100
+
101
+ post '/widgets/:id' do
102
+ request.body.rewind
103
+ body = JSON.parse(request.body.read)
104
+ auth_token = body.delete("auth_token")
105
+ if !settings.auth_token || settings.auth_token == auth_token
106
+ send_event(params['id'], body)
107
+ 204 # response without entity body
108
+ else
109
+ status 401
110
+ "Invalid API key\n"
111
+ end
112
+ end
113
+
114
+ get '/views/:widget?.html' do
115
+ protected!
116
+ tilt_html_engines.each do |suffix, engines|
117
+ file = File.join(settings.root, "widgets", params[:widget], "#{params[:widget]}.#{suffix}")
118
+ return engines.first.new(file).render if File.exist? file
119
+ end
120
+ end
121
+
122
+ def send_event(id, body, target=nil)
123
+ body[:id] = id
124
+ body[:updatedAt] ||= Time.now.to_i
125
+ event = format_event(body.to_json, target)
126
+ Sinatra::Application.settings.history[id] = event unless target == 'dashboards'
127
+ Sinatra::Application.settings.connections.each { |out| out << event }
128
+ end
129
+
130
+ def format_event(body, name=nil)
131
+ str = ""
132
+ str << "event: #{name}\n" if name
133
+ str << "data: #{body}\n\n"
134
+ end
135
+
136
+ def latest_events
137
+ settings.history.inject("") do |str, (id, body)|
138
+ str << body
139
+ end
140
+ end
141
+
142
+ def first_dashboard
143
+ files = Dir[File.join(settings.views, '*')].collect { |f| File.basename(f, '.*') }
144
+ files -= ['layout']
145
+ files.sort.first
146
+ end
147
+
148
+ def tilt_html_engines
149
+ Tilt.mappings.select do |_, engines|
150
+ default_mime_type = engines.first.default_mime_type
151
+ default_mime_type.nil? || default_mime_type == 'text/html'
152
+ end
153
+ end
154
+
155
+ def require_glob(relative_glob)
156
+ Dir[File.join(settings.root, relative_glob)].each do |file|
157
+ require file
158
+ end
159
+ end
160
+
161
+ settings_file = File.join(settings.root, 'config/settings.rb')
162
+ require settings_file if File.exists?(settings_file)
163
+
164
+ {}.to_json # Forces your json codec to initialize (in the event that it is lazily loaded). Does this before job threads start.
165
+ job_path = ENV["JOB_PATH"] || 'jobs'
166
+ require_glob(File.join('lib', '**', '*.rb'))
167
+ require_glob(File.join(job_path, '**', '*.rb'))
@@ -0,0 +1,109 @@
1
+ require 'thor'
2
+ require 'open-uri'
3
+
4
+ module Dashing
5
+ class CLI < Thor
6
+ include Thor::Actions
7
+
8
+ attr_reader :name
9
+
10
+ class << self
11
+ attr_accessor :auth_token
12
+
13
+ def hyphenate(str)
14
+ return str.downcase if str =~ /^[A-Z-]+$/
15
+ str.gsub('_', '-').gsub(/\B[A-Z]/, '-\&').squeeze('-').downcase
16
+ end
17
+ end
18
+
19
+ no_tasks do
20
+ %w(widget dashboard job).each do |type|
21
+ define_method "generate_#{type}" do |name|
22
+ @name = Thor::Util.snake_case(name)
23
+ directory(type.to_sym, "#{type}s")
24
+ end
25
+ end
26
+ end
27
+
28
+ desc "new PROJECT_NAME", "Sets up ALL THE THINGS needed for your dashboard project."
29
+ def new(name)
30
+ @name = Thor::Util.snake_case(name)
31
+ directory(:project, @name)
32
+ end
33
+
34
+ desc "generate (widget/dashboard/job) NAME", "Creates a new widget, dashboard, or job."
35
+ def generate(type, name)
36
+ public_send("generate_#{type}".to_sym, name)
37
+ rescue NoMethodError => e
38
+ puts "Invalid generator. Either use widget, dashboard, or job"
39
+ end
40
+
41
+ desc "install GIST_ID", "Installs a new widget from a gist."
42
+ def install(gist_id)
43
+ gist = Downloader.get_gist(gist_id)
44
+ public_url = "https://gist.github.com/#{gist_id}"
45
+
46
+ install_widget_from_gist(gist)
47
+
48
+ print set_color("Don't forget to edit the ", :yellow)
49
+ print set_color("Gemfile ", :yellow, :bold)
50
+ print set_color("and run ", :yellow)
51
+ print set_color("bundle install ", :yellow, :bold)
52
+ say set_color("if needed. More information for this widget can be found at #{public_url}", :yellow)
53
+ rescue OpenURI::HTTPError => http_error
54
+ say set_color("Could not find gist at #{public_url}"), :red
55
+ end
56
+
57
+ desc "start", "Starts the server in style!"
58
+ method_option :job_path, :desc => "Specify the directory where jobs are stored"
59
+ def start(*args)
60
+ port_option = args.include?('-p') ? '' : ' -p 3030'
61
+ args = args.join(' ')
62
+ command = "bundle exec thin -R config.ru start#{port_option} #{args}"
63
+ command.prepend "export JOB_PATH=#{options[:job_path]}; " if options[:job_path]
64
+ run_command(command)
65
+ end
66
+
67
+ desc "stop", "Stops the thin server"
68
+ def stop
69
+ command = "bundle exec thin stop"
70
+ run_command(command)
71
+ end
72
+
73
+ desc "job JOB_NAME AUTH_TOKEN(optional)", "Runs the specified job. Make sure to supply your auth token if you have one set."
74
+ def job(name, auth_token = "")
75
+ Dir[File.join(Dir.pwd, 'lib/**/*.rb')].each {|file| require_file(file) }
76
+ self.class.auth_token = auth_token
77
+ f = File.join(Dir.pwd, "jobs", "#{name}.rb")
78
+ require_file(f)
79
+ end
80
+
81
+ # map some commands
82
+ map 'g' => :generate
83
+ map 'i' => :install
84
+ map 's' => :start
85
+
86
+ private
87
+
88
+ def run_command(command)
89
+ system(command)
90
+ end
91
+
92
+ def install_widget_from_gist(gist)
93
+ gist['files'].each do |file, details|
94
+ if file =~ /\.(html|coffee|scss)\z/
95
+ widget_name = File.basename(file, '.*')
96
+ new_path = File.join(Dir.pwd, 'widgets', widget_name, file)
97
+ create_file(new_path, details['content'])
98
+ elsif file.end_with?('.rb')
99
+ new_path = File.join(Dir.pwd, 'jobs', file)
100
+ create_file(new_path, details['content'])
101
+ end
102
+ end
103
+ end
104
+
105
+ def require_file(file)
106
+ require file
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,18 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+ require 'json'
4
+
5
+ module Dashing
6
+ module Downloader
7
+ extend self
8
+
9
+ def get_gist(gist_id)
10
+ get_json("https://api.github.com/gists/#{gist_id}")
11
+ end
12
+
13
+ def get_json(url)
14
+ response = open(url).read
15
+ JSON.parse(response)
16
+ end
17
+ end
18
+ end
metadata CHANGED
@@ -1,155 +1,261 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dashing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Beauchamp
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZhZG1p
14
+ bnMxFzAVBgoJkiaJk/IsZAEZFgdzaG9waWZ5MRMwEQYKCZImiZPyLGQBGRYDY29t
15
+ MB4XDTE0MDUxNTIwMzM0OFoXDTE1MDUxNTIwMzM0OFowPzEPMA0GA1UEAwwGYWRt
16
+ aW5zMRcwFQYKCZImiZPyLGQBGRYHc2hvcGlmeTETMBEGCgmSJomT8ixkARkWA2Nv
17
+ bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0/81O3e1vh5smcwp2G
18
+ MpLQ6q0kejQLa65bPYPxdzWA1SYOKyGfw+yR9LdFzsuKpwWzKq6zX35lj1IckWS4
19
+ bNBEQzxmufUxU0XPM02haFB8fOfDJzdXsWte9Ge4IFwahwn68gpMqN+BvxL+KMYz
20
+ Iut9YmN44d4LZdsENEIO5vmybuG2vYDz7R56qB0PA+Q2P2CdhymsBad2DQs69FBo
21
+ uico9V6VMYYctL9lCYdzu9IXrOYNTt88suKIVzzAlHOKeN0Ng5qdztFoTR8sfxDr
22
+ Ydg3KHl5n47wlpgd8R0f/4b5gGxW+v9pyJCgQnLlRu7DedVSvv7+GMtj3g9r3nhJ
23
+ KqECAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFI/o
24
+ maf34HXbUOQsdoLHacEKQgunMB0GA1UdEQQWMBSBEmFkbWluc0BzaG9waWZ5LmNv
25
+ bTAdBgNVHRIEFjAUgRJhZG1pbnNAc2hvcGlmeS5jb20wDQYJKoZIhvcNAQEFBQAD
26
+ ggEBADkK9aj5T0HPExsov4EoMWFnO+G7RQ28C30VAfKxnL2UxG6i4XMHVs6Xi94h
27
+ qXFw1ec9Y2eDUqaolT3bviOk9BB197+A8Vz/k7MC6ci2NE+yDDB7HAC8zU6LAx8Y
28
+ Iqvw7B/PSZ/pz4bUVFlTATif4mi1vO3lidRkdHRtM7UePSn2rUpOi0gtXBP3bLu5
29
+ YjHJN7wx5cugMEyroKITG5gL0Nxtu21qtOlHX4Hc4KdE2JqzCPOsS4zsZGhgwhPs
30
+ fl3hbtVFTqbOlwL9vy1fudXcolIE/ZTcxQ+er07ZFZdKCXayR9PPs64heamfn0fp
31
+ TConQSX2BnZdhIEYW+cKzEC/bLc=
32
+ -----END CERTIFICATE-----
11
33
  date: 2013-11-21 00:00:00.000000000 Z
12
34
  dependencies:
13
35
  - !ruby/object:Gem::Dependency
14
36
  name: sass
15
37
  requirement: !ruby/object:Gem::Requirement
16
38
  requirements:
17
- - - '>='
39
+ - - "~>"
18
40
  - !ruby/object:Gem::Version
19
- version: '0'
41
+ version: 3.2.12
20
42
  type: :runtime
21
43
  prerelease: false
22
44
  version_requirements: !ruby/object:Gem::Requirement
23
45
  requirements:
24
- - - '>='
46
+ - - "~>"
25
47
  - !ruby/object:Gem::Version
26
- version: '0'
48
+ version: 3.2.12
27
49
  - !ruby/object:Gem::Dependency
28
50
  name: coffee-script
29
51
  requirement: !ruby/object:Gem::Requirement
30
52
  requirements:
31
- - - '>='
53
+ - - "~>"
32
54
  - !ruby/object:Gem::Version
33
- version: 1.6.2
55
+ version: 2.2.0
34
56
  type: :runtime
35
57
  prerelease: false
36
58
  version_requirements: !ruby/object:Gem::Requirement
37
59
  requirements:
38
- - - '>='
60
+ - - "~>"
39
61
  - !ruby/object:Gem::Version
40
- version: 1.6.2
62
+ version: 2.2.0
41
63
  - !ruby/object:Gem::Dependency
42
64
  name: execjs
43
65
  requirement: !ruby/object:Gem::Requirement
44
66
  requirements:
45
- - - '>='
67
+ - - "~>"
46
68
  - !ruby/object:Gem::Version
47
- version: 2.0.0
69
+ version: 2.0.2
48
70
  type: :runtime
49
71
  prerelease: false
50
72
  version_requirements: !ruby/object:Gem::Requirement
51
73
  requirements:
52
- - - '>='
74
+ - - "~>"
53
75
  - !ruby/object:Gem::Version
54
- version: 2.0.0
76
+ version: 2.0.2
55
77
  - !ruby/object:Gem::Dependency
56
78
  name: sinatra
57
79
  requirement: !ruby/object:Gem::Requirement
58
80
  requirements:
59
- - - '>='
81
+ - - "~>"
60
82
  - !ruby/object:Gem::Version
61
- version: '0'
83
+ version: 1.4.4
62
84
  type: :runtime
63
85
  prerelease: false
64
86
  version_requirements: !ruby/object:Gem::Requirement
65
87
  requirements:
66
- - - '>='
88
+ - - "~>"
67
89
  - !ruby/object:Gem::Version
68
- version: '0'
90
+ version: 1.4.4
69
91
  - !ruby/object:Gem::Dependency
70
92
  name: sinatra-contrib
71
93
  requirement: !ruby/object:Gem::Requirement
72
94
  requirements:
73
- - - '>='
95
+ - - "~>"
74
96
  - !ruby/object:Gem::Version
75
- version: '0'
97
+ version: 1.4.2
76
98
  type: :runtime
77
99
  prerelease: false
78
100
  version_requirements: !ruby/object:Gem::Requirement
79
101
  requirements:
80
- - - '>='
102
+ - - "~>"
81
103
  - !ruby/object:Gem::Version
82
- version: '0'
104
+ version: 1.4.2
83
105
  - !ruby/object:Gem::Dependency
84
106
  name: thin
85
107
  requirement: !ruby/object:Gem::Requirement
86
108
  requirements:
87
- - - '>='
109
+ - - "~>"
88
110
  - !ruby/object:Gem::Version
89
- version: '0'
111
+ version: 1.6.1
90
112
  type: :runtime
91
113
  prerelease: false
92
114
  version_requirements: !ruby/object:Gem::Requirement
93
115
  requirements:
94
- - - '>='
116
+ - - "~>"
95
117
  - !ruby/object:Gem::Version
96
- version: '0'
118
+ version: 1.6.1
97
119
  - !ruby/object:Gem::Dependency
98
120
  name: rufus-scheduler
99
121
  requirement: !ruby/object:Gem::Requirement
100
122
  requirements:
101
- - - ~>
123
+ - - "~>"
102
124
  - !ruby/object:Gem::Version
103
- version: '2.0'
125
+ version: 3.0.3
104
126
  type: :runtime
105
127
  prerelease: false
106
128
  version_requirements: !ruby/object:Gem::Requirement
107
129
  requirements:
108
- - - ~>
130
+ - - "~>"
109
131
  - !ruby/object:Gem::Version
110
- version: '2.0'
132
+ version: 3.0.3
111
133
  - !ruby/object:Gem::Dependency
112
134
  name: thor
113
135
  requirement: !ruby/object:Gem::Requirement
114
136
  requirements:
115
- - - '>='
137
+ - - "~>"
116
138
  - !ruby/object:Gem::Version
117
- version: '0'
139
+ version: 0.18.1
118
140
  type: :runtime
119
141
  prerelease: false
120
142
  version_requirements: !ruby/object:Gem::Requirement
121
143
  requirements:
122
- - - '>='
144
+ - - "~>"
123
145
  - !ruby/object:Gem::Version
124
- version: '0'
146
+ version: 0.18.1
125
147
  - !ruby/object:Gem::Dependency
126
148
  name: sprockets
127
149
  requirement: !ruby/object:Gem::Requirement
128
150
  requirements:
129
- - - '>='
151
+ - - "~>"
130
152
  - !ruby/object:Gem::Version
131
- version: '0'
153
+ version: 2.10.1
132
154
  type: :runtime
133
155
  prerelease: false
134
156
  version_requirements: !ruby/object:Gem::Requirement
135
157
  requirements:
136
- - - '>='
158
+ - - "~>"
137
159
  - !ruby/object:Gem::Version
138
- version: '0'
160
+ version: 2.10.1
139
161
  - !ruby/object:Gem::Dependency
140
162
  name: rack
141
163
  requirement: !ruby/object:Gem::Requirement
142
164
  requirements:
143
- - - '>='
165
+ - - "~>"
144
166
  - !ruby/object:Gem::Version
145
- version: '0'
167
+ version: 1.5.2
146
168
  type: :runtime
147
169
  prerelease: false
148
170
  version_requirements: !ruby/object:Gem::Requirement
149
171
  requirements:
150
- - - '>='
172
+ - - "~>"
151
173
  - !ruby/object:Gem::Version
152
- version: '0'
174
+ version: 1.5.2
175
+ - !ruby/object:Gem::Dependency
176
+ name: rake
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: 10.1.0
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: 10.1.0
189
+ - !ruby/object:Gem::Dependency
190
+ name: haml
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - "~>"
194
+ - !ruby/object:Gem::Version
195
+ version: 4.0.4
196
+ type: :development
197
+ prerelease: false
198
+ version_requirements: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - "~>"
201
+ - !ruby/object:Gem::Version
202
+ version: 4.0.4
203
+ - !ruby/object:Gem::Dependency
204
+ name: minitest
205
+ requirement: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: 5.2.0
210
+ type: :development
211
+ prerelease: false
212
+ version_requirements: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - "~>"
215
+ - !ruby/object:Gem::Version
216
+ version: 5.2.0
217
+ - !ruby/object:Gem::Dependency
218
+ name: mocha
219
+ requirement: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - "~>"
222
+ - !ruby/object:Gem::Version
223
+ version: 0.14.0
224
+ type: :development
225
+ prerelease: false
226
+ version_requirements: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - "~>"
229
+ - !ruby/object:Gem::Version
230
+ version: 0.14.0
231
+ - !ruby/object:Gem::Dependency
232
+ name: fakeweb
233
+ requirement: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - "~>"
236
+ - !ruby/object:Gem::Version
237
+ version: 1.3.0
238
+ type: :development
239
+ prerelease: false
240
+ version_requirements: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - "~>"
243
+ - !ruby/object:Gem::Version
244
+ version: 1.3.0
245
+ - !ruby/object:Gem::Dependency
246
+ name: simplecov
247
+ requirement: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - "~>"
250
+ - !ruby/object:Gem::Version
251
+ version: 0.8.2
252
+ type: :development
253
+ prerelease: false
254
+ version_requirements: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - "~>"
257
+ - !ruby/object:Gem::Version
258
+ version: 0.8.2
153
259
  description: This framework lets you build & easily layout dashboards with your own
154
260
  custom widgets. Use it to make a status boards for your ops team, or use it to track
155
261
  signups, conversion rates, or whatever else metrics you'd like to see in one spot.
@@ -163,13 +269,21 @@ extensions: []
163
269
  extra_rdoc_files: []
164
270
  files:
165
271
  - README.md
272
+ - bin/dashing
166
273
  - javascripts/batman.jquery.js
167
274
  - javascripts/batman.js
168
275
  - javascripts/dashing.coffee
169
276
  - javascripts/es5-shim.js
170
277
  - javascripts/jquery.js
278
+ - lib/dashing.rb
279
+ - lib/dashing/app.rb
280
+ - lib/dashing/cli.rb
281
+ - lib/dashing/downloader.rb
171
282
  - templates/dashboard/%name%.erb.tt
172
283
  - templates/job/%name%.rb
284
+ - templates/project/.gitignore
285
+ - templates/project/Gemfile
286
+ - templates/project/README.md
173
287
  - templates/project/assets/fonts/fontawesome-webfont.eot
174
288
  - templates/project/assets/fonts/fontawesome-webfont.svg
175
289
  - templates/project/assets/fonts/fontawesome-webfont.ttf
@@ -189,14 +303,13 @@ files:
189
303
  - templates/project/dashboards/layout.erb
190
304
  - templates/project/dashboards/sample.erb
191
305
  - templates/project/dashboards/sampletv.erb
192
- - templates/project/Gemfile
193
306
  - templates/project/jobs/buzzwords.rb
194
307
  - templates/project/jobs/convergence.rb
195
308
  - templates/project/jobs/sample.rb
196
309
  - templates/project/jobs/twitter.rb
310
+ - templates/project/lib/.empty_directory
197
311
  - templates/project/public/404.html
198
312
  - templates/project/public/favicon.ico
199
- - templates/project/README.md
200
313
  - templates/project/widgets/clock/clock.coffee
201
314
  - templates/project/widgets/clock/clock.html
202
315
  - templates/project/widgets/clock/clock.scss
@@ -227,10 +340,6 @@ files:
227
340
  - templates/widget/%name%/%name%.coffee.tt
228
341
  - templates/widget/%name%/%name%.html
229
342
  - templates/widget/%name%/%name%.scss.tt
230
- - templates/project/.gitignore
231
- - templates/project/lib/.empty_directory
232
- - lib/dashing.rb
233
- - bin/dashing
234
343
  homepage: http://shopify.github.com/dashing
235
344
  licenses: []
236
345
  metadata: {}
@@ -240,17 +349,17 @@ require_paths:
240
349
  - lib
241
350
  required_ruby_version: !ruby/object:Gem::Requirement
242
351
  requirements:
243
- - - '>='
352
+ - - ">="
244
353
  - !ruby/object:Gem::Version
245
354
  version: '0'
246
355
  required_rubygems_version: !ruby/object:Gem::Requirement
247
356
  requirements:
248
- - - '>='
357
+ - - ">="
249
358
  - !ruby/object:Gem::Version
250
359
  version: '0'
251
360
  requirements: []
252
361
  rubyforge_project:
253
- rubygems_version: 2.0.3
362
+ rubygems_version: 2.2.0
254
363
  signing_key:
255
364
  specification_version: 4
256
365
  summary: The exceptionally handsome dashboard framework.
@@ -0,0 +1,3 @@
1
+ ��@�&eP۩�t�e6Ԩj T��wm� �r�&���7��f���fm�d�N
2
+ m�����F��u������+��(���{<�@���E�{�Nx�&ja+�S`���ba6���~����(l"p���C�<�ɍF|�,��x��(x��̽Z
3
+ $8�\�nCl.!��k/ ��za��+�!