dashing 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
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��+�!