queue_classic_admin 0.0.10 → 0.0.11

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: 3a58c69e7e867116a6c77b00df9c6005ad3f5599
4
- data.tar.gz: 39f32e4d9a8204087f939833df9109ac356ba3a5
3
+ metadata.gz: 41a0eb24e9a9c27f51984d4752a4968996fa6b17
4
+ data.tar.gz: 2d04cb799e6465d420aaded11d2372364aed63c3
5
5
  SHA512:
6
- metadata.gz: 0352c8793f908735b614110b0fe8f060a5e8514425807466f343d81b84310667aaa18b27838040a4c0c133497ba2a5714e4a2fec2a5f2471419c6fdcd54feabe
7
- data.tar.gz: 7f618ede8f3f8c7e3599951a7033c693b10026ed1398c6a39f9e94eb990a0b3bf2d5f2a56232be99f99917dd479d6298930d69ba0f5e378cfe1d6876f4d97b9f
6
+ metadata.gz: 5d05e96c59f06aa118cd1e5c15689ecc2078d849f9d73ecc1ccd857650b7ade9a856e6c6a17a2bc41b95a090241b873747c32193c46d695edb4e8fe6e10d1677
7
+ data.tar.gz: 9f3dd7e54e6509deb451c4bfb099fd5cfa73652cd914b6db362d6d46a1813c23bf2967cc3f195e0113952f056f6d86bfacea29e3781719c1be9ab542022f6f15
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Queue Classic Admin
2
2
 
3
+ [![Build Status](https://travis-ci.org/rainforestapp/queue_classic_admin.png)](https://travis-ci.org/rainforestapp/queue_classic_admin)
4
+
3
5
  An admin interface for the [queue_classic](https://github.com/ryandotsmith/queue_classic) and [queue_classic-later](https://github.com/dpiddy/queue_classic-later) gems.
4
6
 
5
7
  ![qc admin](https://f.cloud.github.com/assets/148622/865030/9b1b2610-f62e-11e2-8908-8c271bfe0f6c.png)
@@ -12,6 +14,7 @@ An admin interface for the [queue_classic](https://github.com/ryandotsmith/queue
12
14
  * Delete entire queues
13
15
  * Delete jobs
14
16
 
17
+
15
18
  # Install
16
19
 
17
20
  Copy and run the migrations
@@ -23,7 +26,34 @@ Mount in your rails app config/routes.rb file
23
26
 
24
27
  mount QueueClassicAdmin::Engine => "/queue_classic_admin"
25
28
 
26
- # TODO
29
+ # Configuration
30
+
31
+ ## Custom searchable fields
32
+
33
+ ```ruby
34
+ QueueClassicJob.searchable_columns << :my_custom_fields
35
+
36
+ ```
37
+
38
+ ## Custom job action
39
+
40
+ ```ruby
41
+ QueueClassicAdmin.add_custom_action "Retry" do |job|
42
+ job.q_name = "low"
43
+ job.save!
44
+ end
45
+ ```
46
+
47
+ # Development
48
+
49
+ You can develop with POW by configuring it like so:
50
+
51
+ ```bash
52
+ ln -s $PWD/spec/dummy ~/.pow/qc-admin
53
+ (cd spec/dummy && rake db:create:all db:migrate)
54
+
55
+ ln -s $PWD/spec/dummy-no-later ~/.pow/qc-admin-no-later
56
+ (cd spec/dummy-no-later && rake db:create:all db:migrate)
57
+ ```
27
58
 
28
- - Use something more lightweight than bootstrap
29
- - Don't die if the queue_classic-later gem is missing
59
+ Then go to [http://qc-admin.dev/](http://qc-admin.dev/).
data/Rakefile CHANGED
@@ -23,7 +23,8 @@ end
23
23
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
24
  load 'rails/tasks/engine.rake'
25
25
 
26
-
27
-
28
26
  Bundler::GemHelper.install_tasks
29
27
 
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec)
30
+ task :default => :spec
@@ -16,3 +16,8 @@
16
16
  body .container-fluid .row-fluid {
17
17
  padding-top: 60px;
18
18
  }
19
+
20
+ #search {
21
+ display: inline-block;
22
+ float: right;
23
+ }
@@ -3,10 +3,16 @@ module QueueClassicAdmin
3
3
  protected
4
4
  def filter_jobs(klass)
5
5
  @klass = klass
6
- @queue_classic_jobs = klass.scoped
6
+ @queue_classic_jobs = klass.order("id DESC")
7
7
  if params[:q_name].present?
8
8
  @queue_classic_jobs = @queue_classic_jobs.where(q_name: params[:q_name])
9
9
  end
10
+ if params[:search].present?
11
+ @queue_classic_jobs = @queue_classic_jobs.search(params[:search])
12
+ end
13
+ if params[:sort].present?
14
+ @queue_classic_jobs = @queue_classic_jobs.reorder("#{params[:sort]} #{params[:dir]}")
15
+ end
10
16
  @queue_classic_jobs
11
17
  end
12
18
  end
@@ -2,7 +2,7 @@ require_dependency "queue_classic_admin/application_controller"
2
2
 
3
3
  module QueueClassicAdmin
4
4
  class QueueClassicJobsController < ApplicationController
5
- before_filter :get_job, only: [:destroy, :unlock]
5
+ before_filter :get_job, only: [:destroy, :unlock, :custom]
6
6
  def index
7
7
  filter_jobs(QueueClassicJob)
8
8
  @queue_classic_jobs = @queue_classic_jobs.paginate(page: params[:page])
@@ -10,14 +10,14 @@ module QueueClassicAdmin
10
10
 
11
11
  def destroy
12
12
  @queue_classic_job.destroy
13
- redirect_to queue_classic_jobs_url
13
+ redirect_to :back
14
14
  end
15
15
 
16
16
  def destroy_all
17
17
  filter_jobs(QueueClassicJob).delete_all
18
18
  redirect_to queue_classic_jobs_url
19
19
  end
20
-
20
+
21
21
  def unlock_all
22
22
  filter_jobs(QueueClassicJob).where('locked_at < ?', 5.minutes.ago).update_all(locked_at: nil)
23
23
  redirect_to queue_classic_jobs_url
@@ -26,8 +26,13 @@ module QueueClassicAdmin
26
26
  def unlock
27
27
  @queue_classic_job.locked_at = nil
28
28
  @queue_classic_job.save
29
-
30
- redirect_to queue_classic_jobs_url
29
+ redirect_to :back
30
+ end
31
+
32
+ def custom
33
+ custom_action = QueueClassicAdmin.custom_actions[params[:custom_action]]
34
+ custom_action.action.call(@queue_classic_job)
35
+ redirect_to :back
31
36
  end
32
37
 
33
38
  private
@@ -1,4 +1,26 @@
1
1
  module QueueClassicAdmin
2
2
  module ApplicationHelper
3
+ def has_qc_later?
4
+ QC.respond_to?(:enqueue_in) &&
5
+ defined?(QC::Later) &&
6
+ ActiveRecord::Base.connection.table_exists?(QC::Later::TABLE_NAME)
7
+ end
8
+
9
+ def sortable_column(name, title)
10
+ opts = {sort: name}
11
+ opts[:dir] = (params[:dir] == "asc" ? "desc" : "asc")
12
+ content_tag :th do
13
+ s = link_to title, params.merge(opts)
14
+ if params[:sort] == name.to_s
15
+ icon = if params[:dir] == 'asc'
16
+ "&uarr;"
17
+ else
18
+ "&darr;"
19
+ end
20
+ s += raw(icon)
21
+ end
22
+ s.html_safe
23
+ end
24
+ end
3
25
  end
4
26
  end
@@ -2,6 +2,8 @@ module QueueClassicAdmin
2
2
  module JobCommon
3
3
  module ClassMethods
4
4
  KNOWN_COLUMN = ["id", "q_name", "method", "args", "locked_at", "created_at", "not_before"]
5
+ SEARCHABLE_COLUMNS = [ :method, :args ]
6
+
5
7
  def queue_counts
6
8
  group(:q_name).count
7
9
  end
@@ -9,14 +11,27 @@ module QueueClassicAdmin
9
11
  def extra_columns
10
12
  columns.map(&:name) - KNOWN_COLUMN
11
13
  end
14
+
15
+ def searchable_columns
16
+ @searchable_columns ||= SEARCHABLE_COLUMNS.dup
17
+ end
18
+
19
+ def search(query)
20
+ sql = searchable_columns.inject([]) do |sql, field|
21
+ sql << "#{field} LIKE ?"
22
+ end.join(" OR ")
23
+
24
+ wildcard_query = ["%", query, "%"].join
25
+ relation.where(sql, *([wildcard_query] * SEARCHABLE_COLUMNS.size))
26
+ end
12
27
  end
13
-
28
+
14
29
  module InstanceMethods
15
30
  def arguments
16
31
  JSON.parse(args)
17
32
  end
18
33
  end
19
-
34
+
20
35
  def self.included(receiver)
21
36
  receiver.extend ClassMethods
22
37
  receiver.send :include, InstanceMethods
@@ -29,7 +29,9 @@
29
29
  <div class="container-fluid nav-collapse">
30
30
  <ul class="nav">
31
31
  <li><%= link_to "Jobs", queue_classic_jobs_path %></li>
32
- <li><%= link_to "Scheduled Jobs", queue_classic_later_jobs_path %></li>
32
+ <% if has_qc_later? %>
33
+ <li><%= link_to "Scheduled Jobs", queue_classic_later_jobs_path %></li>
34
+ <% end %>
33
35
  </ul>
34
36
  </div><!--/.nav-collapse -->
35
37
  </div>
@@ -1,3 +1,10 @@
1
+ <div id="search">
2
+ <%= form_tag(url_for(params), method: 'GET') do %>
3
+ <%= hidden_field_tag :q_name, params[:q_name] %>
4
+ <input class="search-query" name="search" placeholder="Search jobs" value="<%= params[:search] %>"/>
5
+ <% end %>
6
+ </div>
7
+
1
8
  <ul class="nav nav-pills">
2
9
  <li class="<%= q_name_pill_class(nil)%>" >
3
10
  <a href="<%= index_path %>"><%= "All (#{@klass.count})" %></a>
@@ -12,25 +19,25 @@
12
19
  <table class="table table-striped table-bordered">
13
20
  <thead>
14
21
  <tr>
15
- <th>Queue</th>
16
- <th>ID</th>
17
- <th>Enqueued At</th>
18
- <th>Locked At</th>
19
- <th>Method</th>
20
- <th>Arguments</th>
22
+ <%= sortable_column :queue_name, "Queue" %>
23
+ <%= sortable_column :id, "ID" %>
24
+ <%= sortable_column :created_at, "Enqueued At" %>
25
+ <%= sortable_column :locked_at, "Locked At" %>
26
+ <%= sortable_column :method, "Method" %>
27
+ <%= sortable_column :args, "Arguments" %>
21
28
  <% if @klass.columns_hash['not_before'] %>
22
29
  <th>Run At</th>
23
30
  <% end %>
24
31
  <% @klass.extra_columns.each do |column| %>
25
- <th><%= column %></th>
32
+ <%= sortable_column column, column.titleize %>
26
33
  <% end %>
27
34
  <th>
28
35
  <%=
29
- link_to "Destroy All", url_for(params.merge(action: 'destroy_all')), class: 'btn btn-danger', data: {confirm: "Are you sure?", method: :delete}
36
+ link_to "Destroy Matching", url_for(params.merge(action: 'destroy_all')), class: 'btn btn-danger', data: {confirm: "Are you sure?", method: :delete}
30
37
  %>
31
38
  <% unless later? %>
32
39
  <%=
33
- link_to "Unlock All > 5 mins", url_for(params.merge(action: 'unlock_all')), class: 'btn btn-danger', data: {confirm: "Are you sure?", method: :put}
40
+ link_to "Unlock Matching > 5 mins", url_for(params.merge(action: 'unlock_all')), class: 'btn btn-danger', data: {confirm: "Are you sure?", method: :put}
34
41
  %>
35
42
  <% end %>
36
43
  </th>
@@ -75,6 +82,9 @@
75
82
  <% if queue_classic_job[:locked_at] %>
76
83
  <%= link_to 'Unlock', unlock_queue_classic_job_path(queue_classic_job), method: :post, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' %>
77
84
  <% end %>
85
+ <% QueueClassicAdmin.custom_actions.each do |slug, action| %>
86
+ <%= link_to action.name, custom_queue_classic_job_path(queue_classic_job, custom_action: slug), method: :post, class: "btn btn-danger" %>
87
+ <% end %>
78
88
  </td>
79
89
  </tr>
80
90
  <% end %>
data/config/routes.rb CHANGED
@@ -13,8 +13,9 @@ QueueClassicAdmin::Engine.routes.draw do
13
13
 
14
14
  member do
15
15
  post :unlock
16
+ post :custom
16
17
  end
17
18
  end
18
19
 
19
20
  root to: "queue_classic_jobs#index"
20
- end
21
+ end
@@ -0,0 +1,15 @@
1
+ module QueueClassicAdmin
2
+ class CustomAction
3
+ attr_reader :name, :action
4
+
5
+ def initialize(name, &block)
6
+ @name, @action = name, block
7
+ end
8
+
9
+ def slug
10
+ name.underscore
11
+ end
12
+
13
+ end
14
+ end
15
+
@@ -1,5 +1,13 @@
1
1
  module QueueClassicAdmin
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace QueueClassicAdmin
4
+
5
+ initializer :append_migrations do |app|
6
+ unless app.root.to_s.match root.to_s
7
+ config.paths["db/migrate"].expanded.each do |expanded_path|
8
+ app.config.paths["db/migrate"] << expanded_path
9
+ end
10
+ end
11
+ end
4
12
  end
5
13
  end
@@ -1,3 +1,3 @@
1
1
  module QueueClassicAdmin
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
@@ -1,4 +1,15 @@
1
1
  require "queue_classic_admin/engine"
2
+ require "queue_classic_admin/custom_action"
2
3
 
3
4
  module QueueClassicAdmin
5
+
6
+ def self.custom_actions
7
+ @@custom_actions ||= {}
8
+ end
9
+
10
+ def self.add_custom_action(name, &block)
11
+ action = CustomAction.new(name, &block)
12
+ custom_actions[action.slug] = action
13
+ end
4
14
  end
15
+
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queue_classic_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Mathieu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-10 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.2.13
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.13
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: queue_classic
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 2.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pg
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: will_paginate
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 3.0.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.0.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: will_paginate-bootstrap
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.2.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.2.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: twitter-bootstrap-rails
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: sqlite3
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: An admin interface for QueueClassic
@@ -142,11 +142,13 @@ files:
142
142
  - db/migrate/20130626182618_add_id_to_later.rb
143
143
  - db/migrate/20130627175128_add_created_column.rb
144
144
  - lib/queue_classic_admin.rb
145
+ - lib/queue_classic_admin/custom_action.rb
145
146
  - lib/queue_classic_admin/engine.rb
146
147
  - lib/queue_classic_admin/version.rb
147
148
  - lib/tasks/queue_classic_admin_tasks.rake
148
149
  homepage: https://github.com/rainforestapp/queue_classic_admin
149
- licenses: []
150
+ licenses:
151
+ - MIT
150
152
  metadata: {}
151
153
  post_install_message:
152
154
  rdoc_options: []
@@ -154,17 +156,17 @@ require_paths:
154
156
  - lib
155
157
  required_ruby_version: !ruby/object:Gem::Requirement
156
158
  requirements:
157
- - - '>='
159
+ - - ">="
158
160
  - !ruby/object:Gem::Version
159
161
  version: '0'
160
162
  required_rubygems_version: !ruby/object:Gem::Requirement
161
163
  requirements:
162
- - - '>='
164
+ - - ">="
163
165
  - !ruby/object:Gem::Version
164
166
  version: '0'
165
167
  requirements: []
166
168
  rubyforge_project:
167
- rubygems_version: 2.2.1
169
+ rubygems_version: 2.2.2
168
170
  signing_key:
169
171
  specification_version: 4
170
172
  summary: An admin interface for QueueClassic