worthwhile-models 0.1.0 → 0.1.1

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: 9e40a4356445e489fdd44804236d674d99cd7f29
4
- data.tar.gz: 426954c2064b078d0a811069528a96642cb4fdfb
3
+ metadata.gz: 58f35d866b0060f648dfa182e9f9ad547e1c68b9
4
+ data.tar.gz: f8aabad35e8d3e43edb296f8aea2f1e1987071b3
5
5
  SHA512:
6
- metadata.gz: dd3b23367115d00157ecd7c21b38c8dc0a279f328f4a7d1fe5bfbca99b08518c8512c43056a689b4f8a4d343d6c0db0b302e505e33298052a3b5bdc63b8f358f
7
- data.tar.gz: c36133602cc143df28212470c1c0d43588703c2cc9d3840e4525de1f05170ea9c27dc80597f147038aeef302fd2abb3ad5f1832f0c1a54c20aea7194cb63462f
6
+ metadata.gz: 41f4d8bffd869208af3c9b2164b758b6e08d055f14bdb8bf86e48cf5ae7b2663e75a9e5ee1375c2d2a4f5cda09c5940e709b3e48dbc5e0d243bdf0b5c6492bfb
7
+ data.tar.gz: 8922c9bce4a1b64bc7b10d8524b6851a2730c5b01f12de63e4c22ecc40104b98a8b4560ab042fdd6c7b7da3494369ebd99e2a81d93941b5e603c53d581dc5580
@@ -0,0 +1,79 @@
1
+ module Worthwhile
2
+ # To use this module, include it in your Actor class
3
+ # and then add its interpreters wherever you want them to run.
4
+ # They should be called _before_ apply_attributes is called because
5
+ # they intercept values in the attributes Hash.
6
+ #
7
+ # @example
8
+ # class MyActorClass < BaseActor
9
+ # include Worthwile::ManagesEmbargoesActor
10
+ #
11
+ # def create
12
+ # interpret_visibility && super && copy_visibility
13
+ # end
14
+ #
15
+ # def update
16
+ # interpret_visibility && super && copy_visibility
17
+ # end
18
+ # end
19
+ #
20
+ module ManagesEmbargoesActor
21
+ extend ActiveSupport::Concern
22
+
23
+ # Interprets embargo & lease visibility if necessary
24
+ # returns false if there are any errors
25
+ def interpret_visibility
26
+ interpret_embargo_visibility && interpret_lease_visibility
27
+ end
28
+
29
+ # If user has set visibility to embargo, interprets the relevant information and applies it
30
+ # Returns false if there are any errors and sets an error on the curation_concern
31
+ def interpret_embargo_visibility
32
+ if attributes[:visibility] != Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_EMBARGO
33
+ # clear embargo_release_date even if it isn't being used. Otherwise it sets the embargo_date
34
+ # even though they didn't select embargo on the form.
35
+ attributes.delete(:visibility_during_embargo)
36
+ attributes.delete(:visibility_after_embargo)
37
+ attributes.delete(:embargo_release_date)
38
+ true
39
+ elsif !attributes[:embargo_release_date]
40
+ curation_concern.errors.add(:visibility, 'When setting visibility to "embargo" you must also specify embargo release date.')
41
+ false
42
+ else
43
+ attributes.delete(:visibility)
44
+ curation_concern.apply_embargo(attributes[:embargo_release_date], attributes.delete(:visibility_during_embargo),
45
+ attributes.delete(:visibility_after_embargo))
46
+ @needs_to_copy_visibility = true
47
+ true
48
+ end
49
+ end
50
+
51
+ # If user has set visibility to lease, interprets the relevant information and applies it
52
+ # Returns false if there are any errors and sets an error on the curation_concern
53
+ def interpret_lease_visibility
54
+ if attributes[:visibility] != Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_LEASE
55
+ # clear lease_expiration_date even if it isn't being used. Otherwise it sets the lease_expiration
56
+ # even though they didn't select lease on the form.
57
+ attributes.delete(:visibility_during_lease)
58
+ attributes.delete(:visibility_after_lease)
59
+ attributes.delete(:lease_expiration_date)
60
+ true
61
+ elsif !attributes[:lease_expiration_date]
62
+ curation_concern.errors.add(:visibility, 'When setting visibility to "lease" you must also specify lease expiration date.')
63
+ false
64
+ else
65
+ curation_concern.apply_lease(attributes[:lease_expiration_date], attributes.delete(:visibility_during_lease),
66
+ attributes.delete(:visibility_after_lease))
67
+ @needs_to_copy_visibility = true
68
+ attributes.delete(:visibility)
69
+ true
70
+ end
71
+ end
72
+
73
+
74
+ def copy_visibility
75
+ Sufia.queue.push(VisibilityCopyWorker.new(curation_concern.id)) if @needs_to_copy_visibility
76
+ true
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,86 @@
1
+
2
+ module CurationConcern
3
+ # The CurationConcern base actor should respond to three primary actions:
4
+ # * #create
5
+ # * #update
6
+ # * #delete
7
+ class BaseActor
8
+ attr_reader :curation_concern, :user, :attributes, :cloud_resources
9
+ def initialize(curation_concern, user, input_attributes)
10
+ @curation_concern = curation_concern
11
+ @user = user
12
+ @attributes = input_attributes.dup.with_indifferent_access
13
+ @visibility = attributes[:visibility]
14
+ @cloud_resources= attributes.delete(:cloud_resources.to_s)
15
+ end
16
+
17
+ attr_reader :visibility
18
+ protected :visibility
19
+
20
+ delegate :visibility_changed?, to: :curation_concern
21
+
22
+ def create
23
+ apply_creation_data_to_curation_concern
24
+ apply_save_data_to_curation_concern
25
+ save
26
+ end
27
+
28
+ def update
29
+ apply_update_data_to_curation_concern
30
+ apply_save_data_to_curation_concern
31
+ save
32
+ end
33
+
34
+ protected
35
+ def apply_creation_data_to_curation_concern
36
+ apply_depositor_metadata
37
+ apply_deposit_date
38
+ end
39
+
40
+ def apply_update_data_to_curation_concern
41
+ true
42
+ end
43
+
44
+ def apply_depositor_metadata
45
+ curation_concern.apply_depositor_metadata(user.user_key)
46
+ curation_concern.edit_users += [user.user_key]
47
+ end
48
+
49
+ def apply_deposit_date
50
+ curation_concern.date_uploaded = Date.today
51
+ end
52
+
53
+ def save
54
+ curation_concern.save
55
+ end
56
+
57
+ def apply_save_data_to_curation_concern
58
+ attributes[:rights] = Array(attributes[:rights]) if attributes.key? :rights
59
+ remove_blank_attributes!
60
+ curation_concern.attributes = attributes
61
+ curation_concern.date_modified = Date.today
62
+ end
63
+
64
+ def attach_file(generic_file, file_to_attach)
65
+ ActiveSupport::Deprecation.warn("removing #{self.class}#attach_file, use CurationConcern.attach_file instead")
66
+ CurationConcern.attach_file(generic_file, user, file_to_attach)
67
+ end
68
+
69
+ # If any attributes are blank remove them
70
+ # e.g.:
71
+ # self.attributes = { 'title' => ['first', 'second', ''] }
72
+ # remove_blank_attributes!
73
+ # self.attributes
74
+ # => { 'title' => ['first', 'second'] }
75
+ def remove_blank_attributes!
76
+ multivalued_form_attributes.each_with_object(attributes) do |(k, v), h|
77
+ h[k] = v.select(&:present?)
78
+ end
79
+ end
80
+
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
85
+ end
86
+ end
@@ -0,0 +1,40 @@
1
+ module CurationConcern
2
+ class GenericFileActor < Sufia::GenericFile::Actor
3
+ include Worthwhile::ManagesEmbargoesActor
4
+
5
+ attr_reader :attributes, :curation_concern
6
+
7
+ def initialize(generic_file, user, attributes)
8
+ super(generic_file, user)
9
+ # we're setting attributes and curation_concern to bridge the difference
10
+ # between Sufia::GenericFile::Actor and ManagesEmbargoesActor
11
+ @curation_concern = generic_file
12
+ @attributes = attributes
13
+ end
14
+
15
+ # we can trim this down a bit when Sufia 7.1 is released (adds update_visibility)
16
+ def update_metadata(_, _)
17
+ interpret_visibility
18
+ generic_file.visibility = attributes[:visibility] if attributes.key?(:visibility)
19
+ generic_file.attributes = generic_file.sanitize_attributes(attributes)
20
+ generic_file.date_modified = DateTime.now
21
+ remove_from_feature_works if generic_file.visibility_changed? && !generic_file.public?
22
+ save_and_record_committer do
23
+ if Sufia.config.respond_to?(:after_update_metadata)
24
+ Sufia.config.after_update_metadata.call(generic_file, user)
25
+ end
26
+ end
27
+ end
28
+
29
+ def create_metadata(batch_id)
30
+ if batch_id
31
+ generic_file.visibility = load_parent(batch_id).visibility
32
+ end
33
+ super
34
+ end
35
+
36
+ def load_parent(batch_id)
37
+ @parent ||= GenericWork.find(batch_id)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,92 @@
1
+
2
+ module CurationConcern
3
+ class GenericWorkActor < CurationConcern::BaseActor
4
+ include Worthwhile::ManagesEmbargoesActor
5
+
6
+ def create
7
+ assign_pid && interpret_visibility && super && attach_files && create_linked_resources && assign_representative && copy_visibility
8
+ end
9
+
10
+ def update
11
+ add_to_collections(attributes.delete(:collection_ids)) && interpret_visibility &&
12
+ super && attach_files && create_linked_resources && copy_visibility
13
+ end
14
+
15
+ delegate :visibility_changed?, to: :curation_concern
16
+
17
+ protected
18
+
19
+ def assign_pid
20
+ curation_concern.inner_object.pid ||= Worthwhile::CurationConcern.mint_a_pid
21
+ end
22
+
23
+ def files
24
+ return @files if defined?(@files)
25
+ @files = [attributes[:files]].flatten.compact
26
+ end
27
+
28
+ def attach_files
29
+ files.all? do |file|
30
+ attach_file(file)
31
+ end
32
+ end
33
+
34
+ # The default behavior of active_fedora's has_and_belongs_to_many association,
35
+ # when assigning the id accessor (e.g. collection_ids = ['foo:1']) is to add
36
+ # to new collections, but not remove from old collections.
37
+ # This method ensures it's removed from the old collections.
38
+ def add_to_collections(new_collection_ids)
39
+ return true unless new_collection_ids
40
+ #remove from old collections
41
+ (curation_concern.collection_ids - new_collection_ids).each do |old_id|
42
+ Collection.find(old_id).members.delete(curation_concern)
43
+ end
44
+
45
+ #add to new
46
+ curation_concern.collection_ids = new_collection_ids
47
+ true
48
+ end
49
+
50
+ def linked_resource_urls
51
+ @linked_resource_urls ||= Array(attributes[:linked_resource_urls]).flatten.compact
52
+ end
53
+
54
+ def create_linked_resources
55
+ linked_resource_urls.all? do |link_resource_url|
56
+ create_linked_resource(link_resource_url)
57
+ end
58
+ end
59
+
60
+ def create_linked_resource(link_resource_url)
61
+ return true unless link_resource_url.present?
62
+ resource = Worthwhile::LinkedResource.new.tap do |link|
63
+ link.url = link_resource_url
64
+ link.batch = curation_concern
65
+ link.label = curation_concern.human_readable_type
66
+ end
67
+ Sufia::GenericFile::Actor.new(resource, user).create_metadata(curation_concern.pid)
68
+ resource.save
69
+ end
70
+
71
+ def assign_representative
72
+ curation_concern.representative = curation_concern.generic_file_ids.first
73
+ curation_concern.save
74
+ end
75
+
76
+ private
77
+ def attach_file(file)
78
+ generic_file = Worthwhile::GenericFile.new
79
+ generic_file.file = file
80
+ generic_file.batch = curation_concern
81
+ Sufia::GenericFile::Actor.new(generic_file, user).create_metadata(curation_concern.pid)
82
+ generic_file.embargo_release_date = curation_concern.embargo_release_date
83
+ generic_file.visibility = visibility
84
+ Worthwhile::CurationConcern.attach_file(generic_file, user, file)
85
+ end
86
+
87
+
88
+ def valid_file?(file_path)
89
+ return file_path.present? && File.exists?(file_path) && !File.zero?(file_path)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,4 @@
1
+ module CurationConcern
2
+ class LinkedResourceActor < CurationConcern::BaseActor
3
+ end
4
+ end
@@ -0,0 +1,17 @@
1
+ module CurationConcern
2
+ module VersionedContent
3
+ def versions
4
+ return [] unless persisted?
5
+ @versions ||= content.versions.collect {|version| Worthwhile::ContentVersion.new(content, version)}
6
+ end
7
+
8
+ def latest_version
9
+ versions.first || Worthwhile::ContentVersion::Null.new(content)
10
+ end
11
+
12
+ def current_version_id
13
+ latest_version.version_id
14
+ end
15
+ end
16
+ end
17
+
@@ -12,7 +12,7 @@ module Worthwhile
12
12
  include Sufia::GenericFile::Metadata
13
13
  include Sufia::GenericFile::Versions
14
14
  include Sufia::Permissions::Readable
15
- include Worthwhile::GenericFile::VersionedContent
15
+ include CurationConcern::VersionedContent
16
16
 
17
17
  included do
18
18
  belongs_to :batch, property: :is_part_of, class_name: 'ActiveFedora::Base'
@@ -2,9 +2,9 @@ require 'sufia/models'
2
2
  module Worthwhile
3
3
  module Models
4
4
  class Engine < ::Rails::Engine
5
- # config.autoload_paths += %W(
6
- # #{config.root}/app/models/datastreams
7
- # )
5
+ config.autoload_paths += %W(
6
+ #{config.root}/app/actors/concerns
7
+ )
8
8
  end
9
9
  end
10
10
  end
@@ -1,5 +1,5 @@
1
1
  module Worthwhile
2
2
  module Models
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worthwhile-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-08 00:00:00.000000000 Z
11
+ date: 2014-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hydra-head
@@ -102,17 +102,22 @@ executables: []
102
102
  extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
+ - app/actors/concerns/worthwhile/manages_embargoes_actor.rb
106
+ - app/actors/curation_concern/base_actor.rb
107
+ - app/actors/curation_concern/generic_file_actor.rb
108
+ - app/actors/curation_concern/generic_work_actor.rb
109
+ - app/actors/curation_concern/linked_resource_actor.rb
105
110
  - app/models/concerns/curation_concern/collection_model.rb
106
111
  - app/models/concerns/curation_concern/curatable.rb
107
112
  - app/models/concerns/curation_concern/has_representative.rb
108
113
  - app/models/concerns/curation_concern/human_readable_type.rb
114
+ - app/models/concerns/curation_concern/versioned_content.rb
109
115
  - app/models/concerns/curation_concern/with_basic_metadata.rb
110
116
  - app/models/concerns/curation_concern/with_editors.rb
111
117
  - app/models/concerns/curation_concern/with_generic_files.rb
112
118
  - app/models/concerns/curation_concern/with_linked_resources.rb
113
119
  - app/models/concerns/curation_concern/work.rb
114
120
  - app/models/concerns/worthwhile/ability.rb
115
- - app/models/concerns/worthwhile/generic_file/versioned_content.rb
116
121
  - app/models/concerns/worthwhile/generic_file_base.rb
117
122
  - app/models/concerns/worthwhile/solr_document_behavior.rb
118
123
  - app/models/generic_work.rb
@@ -1,18 +0,0 @@
1
- module Worthwhile
2
- class GenericFile
3
- module VersionedContent
4
- def versions
5
- return [] unless persisted?
6
- @versions ||= content.versions.collect {|version| Worthwhile::ContentVersion.new(content, version)}
7
- end
8
-
9
- def latest_version
10
- versions.first || Worthwhile::ContentVersion::Null.new(content)
11
- end
12
-
13
- def current_version_id
14
- latest_version.version_id
15
- end
16
- end
17
- end
18
- end