curation_concerns-models 0.1.0 → 0.2.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 +4 -4
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +11 -19
- data/app/actors/curation_concerns/base_actor.rb +41 -45
- data/app/actors/curation_concerns/embargo_actor.rb +19 -0
- data/app/actors/curation_concerns/file_set_actor.rb +200 -0
- data/app/actors/curation_concerns/lease_actor.rb +19 -0
- data/app/actors/curation_concerns/work_actor_behavior.rb +55 -58
- data/app/indexers/curation_concerns/collection_indexer.rb +10 -0
- data/app/indexers/curation_concerns/file_set_indexing_service.rb +24 -0
- data/app/{services/curation_concerns/generic_work_indexing_service.rb → indexers/curation_concerns/work_indexing_service.rb} +6 -6
- data/app/jobs/active_fedora_id_based_job.rb +5 -12
- data/app/jobs/audit_job.rb +11 -17
- data/app/jobs/characterize_job.rb +8 -7
- data/app/jobs/create_derivatives_job.rb +8 -11
- data/app/jobs/import_url_job.rb +12 -25
- data/app/jobs/ingest_file_job.rb +16 -0
- data/app/jobs/ingest_local_file_job.rb +14 -35
- data/app/jobs/resolrize_job.rb +3 -5
- data/app/jobs/upload_set_update_job.rb +68 -0
- data/app/models/checksum_audit_log.rb +2 -3
- data/app/models/concerns/curation_concerns/ability.rb +18 -10
- data/app/models/concerns/curation_concerns/basic_metadata.rb +1 -3
- data/app/models/concerns/curation_concerns/collection_behavior.rb +13 -14
- data/app/models/concerns/curation_concerns/file_set/belongs_to_upload_sets.rb +15 -0
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/belongs_to_works.rb +8 -14
- data/app/models/concerns/curation_concerns/file_set/derivatives.rb +54 -0
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/full_text_indexing.rb +1 -2
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/indexing.rb +2 -2
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/versions.rb +2 -3
- data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
- data/app/models/concerns/curation_concerns/generic_file.rb +1 -1
- data/app/models/concerns/curation_concerns/has_representative.rb +6 -7
- data/app/models/concerns/curation_concerns/human_readable_type.rb +5 -7
- data/app/models/concerns/curation_concerns/permissions.rb +2 -2
- data/app/models/concerns/curation_concerns/permissions/readable.rb +0 -1
- data/app/models/concerns/curation_concerns/permissions/writable.rb +10 -51
- data/app/models/concerns/curation_concerns/serializers.rb +3 -5
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +37 -40
- data/app/models/concerns/curation_concerns/upload_set_behavior.rb +38 -0
- data/app/models/concerns/curation_concerns/user.rb +4 -51
- data/app/models/concerns/curation_concerns/with_file_sets.rb +28 -0
- data/app/models/concerns/curation_concerns/{generic_work_behavior.rb → work_behavior.rb} +12 -6
- data/app/models/curation_concerns/classify_concern.rb +7 -7
- data/app/models/curation_concerns/quick_classification_query.rb +6 -7
- data/app/models/single_use_link.rb +34 -0
- data/app/models/upload_set.rb +3 -0
- data/app/services/curation_concerns/derivative_path.rb +32 -0
- data/app/services/curation_concerns/{generic_file_audit_service.rb → file_set_audit_service.rb} +17 -18
- data/app/services/curation_concerns/indexes_thumbnails.rb +14 -0
- data/app/services/curation_concerns/local_file_service.rb +10 -0
- data/app/services/curation_concerns/lock_manager.rb +40 -0
- data/app/services/curation_concerns/noid.rb +1 -1
- data/app/services/curation_concerns/persist_derivatives.rb +33 -0
- data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
- data/app/services/curation_concerns/repository_audit_service.rb +1 -3
- data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
- data/app/services/curation_concerns/time_service.rb +7 -0
- data/app/services/curation_concerns/versioning_service.rb +11 -12
- data/curation_concerns-models.gemspec +6 -6
- data/lib/curation_concerns/configuration.rb +154 -0
- data/lib/curation_concerns/messages.rb +26 -26
- data/lib/curation_concerns/models.rb +5 -14
- data/lib/curation_concerns/models/engine.rb +0 -30
- data/lib/curation_concerns/models/utils.rb +4 -4
- data/lib/curation_concerns/models/version.rb +1 -1
- data/lib/generators/curation_concerns/models/abstract_migration_generator.rb +8 -7
- data/lib/generators/curation_concerns/models/clamav_generator.rb +3 -3
- data/lib/generators/curation_concerns/models/install_generator.rb +13 -20
- data/lib/generators/curation_concerns/models/templates/app/models/file_set.rb +4 -0
- data/lib/generators/curation_concerns/models/templates/config/clamav.rb +1 -1
- data/lib/generators/curation_concerns/models/templates/config/curation_concerns.rb +52 -65
- data/lib/generators/curation_concerns/models/templates/config/redis_config.rb +13 -17
- data/lib/generators/curation_concerns/models/templates/config/resque_config.rb +2 -1
- data/lib/generators/curation_concerns/models/templates/migrations/create_checksum_audit_logs.rb +3 -3
- data/lib/generators/curation_concerns/models/templates/migrations/create_single_use_links.rb +12 -0
- data/lib/tasks/curation_concerns-models_tasks.rake +4 -62
- data/lib/tasks/migrate.rake +1 -1
- data/lib/tasks/resque.rake +1 -0
- data/lib/tasks/solr_reindex.rake +1 -1
- metadata +59 -52
- data/app/actors/curation_concerns/generic_file_actor.rb +0 -150
- data/app/jobs/active_fedora_pid_based_job.rb +0 -6
- data/app/jobs/copy_permissions_job.rb +0 -24
- data/app/models/concerns/curation_concerns/generic_file/characterization.rb +0 -89
- data/app/models/concerns/curation_concerns/generic_file/content.rb +0 -8
- data/app/models/concerns/curation_concerns/generic_file/export.rb +0 -343
- data/app/models/concerns/curation_concerns/generic_file_behavior.rb +0 -44
- data/app/models/concerns/curation_concerns/with_basic_metadata.rb +0 -98
- data/app/models/concerns/curation_concerns/with_generic_files.rb +0 -29
- data/app/models/datastreams/fits_datastream.rb +0 -148
- data/app/services/curation_concerns/characterization_service.rb +0 -71
- data/app/services/curation_concerns/full_text_extraction_service.rb +0 -38
- data/app/services/curation_concerns/generic_file_indexing_service.rb +0 -14
- data/lib/curation_concerns/models/resque.rb +0 -36
- data/lib/generators/curation_concerns/models/fulltext_generator.rb +0 -28
- data/lib/generators/curation_concerns/models/templates/app/models/generic_file.rb +0 -4
- data/lib/generators/curation_concerns/models/templates/config/resque_admin.rb +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b866be7465155c67d0157b20159c75f53cc6d2c
|
|
4
|
+
data.tar.gz: def664a51f3bff81f3ca2396787883ae6b3142cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 399bdc3d1ea0bb4722605fa486662e1e33b4c01872f0fe3fe47d7edd36583c0a744a4bfa0198f39e288f4943c69ac00ec712e5ca985cfde379770c510c052516
|
|
7
|
+
data.tar.gz: 1bc3ca8a712bb6d141d4c8411c959db37c66931b86b0c1e3a7a969d42d41402ffb59397ab7d5da1e1c4eec84228a09c50fd9dce5932d37344368193f5a03ea86
|
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Models extracted from worthwhile-models and sufia-models.
|
|
|
4
4
|
|
|
5
5
|
## Dependencies
|
|
6
6
|
|
|
7
|
+
Checkout the readme for [hydra-derivatives](https://github.com/projecthydra/hydra-derivatives#dependencies) for additional dependencies for generating derivatives.
|
|
8
|
+
|
|
7
9
|
### FITS 0.6.2
|
|
8
10
|
|
|
9
11
|
To install FITS:
|
data/Rakefile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
@@ -9,11 +9,11 @@ module CurationConcerns
|
|
|
9
9
|
# include Worthwile::ManagesEmbargoesActor
|
|
10
10
|
#
|
|
11
11
|
# def create
|
|
12
|
-
# interpret_visibility && super
|
|
12
|
+
# interpret_visibility && super
|
|
13
13
|
# end
|
|
14
14
|
#
|
|
15
15
|
# def update
|
|
16
|
-
# interpret_visibility && super
|
|
16
|
+
# interpret_visibility && super
|
|
17
17
|
# end
|
|
18
18
|
# end
|
|
19
19
|
#
|
|
@@ -22,17 +22,17 @@ module CurationConcerns
|
|
|
22
22
|
|
|
23
23
|
# Interprets embargo & lease visibility if necessary
|
|
24
24
|
# returns false if there are any errors
|
|
25
|
-
def interpret_visibility(attributes=self.attributes)
|
|
25
|
+
def interpret_visibility(attributes = self.attributes)
|
|
26
26
|
should_continue = interpret_embargo_visibility(attributes) && interpret_lease_visibility(attributes)
|
|
27
27
|
if attributes[:visibility]
|
|
28
28
|
curation_concern.visibility = attributes[:visibility]
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
should_continue
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# If user has set visibility to embargo, interprets the relevant information and applies it
|
|
34
34
|
# Returns false if there are any errors and sets an error on the curation_concern
|
|
35
|
-
def interpret_embargo_visibility(attributes=self.attributes)
|
|
35
|
+
def interpret_embargo_visibility(attributes = self.attributes)
|
|
36
36
|
if attributes[:visibility] == Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_EMBARGO
|
|
37
37
|
if !attributes[:embargo_release_date]
|
|
38
38
|
curation_concern.errors.add(:visibility, 'When setting visibility to "embargo" you must also specify embargo release date.')
|
|
@@ -42,9 +42,8 @@ module CurationConcerns
|
|
|
42
42
|
curation_concern.apply_embargo(attributes[:embargo_release_date], attributes.delete(:visibility_during_embargo),
|
|
43
43
|
attributes.delete(:visibility_after_embargo))
|
|
44
44
|
if curation_concern.embargo
|
|
45
|
-
curation_concern.embargo.save
|
|
45
|
+
curation_concern.embargo.save # See https://github.com/projecthydra/hydra-head/issues/226
|
|
46
46
|
end
|
|
47
|
-
@needs_to_copy_visibility = true
|
|
48
47
|
should_continue = true
|
|
49
48
|
end
|
|
50
49
|
else
|
|
@@ -57,23 +56,22 @@ module CurationConcerns
|
|
|
57
56
|
attributes.delete(:visibility_during_embargo)
|
|
58
57
|
attributes.delete(:visibility_after_embargo)
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
should_continue
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
# If user has set visibility to lease, interprets the relevant information and applies it
|
|
64
63
|
# Returns false if there are any errors and sets an error on the curation_concern
|
|
65
|
-
def interpret_lease_visibility(attributes=self.attributes)
|
|
64
|
+
def interpret_lease_visibility(attributes = self.attributes)
|
|
66
65
|
if attributes[:visibility] == Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_LEASE
|
|
67
66
|
if !attributes[:lease_expiration_date]
|
|
68
67
|
curation_concern.errors.add(:visibility, 'When setting visibility to "lease" you must also specify lease expiration date.')
|
|
69
68
|
should_continue = false
|
|
70
69
|
else
|
|
71
70
|
curation_concern.apply_lease(attributes[:lease_expiration_date], attributes.delete(:visibility_during_lease),
|
|
72
|
-
|
|
71
|
+
attributes.delete(:visibility_after_lease))
|
|
73
72
|
if curation_concern.lease
|
|
74
|
-
curation_concern.lease.save
|
|
73
|
+
curation_concern.lease.save # See https://github.com/projecthydra/hydra-head/issues/226
|
|
75
74
|
end
|
|
76
|
-
@needs_to_copy_visibility = true
|
|
77
75
|
attributes.delete(:visibility)
|
|
78
76
|
should_continue = true
|
|
79
77
|
end
|
|
@@ -87,13 +85,7 @@ module CurationConcerns
|
|
|
87
85
|
attributes.delete(:visibility_during_lease)
|
|
88
86
|
attributes.delete(:visibility_after_lease)
|
|
89
87
|
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def copy_visibility
|
|
95
|
-
CurationConcerns.queue.push(VisibilityCopyWorker.new(curation_concern.id)) if @needs_to_copy_visibility
|
|
96
|
-
true
|
|
88
|
+
should_continue
|
|
97
89
|
end
|
|
98
90
|
end
|
|
99
91
|
end
|
|
@@ -11,7 +11,7 @@ module CurationConcerns
|
|
|
11
11
|
@user = user
|
|
12
12
|
@attributes = input_attributes.dup.with_indifferent_access
|
|
13
13
|
@visibility = attributes[:visibility]
|
|
14
|
-
@cloud_resources= attributes.delete(:cloud_resources.to_s)
|
|
14
|
+
@cloud_resources = attributes.delete(:cloud_resources.to_s)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
attr_reader :visibility
|
|
@@ -32,59 +32,55 @@ module CurationConcerns
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
protected
|
|
35
|
-
def apply_creation_data_to_curation_concern
|
|
36
|
-
apply_depositor_metadata
|
|
37
|
-
apply_deposit_date
|
|
38
|
-
end
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
def apply_creation_data_to_curation_concern
|
|
37
|
+
apply_depositor_metadata
|
|
38
|
+
apply_deposit_date
|
|
39
|
+
end
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
41
|
+
def apply_update_data_to_curation_concern
|
|
42
|
+
true
|
|
43
|
+
end
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
def apply_depositor_metadata
|
|
46
|
+
curation_concern.apply_depositor_metadata(user.user_key)
|
|
47
|
+
curation_concern.edit_users += [user.user_key]
|
|
48
|
+
end
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
def apply_deposit_date
|
|
51
|
+
curation_concern.date_uploaded = CurationConcerns::TimeService.time_in_utc
|
|
52
|
+
end
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
curation_concern.attributes = attributes.symbolize_keys
|
|
61
|
-
curation_concern.date_modified = Date.today
|
|
62
|
-
end
|
|
54
|
+
def save
|
|
55
|
+
curation_concern.save
|
|
56
|
+
end
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
def apply_save_data_to_curation_concern
|
|
59
|
+
attributes[:rights] = Array(attributes[:rights]) if attributes.key? :rights
|
|
60
|
+
remove_blank_attributes!
|
|
61
|
+
curation_concern.attributes = attributes.symbolize_keys
|
|
62
|
+
curation_concern.date_modified = CurationConcerns::TimeService.time_in_utc
|
|
63
|
+
end
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
65
|
+
# If any attributes are blank remove them
|
|
66
|
+
# e.g.:
|
|
67
|
+
# self.attributes = { 'title' => ['first', 'second', ''] }
|
|
68
|
+
# remove_blank_attributes!
|
|
69
|
+
# self.attributes
|
|
70
|
+
# => { 'title' => ['first', 'second'] }
|
|
71
|
+
def remove_blank_attributes!
|
|
72
|
+
multivalued_form_attributes.each_with_object(attributes) do |(k, v), h|
|
|
73
|
+
if v.instance_of? Array
|
|
74
|
+
h[k] = v.select(&:present?)
|
|
75
|
+
else
|
|
76
|
+
h[k] = v
|
|
77
|
+
end
|
|
81
78
|
end
|
|
82
79
|
end
|
|
83
|
-
end
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
# Return the hash of attributes that are multivalued and not uploaded files
|
|
82
|
+
def multivalued_form_attributes
|
|
83
|
+
attributes.select { |_, v| v.respond_to?(:select) && !v.respond_to?(:read) }
|
|
84
|
+
end
|
|
89
85
|
end
|
|
90
86
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CurationConcerns
|
|
2
|
+
class EmbargoActor
|
|
3
|
+
attr_reader :work
|
|
4
|
+
|
|
5
|
+
# @param [Hydra::Works::Work] work
|
|
6
|
+
def initialize(work)
|
|
7
|
+
@work = work
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Update the visibility of the work to match the correct state of the embargo, then clear the embargo date, etc.
|
|
11
|
+
# Saves the embargo and the work
|
|
12
|
+
def destroy
|
|
13
|
+
work.embargo_visibility! # If the embargo has lapsed, update the current visibility.
|
|
14
|
+
work.deactivate_embargo!
|
|
15
|
+
work.embargo.save!
|
|
16
|
+
work.save!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
module CurationConcerns
|
|
2
|
+
# Actions are decoupled from controller logic so that they may be called from a controller or a background job.
|
|
3
|
+
class FileSetActor
|
|
4
|
+
include CurationConcerns::ManagesEmbargoesActor
|
|
5
|
+
|
|
6
|
+
attr_reader :file_set, :user, :attributes, :curation_concern
|
|
7
|
+
|
|
8
|
+
def initialize(file_set, user)
|
|
9
|
+
# we're setting attributes and curation_concern to bridge the difference
|
|
10
|
+
# between CurationConcerns::FileSetActor and ManagesEmbargoesActor
|
|
11
|
+
@curation_concern = file_set
|
|
12
|
+
@file_set = file_set
|
|
13
|
+
@user = user
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Adds the appropriate metadata, visibility and relationships to file_set
|
|
17
|
+
#
|
|
18
|
+
# *Note*: In past versions of Sufia this method did not perform a save because it is mainly used in conjunction with
|
|
19
|
+
# create_content, which also performs a save. However, due to the relationship between Hydra::PCDM objects,
|
|
20
|
+
# we have to save both the parent work and the file_set in order to record the "metadata" relationship
|
|
21
|
+
# between them.
|
|
22
|
+
# @param [String] upload_set_id id of the batch of files that the file was uploaded with
|
|
23
|
+
# @param [ActiveFedora::Base] work the parent work that will contain the file_set.
|
|
24
|
+
# @param [Hash] file_set specifying the visibility, lease and/or embargo of the file set. If you don't provide at least one of visibility, embargo_release_date or lease_expiration_date, visibility will be copied from the parent.
|
|
25
|
+
|
|
26
|
+
def create_metadata(upload_set_id, work, file_set_params = {})
|
|
27
|
+
file_set.apply_depositor_metadata(user)
|
|
28
|
+
now = CurationConcerns::TimeService.time_in_utc
|
|
29
|
+
file_set.date_uploaded = now
|
|
30
|
+
file_set.date_modified = now
|
|
31
|
+
file_set.creator = [user.user_key]
|
|
32
|
+
|
|
33
|
+
if upload_set_id && file_set.respond_to?(:upload_set_id=)
|
|
34
|
+
UploadSet.create(id: upload_set_id) unless UploadSet.exists?(upload_set_id)
|
|
35
|
+
file_set.upload_set_id = upload_set_id
|
|
36
|
+
else
|
|
37
|
+
ActiveFedora::Base.logger.warn 'unable to find UploadSet to attach to'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if assign_visibility?(file_set_params)
|
|
41
|
+
interpret_visibility file_set_params
|
|
42
|
+
end
|
|
43
|
+
# TODO: Why do we need to check if work is nil? Shoudn't that raise an error?
|
|
44
|
+
attach_file_to_work(work, file_set, file_set_params) if work
|
|
45
|
+
yield(file_set) if block_given?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Puts the uploaded content into a staging directory. Then kicks off a
|
|
49
|
+
# job to characterize and create derivatives with this on disk variant.
|
|
50
|
+
# Simultaneously moving a preservation copy to the repostiory.
|
|
51
|
+
# TODO: create a job to monitor this directory and prune old files that
|
|
52
|
+
# have made it to the repo
|
|
53
|
+
# @param [ActionDigest::HTTP::UploadedFile, Tempfile] file the file uploaded by the user.
|
|
54
|
+
def create_content(file)
|
|
55
|
+
file_set.label ||= file.original_filename
|
|
56
|
+
file_set.title = [file_set.label] if file_set.title.blank?
|
|
57
|
+
return false unless file_set.save
|
|
58
|
+
|
|
59
|
+
working_file = copy_file_to_working_directory(file, file_set.id)
|
|
60
|
+
IngestFileJob.perform_later(file_set.id, working_file, file.content_type, user.user_key)
|
|
61
|
+
make_derivative(file_set.id, working_file)
|
|
62
|
+
true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def revert_content(revision_id)
|
|
66
|
+
file_set.original_file.restore_version(revision_id)
|
|
67
|
+
|
|
68
|
+
return false unless file_set.save
|
|
69
|
+
|
|
70
|
+
CurationConcerns::VersioningService.create(file_set.original_file, user)
|
|
71
|
+
|
|
72
|
+
# Retrieve a copy of the orginal file from the repository
|
|
73
|
+
working_file = copy_repository_resource_to_working_directory(file_set)
|
|
74
|
+
make_derivative(file_set.id, working_file)
|
|
75
|
+
|
|
76
|
+
CurationConcerns.config.callback.run(:after_revert_content, file_set, user, revision_id)
|
|
77
|
+
true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def update_content(file)
|
|
81
|
+
working_file = copy_file_to_working_directory(file, file_set.id)
|
|
82
|
+
IngestFileJob.perform_later(file_set.id, working_file, file.content_type, user.user_key)
|
|
83
|
+
make_derivative(file_set.id, working_file)
|
|
84
|
+
CurationConcerns.config.callback.run(:after_update_content, file_set, user)
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def update_metadata(attributes)
|
|
89
|
+
update_visibility(attributes)
|
|
90
|
+
# attributes.delete(:visibility) # Applying this attribute is handled by update_visibility
|
|
91
|
+
file_set.attributes = attributes
|
|
92
|
+
file_set.date_modified = CurationConcerns::TimeService.time_in_utc
|
|
93
|
+
save do
|
|
94
|
+
CurationConcerns.config.callback.run(:after_update_metadata, file_set, user)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def destroy
|
|
99
|
+
file_set.destroy
|
|
100
|
+
# TODO: need to mend the linked list of proxies (possibly wrap with a lock)
|
|
101
|
+
CurationConcerns.config.callback.run(:after_destroy, file_set.id, user)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
def make_derivative(file_set_id, working_file)
|
|
107
|
+
CharacterizeJob.perform_later(file_set_id, working_file)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @param [ActionDispatch::Http::UploadedFile] file
|
|
111
|
+
# @param [String] id the identifer
|
|
112
|
+
# @return [String] path of the working file
|
|
113
|
+
def copy_file_to_working_directory(file, id)
|
|
114
|
+
copy_stream_to_working_directory(id, file.original_filename, file)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @param [FileSet] file_set the resource
|
|
118
|
+
# @return [String] path of the working file
|
|
119
|
+
def copy_repository_resource_to_working_directory(file_set)
|
|
120
|
+
file = file_set.original_file
|
|
121
|
+
copy_stream_to_working_directory(file_set.id, file.original_name, StringIO.new(file.content))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @param [String] id the identifer
|
|
125
|
+
# @param [String] name the file name
|
|
126
|
+
# @param [#read] stream the stream to copy to the working directory
|
|
127
|
+
# @return [String] path of the working file
|
|
128
|
+
def copy_stream_to_working_directory(id, name, stream)
|
|
129
|
+
working_path = full_filename(id, name)
|
|
130
|
+
FileUtils.mkdir_p(File.dirname(working_path))
|
|
131
|
+
IO.copy_stream(stream, working_path)
|
|
132
|
+
working_path
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def full_filename(id, original_name)
|
|
136
|
+
pair = id.scan(/..?/).first(4)
|
|
137
|
+
File.join(CurationConcerns.config.working_path, *pair, original_name)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Takes an optional block and executes the block if the save was successful.
|
|
141
|
+
# returns false if the save was unsuccessful
|
|
142
|
+
def save
|
|
143
|
+
save_tries = 0
|
|
144
|
+
begin
|
|
145
|
+
return false unless file_set.save
|
|
146
|
+
rescue RSolr::Error::Http => error
|
|
147
|
+
ActiveFedora::Base.logger.warn "CurationConcerns::FileSetActor#save Caught RSOLR error #{error.inspect}"
|
|
148
|
+
save_tries += 1
|
|
149
|
+
# fail for good if the tries is greater than 3
|
|
150
|
+
raise error if save_tries >= 3
|
|
151
|
+
sleep 0.01
|
|
152
|
+
retry
|
|
153
|
+
end
|
|
154
|
+
yield if block_given?
|
|
155
|
+
true
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Adds a FileSet to the work using ore:Aggregations.
|
|
159
|
+
# Locks to ensure that only one process is operating on
|
|
160
|
+
# the list at a time.
|
|
161
|
+
def attach_file_to_work(work, file_set, file_set_params)
|
|
162
|
+
acquire_lock_for(work.id) do
|
|
163
|
+
# Ensure we have an up-to-date copy of the members association, so
|
|
164
|
+
# that we append to the end of the list.
|
|
165
|
+
work.reload unless work.new_record?
|
|
166
|
+
unless assign_visibility?(file_set_params)
|
|
167
|
+
copy_visibility(work, file_set)
|
|
168
|
+
end
|
|
169
|
+
work.ordered_members << file_set
|
|
170
|
+
# Save the work so the association between the work and the file_set is persisted (head_id)
|
|
171
|
+
work.save
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def acquire_lock_for(lock_key, &block)
|
|
176
|
+
lock_manager.lock(lock_key, &block)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def lock_manager
|
|
180
|
+
@lock_manager ||= CurationConcerns::LockManager.new(
|
|
181
|
+
CurationConcerns.config.lock_time_to_live,
|
|
182
|
+
CurationConcerns.config.lock_retry_count,
|
|
183
|
+
CurationConcerns.config.lock_retry_delay)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def assign_visibility?(file_set_params = {})
|
|
187
|
+
!((file_set_params || {}).keys & %w(visibility embargo_release_date lease_expiration_date)).empty?
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# This method can be overridden in case there is a custom approach for visibility (e.g. embargo)
|
|
191
|
+
def update_visibility(attributes)
|
|
192
|
+
interpret_visibility(attributes) # relies on CurationConcerns::ManagesEmbargoesActor to interpret and apply visibility
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# copy visibility from source_concern to destination_concern
|
|
196
|
+
def copy_visibility(source_concern, destination_concern)
|
|
197
|
+
destination_concern.visibility = source_concern.visibility
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CurationConcerns
|
|
2
|
+
class LeaseActor
|
|
3
|
+
attr_reader :work
|
|
4
|
+
|
|
5
|
+
# @param [Hydra::Works::Work] work
|
|
6
|
+
def initialize(work)
|
|
7
|
+
@work = work
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Update the visibility of the work to match the correct state of the lease, then clear the lease date, etc.
|
|
11
|
+
# Saves the lease and the work
|
|
12
|
+
def destroy
|
|
13
|
+
work.lease_visibility! # If the lease has lapsed, update the current visibility.
|
|
14
|
+
work.deactivate_lease!
|
|
15
|
+
work.lease.save!
|
|
16
|
+
work.save!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|