curation_concerns 0.13.1 → 0.14.0.pre1

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: dbbc06a003809c33500df0e776f198252bedd77b
4
- data.tar.gz: 6a6dec48311509540d871cf371455c03b2b90674
3
+ metadata.gz: f74821b31213e7a844b8f8e5314eac62b792ccba
4
+ data.tar.gz: 3d63bba8d048b922a52e544b6296a58622137cf5
5
5
  SHA512:
6
- metadata.gz: c0f6df730b3733a86e9df107fbadd1a6ae88e81f833b202a9647f590a33ece77a13ba61af525b07504813f5f3b221ec4f77262ce9a7e42a300de392f04077bd0
7
- data.tar.gz: d1278f599af0eead707bd40eb9d8b981fd1dbd3d369d99988e772bb5c506cd7f385c87a059d3fd2a81ca76fe8f56567367c97092ecde7e3d18bac40903d07000
6
+ metadata.gz: 07a68173b77edab2e48638220ce12435e500aae53c28cb634bbe80a3ceec77e0eaba25bf722e3ad02836e0d9b4d955320247b749f035eeefe2c145bbaa60a6ba
7
+ data.tar.gz: dcd8ca994910c1f326147e3a5d261a3d4e5afbec84fb3884d09801921c80463bd6435762a54fc8cbd9116d205c60ad537857a47bbe9414b112739238db75a1e4
@@ -0,0 +1,12 @@
1
+ module CurationConcerns
2
+ class OperationsController < ApplicationController
3
+ load_and_authorize_resource
4
+
5
+ def index
6
+ @operations = @operations.where(parent_id: nil)
7
+ end
8
+
9
+ def show
10
+ end
11
+ end
12
+ end
@@ -5,7 +5,13 @@ require 'tempfile'
5
5
  class ImportUrlJob < ActiveJob::Base
6
6
  queue_as :import_url
7
7
 
8
- def perform(file_set)
8
+ before_enqueue do |job|
9
+ log = job.arguments.last
10
+ log.pending_job(job)
11
+ end
12
+
13
+ def perform(file_set, log)
14
+ log.performing!
9
15
  user = User.find_by_user_key(file_set.depositor)
10
16
 
11
17
  Tempfile.open(file_set.id.tr('/', '_')) do |f|
@@ -18,8 +24,10 @@ class ImportUrlJob < ActiveJob::Base
18
24
  if CurationConcerns::FileSetActor.new(file_set, user).create_content(f)
19
25
  # send message to user on download success
20
26
  CurationConcerns.config.callback.run(:after_import_url_success, file_set, user)
27
+ log.success!
21
28
  else
22
29
  CurationConcerns.config.callback.run(:after_import_url_failure, file_set, user)
30
+ log.fail!(file_set.errors.full_messages.join(' '))
23
31
  end
24
32
  end
25
33
  end
@@ -2,7 +2,9 @@ module CurationConcerns
2
2
  module Ability
3
3
  extend ActiveSupport::Concern
4
4
  included do
5
- self.ability_logic += [:curation_concerns_permissions, :add_to_collection]
5
+ self.ability_logic += [:curation_concerns_permissions,
6
+ :operation_abilities,
7
+ :add_to_collection]
6
8
  end
7
9
 
8
10
  def curation_concerns_permissions
@@ -21,6 +23,10 @@ module CurationConcerns
21
23
  end
22
24
  end
23
25
 
26
+ def operation_abilities
27
+ can :read, Operation, user_id: current_user.id
28
+ end
29
+
24
30
  def admin_permissions
25
31
  alias_action :edit, to: :update
26
32
  alias_action :show, to: :read
@@ -0,0 +1,44 @@
1
+ module CurationConcerns
2
+ class Operation < ActiveRecord::Base
3
+ PENDING = 'pending'.freeze
4
+ PERFORMING = 'performing'.freeze
5
+ FAILURE = 'failure'.freeze
6
+ SUCCESS = 'success'.freeze
7
+
8
+ acts_as_nested_set
9
+ define_callbacks :success, :failure
10
+ belongs_to :user, class_name: '::User'
11
+
12
+ # If this is a batch job (has children), check to see if all the children are complete
13
+ def rollup_status
14
+ with_lock do
15
+ stats = children.pluck(:status)
16
+ return if stats.include?(PENDING) || stats.include?(PERFORMING)
17
+ return fail! if stats.include?(FAILURE)
18
+ success!
19
+ end
20
+ end
21
+
22
+ def success!
23
+ run_callbacks :success do
24
+ update(status: SUCCESS)
25
+ parent.rollup_status if parent
26
+ end
27
+ end
28
+
29
+ def fail!(message = nil)
30
+ run_callbacks :failure do
31
+ update(status: FAILURE, message: message)
32
+ parent.rollup_status if parent
33
+ end
34
+ end
35
+
36
+ def performing!
37
+ update(status: PERFORMING)
38
+ end
39
+
40
+ def pending_job(job)
41
+ update(job_class: job.class.to_s, job_id: job.job_id, status: CurationConcerns::Operation::PENDING)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,23 @@
1
+ <% provide :page_title, 'Operations' %>
2
+ <% provide :page_header do %>
3
+ <h1>Operations</h1>
4
+ <% end %>
5
+
6
+ <div class="row">
7
+ <div class="col-sm-4">
8
+ <table class="table">
9
+ <thead>
10
+ <th>Operation Type</th>
11
+ <th>Status</th>
12
+ </thead>
13
+ <tbody>
14
+ <% @operations.each do |op| %>
15
+ <tr>
16
+ <td><%= link_to op.operation_type, sufia.user_operation_path(params[:user_id], op) %></td>
17
+ <td><span class="label <%= op.status == 'failure' ? 'label-danger' : 'label-success' %>"><%= op.status %></span></td>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
21
+ </table>
22
+ </div>
23
+ </div>
@@ -0,0 +1,30 @@
1
+ <% provide :page_title, 'Operations' %>
2
+ <% provide :page_header do %>
3
+ <h1><%= @operation.operation_type %> status</h1>
4
+ <% end %>
5
+
6
+ <p><strong>Status:</strong> <span class="label <%= @operation.status == 'failure' ? 'label-danger' : 'label-success' %>"><%= @operation.status %></span></p>
7
+ <p><strong>Message:</strong> <span class="message"><%= @operation.message %></span></p>
8
+
9
+ <% if @operation.children.any? %>
10
+ <div class="row">
11
+ <div class="col-sm-4">
12
+ <table class="table">
13
+ <thead>
14
+ <th>Operation Type</th>
15
+ <th>Status</th>
16
+ <th>Message</th>
17
+ </thead>
18
+ <tbody>
19
+ <% @operation.children.each do |op| %>
20
+ <tr>
21
+ <td><%= link_to op.operation_type, sufia.user_operation_path(params[:user_id], op) %></td>
22
+ <td><span class="label <%= op.status == 'failure' ? 'label-danger' : 'label-success' %>"><%= op.status %></span></td>
23
+ <td><%= op.message %></td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
28
+ </div>
29
+ </div>
30
+ <% end %>
data/config/routes.rb CHANGED
@@ -6,4 +6,8 @@ CurationConcerns::Engine.routes.draw do
6
6
 
7
7
  # mount BrowseEverything::Engine => '/remote_files/browse'
8
8
  resources :classify_concerns, only: [:new, :create]
9
+
10
+ resources :users, only: [] do
11
+ resources :operations, only: [:index, :show]
12
+ end
9
13
  end
@@ -40,6 +40,8 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency 'deprecation', '~> 0.1'
41
41
  spec.add_dependency 'rdf', '~> 1.99'
42
42
  spec.add_dependency 'rdf-vocab', '~> 0'
43
+ spec.add_dependency 'awesome_nested_set', '~> 3.0'
44
+
43
45
 
44
46
  spec.add_development_dependency 'solr_wrapper', '~> 0.4'
45
47
  spec.add_development_dependency 'fcrepo_wrapper', '~> 0.1'
@@ -13,6 +13,7 @@ module CurationConcerns
13
13
 
14
14
  class Engine < ::Rails::Engine
15
15
  isolate_namespace CurationConcerns
16
+ require 'awesome_nested_set'
16
17
  require 'breadcrumbs_on_rails'
17
18
 
18
19
  config.autoload_paths += %W(
@@ -1,3 +1,3 @@
1
1
  module CurationConcerns
2
- VERSION = "0.13.1".freeze
2
+ VERSION = "0.14.0.pre1".freeze
3
3
  end
@@ -18,7 +18,8 @@ This generator makes the following changes to your application:
18
18
  [
19
19
  'create_version_committers.rb',
20
20
  'create_checksum_audit_logs.rb',
21
- 'create_single_use_links.rb' # ,
21
+ 'create_single_use_links.rb',
22
+ 'create_operations.rb'
22
23
  ].each do |file|
23
24
  better_migration_template file
24
25
  end
@@ -7,7 +7,7 @@ class CreateChecksumAuditLogs < ActiveRecord::Migration
7
7
  t.integer :pass
8
8
  t.string :expected_result
9
9
  t.string :actual_result
10
- t.timestamps
10
+ t.timestamps null: false
11
11
  end
12
12
  add_index :checksum_audit_logs, [:file_set_id, :file_id], name: 'by_file_set_id_and_file_id', order: { created_at: 'DESC' }
13
13
  end
@@ -0,0 +1,23 @@
1
+ class CreateOperations < ActiveRecord::Migration
2
+ def change
3
+ create_table :curation_concerns_operations do |t|
4
+ t.string :status
5
+ t.string :operation_type
6
+ t.string :job_class
7
+ t.string :job_id
8
+ t.string :type # For Single Table Inheritance
9
+ t.text :message
10
+ t.references :user, index: true, foreign_key: true
11
+
12
+ t.integer :parent_id, null: true, index: true
13
+ t.integer :lft, null: false, index: true
14
+ t.integer :rgt, null: false, index: true
15
+
16
+ # optional fields
17
+ t.integer :depth, null: false, default: 0
18
+ t.integer :children_count, null: false, default: 0
19
+
20
+ t.timestamps null: false
21
+ end
22
+ end
23
+ end
@@ -6,7 +6,7 @@ class CreateSingleUseLinks < ActiveRecord::Migration
6
6
  t.string :itemId
7
7
  t.datetime :expires
8
8
 
9
- t.timestamps
9
+ t.timestamps null: false
10
10
  end
11
11
  end
12
12
  end
@@ -5,7 +5,7 @@ class CreateVersionCommitters < ActiveRecord::Migration
5
5
  t.string :datastream_id
6
6
  t.string :version_id
7
7
  t.string :committer_login
8
- t.timestamps
8
+ t.timestamps null: false
9
9
  end
10
10
  end
11
11
 
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'cancan/matchers'
3
+
4
+ describe CurationConcerns::Ability, type: :model do
5
+ describe "a registered user" do
6
+ let(:user) { create(:user) }
7
+ subject { Ability.new(user) }
8
+ it { is_expected.to be_able_to(:read, build(:operation, user: user)) }
9
+ it { is_expected.not_to be_able_to(:read, build(:operation)) }
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::OperationsController do
4
+ routes { CurationConcerns::Engine.routes }
5
+ let(:parent) { create(:operation, :pending, user: user) }
6
+ let!(:child1) { create(:operation, :failing, parent: parent, user: user) }
7
+ let!(:child2) { create(:operation, :pending, parent: parent, user: user) }
8
+ let(:user) { create(:user) }
9
+ before do
10
+ sign_in user
11
+ end
12
+
13
+ describe "#index" do
14
+ it "is successful" do
15
+ get :index, user_id: user
16
+ expect(response).to be_successful
17
+ expect(assigns[:operations]).to eq [parent]
18
+ end
19
+ end
20
+
21
+ describe "#show" do
22
+ it "is successful" do
23
+ get :show, user_id: user, id: parent
24
+ expect(response).to be_successful
25
+ expect(assigns[:operation]).to eq parent
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ FactoryGirl.define do
2
+ factory :operation, class: CurationConcerns::Operation do
3
+ operation_type "Test batch operation"
4
+
5
+ trait :failing do
6
+ status CurationConcerns::Operation::FAILURE
7
+ end
8
+
9
+ trait :pending do
10
+ status CurationConcerns::Operation::PENDING
11
+ end
12
+
13
+ trait :successful do
14
+ status CurationConcerns::Operation::SUCCESS
15
+ end
16
+ end
17
+ end
@@ -20,6 +20,7 @@ describe ImportUrlJob do
20
20
  allow(http_res).to receive(:read_body).and_yield(File.open(File.expand_path(file_path, __FILE__)).read)
21
21
  end
22
22
  end
23
+ let(:log) { create(:operation) }
23
24
 
24
25
  context 'after running the job' do
25
26
  let(:actor) { double }
@@ -33,7 +34,8 @@ describe ImportUrlJob do
33
34
  it 'creates the content' do
34
35
  expect_any_instance_of(Net::HTTP).to receive(:request_get).with(file_hash).and_yield(mock_response)
35
36
  expect(actor).to receive(:create_content).and_return(true)
36
- described_class.perform_now(file_set)
37
+ described_class.perform_now(file_set, log)
38
+ expect(log.status).to eq 'success'
37
39
  end
38
40
  end
39
41
 
@@ -57,7 +59,7 @@ describe ImportUrlJob do
57
59
  file_set.update(title: ['File One'])
58
60
 
59
61
  # run the import job
60
- described_class.perform_now(file_set)
62
+ described_class.perform_now(file_set, log)
61
63
 
62
64
  # import job should not override the title set another process
63
65
  file = FileSet.find(file_set_id)
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::Operation do
4
+ describe "rollup_status" do
5
+ let(:parent) { create(:operation, :pending) }
6
+ describe "with a pending process" do
7
+ let!(:child1) { create(:operation, :failing, parent: parent) }
8
+ let!(:child2) { create(:operation, :pending, parent: parent) }
9
+ it "sets status to pending" do
10
+ parent.rollup_status
11
+ expect(parent.status).to eq CurationConcerns::Operation::PENDING
12
+ end
13
+ end
14
+
15
+ describe "with a failure" do
16
+ let!(:child1) { create(:operation, :failing, parent: parent) }
17
+ let!(:child2) { create(:operation, :successful, parent: parent) }
18
+ it "sets status to failure" do
19
+ parent.rollup_status
20
+ expect(parent.status).to eq CurationConcerns::Operation::FAILURE
21
+ end
22
+ end
23
+
24
+ describe "with a successes" do
25
+ let!(:child1) { create(:operation, :successful, parent: parent) }
26
+ let!(:child2) { create(:operation, :successful, parent: parent) }
27
+ it "sets status to success" do
28
+ parent.rollup_status
29
+ expect(parent.status).to eq CurationConcerns::Operation::SUCCESS
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "performing!" do
35
+ it "changes the status to performing" do
36
+ subject.performing!
37
+ expect(subject.status).to eq CurationConcerns::Operation::PERFORMING
38
+ end
39
+ end
40
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curation_concerns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.14.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-04-22 00:00:00.000000000 Z
13
+ date: 2016-04-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hydra-head
@@ -326,6 +326,20 @@ dependencies:
326
326
  - - "~>"
327
327
  - !ruby/object:Gem::Version
328
328
  version: '0'
329
+ - !ruby/object:Gem::Dependency
330
+ name: awesome_nested_set
331
+ requirement: !ruby/object:Gem::Requirement
332
+ requirements:
333
+ - - "~>"
334
+ - !ruby/object:Gem::Version
335
+ version: '3.0'
336
+ type: :runtime
337
+ prerelease: false
338
+ version_requirements: !ruby/object:Gem::Requirement
339
+ requirements:
340
+ - - "~>"
341
+ - !ruby/object:Gem::Version
342
+ version: '3.0'
329
343
  - !ruby/object:Gem::Dependency
330
344
  name: solr_wrapper
331
345
  requirement: !ruby/object:Gem::Requirement
@@ -690,6 +704,7 @@ files:
690
704
  - app/controllers/curation_concerns/application_controller.rb
691
705
  - app/controllers/curation_concerns/classify_concerns_controller.rb
692
706
  - app/controllers/curation_concerns/file_sets_controller.rb
707
+ - app/controllers/curation_concerns/operations_controller.rb
693
708
  - app/controllers/curation_concerns/permissions_controller.rb
694
709
  - app/controllers/curation_concerns/single_use_links_controller.rb
695
710
  - app/controllers/curation_concerns/single_use_links_viewer_controller.rb
@@ -756,6 +771,7 @@ files:
756
771
  - app/models/concerns/curation_concerns/with_file_sets.rb
757
772
  - app/models/concerns/curation_concerns/work_behavior.rb
758
773
  - app/models/curation_concerns/classify_concern.rb
774
+ - app/models/curation_concerns/operation.rb
759
775
  - app/models/curation_concerns/quick_classification_query.rb
760
776
  - app/models/single_use_link.rb
761
777
  - app/models/version_committer.rb
@@ -922,6 +938,8 @@ files:
922
938
  - app/views/curation_concerns/file_sets/upload/_form.html.erb
923
939
  - app/views/curation_concerns/file_sets/upload/_form_fields.html.erb
924
940
  - app/views/curation_concerns/file_sets/upload/_script_templates.html.erb
941
+ - app/views/curation_concerns/operations/index.html.erb
942
+ - app/views/curation_concerns/operations/show.html.erb
925
943
  - app/views/curation_concerns/permissions/confirm.html.erb
926
944
  - app/views/curation_concerns/single_use_links_viewer/show.html.erb
927
945
  - app/views/embargoes/_embargo_history.html.erb
@@ -998,6 +1016,7 @@ files:
998
1016
  - lib/generators/curation_concerns/templates/curation_concerns.scss
999
1017
  - lib/generators/curation_concerns/templates/curation_concerns_helper.rb
1000
1018
  - lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb
1019
+ - lib/generators/curation_concerns/templates/migrations/create_operations.rb
1001
1020
  - lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb
1002
1021
  - lib/generators/curation_concerns/templates/migrations/create_version_committers.rb
1003
1022
  - lib/generators/curation_concerns/work/USAGE
@@ -1036,6 +1055,7 @@ files:
1036
1055
  - spec/abilities/embargo_and_lease_ability_spec.rb
1037
1056
  - spec/abilities/file_set_abilities_spec.rb
1038
1057
  - spec/abilities/generic_work_abilities_spec.rb
1058
+ - spec/abilities/operation_ability_spec.rb
1039
1059
  - spec/actors/curation_concerns/add_to_collections_actor_spec.rb
1040
1060
  - spec/actors/curation_concerns/embargo_actor_spec.rb
1041
1061
  - spec/actors/curation_concerns/file_actor_spec.rb
@@ -1051,6 +1071,7 @@ files:
1051
1071
  - spec/controllers/curation_concerns/file_sets_controller_spec.rb
1052
1072
  - spec/controllers/curation_concerns/generic_works_controller_json_spec.rb
1053
1073
  - spec/controllers/curation_concerns/generic_works_controller_spec.rb
1074
+ - spec/controllers/curation_concerns/operations_controller_spec.rb
1054
1075
  - spec/controllers/curation_concerns/permissions_controller_spec.rb
1055
1076
  - spec/controllers/curation_concerns/single_use_links_controller_spec.rb
1056
1077
  - spec/controllers/curation_concerns/single_use_links_viewer_controller_spec.rb
@@ -1063,6 +1084,7 @@ files:
1063
1084
  - spec/factories/create_curation_concern.rb
1064
1085
  - spec/factories/file_sets.rb
1065
1086
  - spec/factories/generic_works.rb
1087
+ - spec/factories/operations.rb
1066
1088
  - spec/factories/users.rb
1067
1089
  - spec/features/add_file_spec.rb
1068
1090
  - spec/features/catalog_search_spec.rb
@@ -1123,6 +1145,7 @@ files:
1123
1145
  - spec/models/collection_spec.rb
1124
1146
  - spec/models/curation_concerns/collection_behavior_spec.rb
1125
1147
  - spec/models/curation_concerns/file_set/derivatives_spec.rb
1148
+ - spec/models/curation_concerns/operation_spec.rb
1126
1149
  - spec/models/curation_concerns/work_behavior_spec.rb
1127
1150
  - spec/models/file_set_spec.rb
1128
1151
  - spec/models/generic_work_spec.rb
@@ -1219,9 +1242,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
1219
1242
  version: '0'
1220
1243
  required_rubygems_version: !ruby/object:Gem::Requirement
1221
1244
  requirements:
1222
- - - ">="
1245
+ - - ">"
1223
1246
  - !ruby/object:Gem::Version
1224
- version: '0'
1247
+ version: 1.3.1
1225
1248
  requirements: []
1226
1249
  rubyforge_project:
1227
1250
  rubygems_version: 2.5.1
@@ -1234,6 +1257,7 @@ test_files:
1234
1257
  - spec/abilities/embargo_and_lease_ability_spec.rb
1235
1258
  - spec/abilities/file_set_abilities_spec.rb
1236
1259
  - spec/abilities/generic_work_abilities_spec.rb
1260
+ - spec/abilities/operation_ability_spec.rb
1237
1261
  - spec/actors/curation_concerns/add_to_collections_actor_spec.rb
1238
1262
  - spec/actors/curation_concerns/embargo_actor_spec.rb
1239
1263
  - spec/actors/curation_concerns/file_actor_spec.rb
@@ -1249,6 +1273,7 @@ test_files:
1249
1273
  - spec/controllers/curation_concerns/file_sets_controller_spec.rb
1250
1274
  - spec/controllers/curation_concerns/generic_works_controller_json_spec.rb
1251
1275
  - spec/controllers/curation_concerns/generic_works_controller_spec.rb
1276
+ - spec/controllers/curation_concerns/operations_controller_spec.rb
1252
1277
  - spec/controllers/curation_concerns/permissions_controller_spec.rb
1253
1278
  - spec/controllers/curation_concerns/single_use_links_controller_spec.rb
1254
1279
  - spec/controllers/curation_concerns/single_use_links_viewer_controller_spec.rb
@@ -1261,6 +1286,7 @@ test_files:
1261
1286
  - spec/factories/create_curation_concern.rb
1262
1287
  - spec/factories/file_sets.rb
1263
1288
  - spec/factories/generic_works.rb
1289
+ - spec/factories/operations.rb
1264
1290
  - spec/factories/users.rb
1265
1291
  - spec/features/add_file_spec.rb
1266
1292
  - spec/features/catalog_search_spec.rb
@@ -1321,6 +1347,7 @@ test_files:
1321
1347
  - spec/models/collection_spec.rb
1322
1348
  - spec/models/curation_concerns/collection_behavior_spec.rb
1323
1349
  - spec/models/curation_concerns/file_set/derivatives_spec.rb
1350
+ - spec/models/curation_concerns/operation_spec.rb
1324
1351
  - spec/models/curation_concerns/work_behavior_spec.rb
1325
1352
  - spec/models/file_set_spec.rb
1326
1353
  - spec/models/generic_work_spec.rb