que-web 0.4.0 → 0.5.0

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: e462dea7156e236045867d2dc8738e060f62517d
4
- data.tar.gz: 8d01b77c484316f7b34a4dff2f0c61d432fbe92e
3
+ metadata.gz: 7a2be8dc64c1ad88ec87d8850ca883595b6ddd37
4
+ data.tar.gz: 2d0157762713b670c0d06be83ff0b48976164254
5
5
  SHA512:
6
- metadata.gz: dcb503d51659fcded547811282f5bee869312fc17a2006bcb36da240fcea46fb1c6de959832620c4d17b2154d8f427cb9c5d4ae1e1ea2263561551a938fbd2ed
7
- data.tar.gz: b8a3383ffec238ec16c63a07d7a78f02b306ed12482c45eba53c8a3bd564efb95a6db50c143c496b4f22a115edda3d729fbc982a3ec7db094d4558bc0d706655
6
+ metadata.gz: 14476a70a236bc448525729dda19d0c13432daa7e81568b5dcd9a640885370c3f3943277fbeb9facd224d867edf7ecb424687aebf11ed4a7cfab945ff1e8d904
7
+ data.tar.gz: e8d894075794550693695fcbb288f1ce16669e79b815c38e6b30378b773bb17629e169fc50625dbdea609d38e07d818d495ddcfca4fd902023b0e2b20ef5f517
data/README.md CHANGED
@@ -22,7 +22,9 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- In your `config.ru` add
25
+ #### With `config.ru`
26
+
27
+ Add in `config.ru`:
26
28
 
27
29
  ```ruby
28
30
  require "que/web"
@@ -32,14 +34,50 @@ map "/que" do
32
34
  end
33
35
  ```
34
36
 
35
- Or in Rails `config/routes.rb`
37
+ ### Rails
38
+
39
+ In `config/routes.rb`:
36
40
 
37
41
  ```ruby
38
42
  require "que/web"
39
43
  mount Que::Web => "/que"
40
44
  ```
41
45
 
42
- If you want to use Docker, run:
46
+ #### Rails 5.0
47
+
48
+ You must use the master branch of Sinatra for `que-web`.
49
+ In your gemfile:
50
+
51
+ ```
52
+ gem 'que-web'
53
+ gem 'sinatra', git: 'https://github.com/sinatra/sinatra'
54
+ ```
55
+
56
+ See https://github.com/sinatra/sinatra/issues/1071
57
+
58
+ ### Authentication
59
+
60
+ #### Devise
61
+ ```ruby
62
+ # config/routes.rb
63
+ authenticate :user do
64
+ mount Que::Web, at: 'que'
65
+ end
66
+ ```
67
+
68
+ #### Basic HTTP auth
69
+
70
+ In `config/initializers/queweb.rb`:
71
+ ```ruby
72
+ Que::Web.use(Rack::Auth::Basic) do |user, password|
73
+ [user, password] == [ENV["QUEWEB_USERNAME"], ENV["QUEWEB_PASSWORD"]]
74
+ end
75
+ ```
76
+ Then add the two environment variables to your production environment.
77
+
78
+ ### Docker
79
+
80
+ Run:
43
81
  ```
44
82
  docker run -e DATABASE_URL=postgres://username:password@hostname/db_name -p 3002:8080 joevandyk/que-web
45
83
  ```
data/lib/que/web.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "sinatra"
1
+ require "sinatra/base"
2
2
  require "erubis"
3
3
 
4
4
  module Que
@@ -14,30 +14,30 @@ module Que
14
14
  set :erb, :escape_html => true
15
15
 
16
16
  get "/" do
17
- stats = Que.execute SQL[:dashboard_stats]
17
+ stats = Que.execute SQL[:dashboard_stats], [search]
18
18
  @dashboard = Viewmodels::Dashboard.new(stats[0])
19
19
  erb :index
20
20
  end
21
21
 
22
22
  get "/running" do
23
- worker_states = Que.worker_states
23
+ worker_states = search_running Que.worker_states
24
24
  pager = get_pager worker_states.count
25
25
  @list = Viewmodels::JobList.new(worker_states, pager)
26
26
  erb :running
27
27
  end
28
28
 
29
29
  get "/failing" do
30
- stats = Que.execute SQL[:dashboard_stats]
30
+ stats = Que.execute SQL[:dashboard_stats], [search]
31
31
  pager = get_pager stats[0]["failing"]
32
- failing_jobs = Que.execute SQL[:failing_jobs], [pager.page_size, pager.offset]
32
+ failing_jobs = Que.execute SQL[:failing_jobs], [pager.page_size, pager.offset, search]
33
33
  @list = Viewmodels::JobList.new(failing_jobs, pager)
34
34
  erb :failing
35
35
  end
36
36
 
37
37
  get "/scheduled" do
38
- stats = Que.execute SQL[:dashboard_stats]
38
+ stats = Que.execute SQL[:dashboard_stats], [search]
39
39
  pager = get_pager stats[0]["scheduled"]
40
- scheduled_jobs = Que.execute SQL[:scheduled_jobs], [pager.page_size, pager.offset]
40
+ scheduled_jobs = Que.execute SQL[:scheduled_jobs], [pager.page_size, pager.offset, search]
41
41
 
42
42
  @list = Viewmodels::JobList.new(scheduled_jobs, pager)
43
43
  erb :scheduled
@@ -85,6 +85,21 @@ module Que
85
85
  Pager.new(page, PAGE_SIZE, record_count)
86
86
  end
87
87
 
88
+ def search
89
+ return '%' unless search_param.present?
90
+ "%#{search_param}%"
91
+ end
92
+
93
+ def search_running(jobs)
94
+ return jobs unless search_param.present?
95
+ jobs.select { |job| job.job_class.include? search_param }
96
+ end
97
+
98
+ def search_param
99
+ return unless params['search'].present?
100
+ params['search'].gsub(/[^0-9A-Za-z:]/, '')
101
+ end
102
+
88
103
  after { session[FLASH_KEY] = {} if @sweep_flash }
89
104
 
90
105
  helpers do
@@ -92,6 +107,15 @@ module Que
92
107
  "#{env['SCRIPT_NAME']}/"
93
108
  end
94
109
 
110
+ def link_to(path)
111
+ to path_with_search(path)
112
+ end
113
+
114
+ def path_with_search(path)
115
+ path += "?search=#{search_param}" if search_param.present?
116
+ path
117
+ end
118
+
95
119
  def active_class(pattern)
96
120
  if request.path.match pattern
97
121
  "active"
@@ -109,9 +133,6 @@ module Que
109
133
  end
110
134
 
111
135
  def relative_time(time)
112
- if time.is_a?(String)
113
- time = Time.parse(time)
114
- end
115
136
  %{<time class="timeago" datetime="#{time.utc.iso8601}">#{time.utc}</time>}
116
137
  end
117
138
 
data/lib/que/web/sql.rb CHANGED
@@ -1,56 +1,58 @@
1
1
  Que::Web::SQL = {
2
- :dashboard_stats => %{
3
- SELECT count(*) AS total,
4
- count(locks.job_id) AS running,
5
- coalesce(sum((error_count > 0 AND locks.job_id IS NULL)::int), 0) AS failing,
6
- coalesce(sum((error_count = 0 AND locks.job_id IS NULL)::int), 0) AS scheduled
7
- FROM que_jobs
8
- LEFT JOIN (
9
- SELECT (classid::bigint << 32) + objid::bigint AS job_id
10
- FROM pg_locks
11
- WHERE locktype = 'advisory'
12
- ) locks USING (job_id)
13
- }.freeze,
14
- :failing_jobs => %{
15
- SELECT que_jobs.*
16
- FROM que_jobs
17
- LEFT JOIN (
18
- SELECT (classid::bigint << 32) + objid::bigint AS job_id
19
- FROM pg_locks
20
- WHERE locktype = 'advisory'
21
- ) locks USING (job_id)
22
- WHERE locks.job_id IS NULL AND error_count > 0
23
- ORDER BY run_at
24
- LIMIT $1::int
25
- OFFSET $2::int
26
- }.freeze,
27
- :scheduled_jobs => %{
28
- SELECT que_jobs.*
29
- FROM que_jobs
30
- LEFT JOIN (
31
- SELECT (classid::bigint << 32) + objid::bigint AS job_id
32
- FROM pg_locks
33
- WHERE locktype = 'advisory'
34
- ) locks USING (job_id)
35
- WHERE locks.job_id IS NULL AND error_count = 0
36
- ORDER BY run_at
37
- LIMIT $1::int
38
- OFFSET $2::int
39
- }.freeze,
40
- :delete_job => %{
41
- DELETE
42
- FROM que_jobs
43
- WHERE job_id = $1::bigint
44
- }.freeze,
45
- :reschedule_job => %{
46
- UPDATE que_jobs
47
- SET run_at = $2::timestamptz
48
- WHERE job_id = $1::bigint
49
- }.freeze,
50
- :fetch_job => %{
51
- SELECT *
52
- FROM que_jobs
53
- WHERE job_id = $1::bigint
54
- LIMIT 1
55
- }.freeze,
2
+ dashboard_stats: <<-SQL.freeze,
3
+ SELECT count(*) AS total,
4
+ count(locks.job_id) AS running,
5
+ coalesce(sum((error_count > 0 AND locks.job_id IS NULL)::int), 0) AS failing,
6
+ coalesce(sum((error_count = 0 AND locks.job_id IS NULL)::int), 0) AS scheduled
7
+ FROM que_jobs
8
+ LEFT JOIN (
9
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
10
+ FROM pg_locks
11
+ WHERE locktype = 'advisory'
12
+ ) locks USING (job_id)
13
+ WHERE
14
+ job_class LIKE ($1)
15
+ SQL
16
+ failing_jobs: <<-SQL.freeze,
17
+ SELECT que_jobs.*
18
+ FROM que_jobs
19
+ LEFT JOIN (
20
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
21
+ FROM pg_locks
22
+ WHERE locktype = 'advisory'
23
+ ) locks USING (job_id)
24
+ WHERE locks.job_id IS NULL AND error_count > 0 AND job_class LIKE ($3)
25
+ ORDER BY run_at
26
+ LIMIT $1::int
27
+ OFFSET $2::int
28
+ SQL
29
+ scheduled_jobs: <<-SQL.freeze,
30
+ SELECT que_jobs.*
31
+ FROM que_jobs
32
+ LEFT JOIN (
33
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
34
+ FROM pg_locks
35
+ WHERE locktype = 'advisory'
36
+ ) locks USING (job_id)
37
+ WHERE locks.job_id IS NULL AND error_count = 0 AND job_class LIKE ($3)
38
+ ORDER BY run_at
39
+ LIMIT $1::int
40
+ OFFSET $2::int
41
+ SQL
42
+ delete_job: <<-SQL.freeze,
43
+ DELETE
44
+ FROM que_jobs
45
+ WHERE job_id = $1::bigint
46
+ SQL
47
+ reschedule_job: <<-SQL.freeze,
48
+ UPDATE que_jobs
49
+ SET run_at = $2::timestamptz
50
+ WHERE job_id = $1::bigint
51
+ SQL
52
+ fetch_job: <<-SQL.freeze,
53
+ SELECT *
54
+ FROM que_jobs
55
+ WHERE job_id = $1::bigint
56
+ LIMIT 1
57
+ SQL
56
58
  }.freeze
data/que-web.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "que-web"
7
- spec.version = "0.4.0"
7
+ spec.version = "0.5.0"
8
8
  spec.authors = ["Jason Staten"]
9
9
  spec.email = ["jstaten07@gmail.com"]
10
10
  spec.summary = %q{A web interface for the que queue}
@@ -71,3 +71,7 @@ pre {
71
71
  i.subtle {
72
72
  color: #999999;
73
73
  }
74
+
75
+ .search {
76
+ margin-top: 15px;
77
+ }
@@ -1,14 +1,14 @@
1
1
  <nav class="top-bar" data-topbar role="navigation">
2
2
  <ul class="title-area">
3
3
  <li class="name">
4
- <h1><a href="<%= root_path %>">Que</a></h1>
4
+ <h1><a href="<%= path_with_search root_path %>">Que</a></h1>
5
5
  </li>
6
6
  </ul>
7
7
  <section class="top-bar-section">
8
8
  <ul class="left">
9
- <li class="<%= active_class('running') %>"><a href="<%= to 'running' %>"><span>Running</span></a></li>
10
- <li class="<%= active_class('scheduled') %>"><a href="<%= to 'scheduled' %>"><span>Scheduled</span></a></li>
11
- <li class="<%= active_class('failing') %>"><a href="<%= to 'failing' %>"><span>Failing</span></a></li>
9
+ <li class="<%= active_class('running') %>"><a href="<%= link_to 'running' %>"><span>Running</span></a></li>
10
+ <li class="<%= active_class('scheduled') %>"><a href="<%= link_to 'scheduled' %>"><span>Scheduled</span></a></li>
11
+ <li class="<%= active_class('failing') %>"><a href="<%= link_to 'failing' %>"><span>Failing</span></a></li>
12
12
  </ul>
13
13
  <ul class="right version">
14
14
  <li>Que <%= Que::Version %></li>
@@ -0,0 +1,10 @@
1
+ <form class="search" action="<%= request.path %>" method="get">
2
+ <div class="row collapse">
3
+ <div class="small-8 columns">
4
+ <input type="text" name="search" value="<%= search_param %>" />
5
+ </div>
6
+ <div class="small-4 columns">
7
+ <button class="button postfix">Search</button>
8
+ </div>
9
+ </div>
10
+ </form>
@@ -1,7 +1,10 @@
1
1
  <div class="row">
2
- <div class="small-12 columns">
2
+ <div class="small-12 medium-8 columns">
3
3
  <h1><%= @list.total %> Failing Job<%= @list.total == 1 ? "" : "s" %></h1>
4
4
  </div>
5
+ <div class="small-12 medium-4 columns">
6
+ <%== erb :_search %>
7
+ </div>
5
8
  </div>
6
9
  <div class="row">
7
10
  <div class="small-12 columns">
@@ -21,7 +24,7 @@
21
24
  <tbody>
22
25
  <% @list.page_jobs.each do |job| %>
23
26
  <tr>
24
- <td><a href="<%= to "jobs/#{job.job_id}" %>">
27
+ <td><a href="<%= link_to "jobs/#{job.job_id}" %>">
25
28
  <%== relative_time job.run_at %></a>
26
29
  <%== erb :_past_due, locals: {job: job} %>
27
30
  </td>
@@ -31,13 +34,13 @@
31
34
  <td><pre><%= format_args job %></pre></td>
32
35
  <td><%= format_error job %></pre></td>
33
36
  <td>
34
- <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
37
+ <form action="<%= link_to "jobs/#{job.job_id}" %>" method="post">
35
38
  <input type="hidden" name="_method" value="put" />
36
39
  <button class="plain" title="Retry Immediately"><i class="fa fa-refresh"></i></button>
37
40
  </form>
38
41
  </td>
39
42
  <td>
40
- <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
43
+ <form action="<%= link_to "jobs/#{job.job_id}" %>" method="post">
41
44
  <input type="hidden" name="_method" value="delete" />
42
45
  <button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
43
46
  </form>
data/web/views/index.erb CHANGED
@@ -1,10 +1,13 @@
1
1
  <div class="row">
2
- <div class="small-12 columns">
2
+ <div class="small-12 medium-8 columns">
3
3
  <h1>Jobs</h1>
4
4
  </div>
5
+ <div class="small-12 medium-4 columns">
6
+ <%== erb :_search %>
7
+ </div>
5
8
  </div>
6
9
  <div class="row">
7
- <a class="small-12 large-4 columns" href="<%= to 'running' %>">
10
+ <a class="small-12 large-4 columns" href="<%= link_to 'running' %>">
8
11
  <div class="dashboard-stat running">
9
12
  <div class="cell">
10
13
  <h2>Running<h2>
@@ -14,7 +17,7 @@
14
17
  </div>
15
18
  </div>
16
19
  </a>
17
- <a class="small-12 large-4 columns" href="<%= to 'scheduled' %>">
20
+ <a class="small-12 large-4 columns" href="<%= link_to 'scheduled' %>">
18
21
  <div class="dashboard-stat scheduled">
19
22
  <div class="cell">
20
23
  <h2>Scheduled<h2>
@@ -24,7 +27,7 @@
24
27
  </div>
25
28
  </div>
26
29
  </a>
27
- <a class="small-12 large-4 columns" href="<%= to 'failing' %>">
30
+ <a class="small-12 large-4 columns" href="<%= link_to 'failing' %>">
28
31
  <div class="dashboard-stat failing">
29
32
  <div class="cell">
30
33
  <h2>Failing<h2>
@@ -1,7 +1,10 @@
1
1
  <div class="row">
2
- <div class="small-12 columns">
2
+ <div class="small-12 medium-8 columns">
3
3
  <h1><%= @list.total %> Running Job<%= @list.total == 1 ? "" : "s" %></h1>
4
4
  </div>
5
+ <div class="small-12 medium-4 columns">
6
+ <%== erb :_search %>
7
+ </div>
5
8
  </div>
6
9
  <div class="row">
7
10
  <div class="small-12 columns">
@@ -1,7 +1,10 @@
1
1
  <div class="row">
2
- <div class="small-12 columns">
2
+ <div class="small-12 medium-8 columns">
3
3
  <h1><%= @list.total %> Scheduled Job<%= @list.total == 1 ? "" : "s" %></h1>
4
4
  </div>
5
+ <div class="small-12 medium-4 columns">
6
+ <%== erb :_search %>
7
+ </div>
5
8
  </div>
6
9
  <div class="row">
7
10
  <div class="small-12 columns">
@@ -20,20 +23,20 @@
20
23
  <% @list.page_jobs.each do |job| %>
21
24
  <tr>
22
25
  <td>
23
- <a href="<%= to "jobs/#{job.job_id}" %>"><%== relative_time job.run_at %></a>
26
+ <a href="<%= link_to "jobs/#{job.job_id}" %>"><%== relative_time job.run_at %></a>
24
27
  <%== erb :_past_due, locals: {job: job}%>
25
28
  </td>
26
29
  <td><%= job.job_class %></td>
27
30
  <td><%= job.queue %></td>
28
31
  <td><pre><%= format_args job %></pre></td>
29
32
  <td>
30
- <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
33
+ <form action="<%= link_to "jobs/#{job.job_id}" %>" method="post">
31
34
  <input type="hidden" name="_method" value="put" />
32
35
  <button class="plain" title="Run Immediately"><i class="fa fa-play-circle"></i></button>
33
36
  </form>
34
37
  </td>
35
38
  <td>
36
- <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
39
+ <form action="<%= link_to "jobs/#{job.job_id}" %>" method="post">
37
40
  <input type="hidden" name="_method" value="delete" />
38
41
  <button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
39
42
  </form>
data/web/views/show.erb CHANGED
@@ -44,11 +44,11 @@
44
44
  </div>
45
45
  <div class="row">
46
46
  <div class="small-12 columns">
47
- <form class="form-inline" action="<%= to "/jobs/#{@job.job_id}" %>" method="post">
47
+ <form class="form-inline" action="<%= link_to "/jobs/#{@job.job_id}" %>" method="post">
48
48
  <input type="hidden" name="_method" value="put" />
49
49
  <button><i class="fa fa-play-circle"></i> Run Immediately</button>
50
50
  </form>
51
- <form class="form-inline" maction="<%= to "/jobs/#{@job.job_id}" %>" method="post">
51
+ <form class="form-inline" maction="<%= link_to "/jobs/#{@job.job_id}" %>" method="post">
52
52
  <input type="hidden" name="_method" value="Delete" />
53
53
  <button class="button alert"><i class="fa fa-trash"></i> Delete</button>
54
54
  </form>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Staten
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-09 00:00:00.000000000 Z
11
+ date: 2017-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: que
@@ -150,6 +150,7 @@ files:
150
150
  - web/views/_navbar.erb
151
151
  - web/views/_pager.erb
152
152
  - web/views/_past_due.erb
153
+ - web/views/_search.erb
153
154
  - web/views/failing.erb
154
155
  - web/views/index.erb
155
156
  - web/views/layout.erb
@@ -176,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
177
  version: '0'
177
178
  requirements: []
178
179
  rubyforge_project:
179
- rubygems_version: 2.2.2
180
+ rubygems_version: 2.6.11
180
181
  signing_key:
181
182
  specification_version: 4
182
183
  summary: A web interface for the que queue