sufia-models 4.0.0.rc1 → 4.0.0.rc2

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/actors/sufia/generic_file/actor.rb +14 -5
  3. data/{lib/sufia/models → app}/jobs/active_fedora_pid_based_job.rb +0 -0
  4. data/{lib/sufia/models → app}/jobs/audit_job.rb +4 -10
  5. data/{lib/sufia/models → app}/jobs/batch_update_job.rb +22 -18
  6. data/{lib/sufia/models → app}/jobs/characterize_job.rb +0 -0
  7. data/{lib/sufia/models → app}/jobs/create_derivatives_job.rb +0 -0
  8. data/{lib/sufia/models → app}/jobs/import_url_job.rb +0 -0
  9. data/{lib/sufia/models → app}/jobs/resolrize_job.rb +0 -0
  10. data/app/models/collection.rb +1 -39
  11. data/{lib → app/models/concerns}/sufia/ability.rb +0 -0
  12. data/app/models/concerns/sufia/collection.rb +55 -0
  13. data/app/models/concerns/sufia/generic_file.rb +5 -11
  14. data/app/models/concerns/sufia/generic_file/audit.rb +1 -2
  15. data/app/models/concerns/sufia/generic_file/characterization.rb +4 -2
  16. data/app/models/concerns/sufia/generic_file/full_text_indexing.rb +27 -0
  17. data/app/models/concerns/sufia/generic_file/mime_types.rb +1 -0
  18. data/app/models/concerns/sufia/generic_file/permissions.rb +2 -49
  19. data/{lib/sufia/models → app/models/concerns/sufia}/model_methods.rb +0 -0
  20. data/app/models/concerns/sufia/user.rb +8 -1
  21. data/app/models/sufia/avatar_uploader.rb +2 -3
  22. data/app/services/sufia/noid.rb +9 -0
  23. data/config/locales/sufia.en.yml +1 -0
  24. data/lib/generators/sufia/models/fulltext_generator.rb +27 -0
  25. data/lib/generators/sufia/models/install_generator.rb +7 -0
  26. data/lib/generators/sufia/models/templates/config/analytics.yml +5 -5
  27. data/lib/generators/sufia/models/templates/config/solrconfig.xml +177 -0
  28. data/lib/generators/sufia/models/templates/config/sufia.rb +3 -1
  29. data/lib/generators/sufia/models/upgrade400_generator.rb +7 -0
  30. data/lib/sufia/messages.rb +67 -0
  31. data/lib/sufia/models.rb +2 -0
  32. data/lib/sufia/models/active_fedora/redis.rb +0 -6
  33. data/lib/sufia/models/engine.rb +1 -3
  34. data/lib/sufia/models/resque.rb +1 -1
  35. data/lib/sufia/models/version.rb +1 -1
  36. data/lib/sufia/permissions.rb +9 -0
  37. data/lib/sufia/permissions/readable.rb +20 -0
  38. data/lib/sufia/permissions/writable.rb +56 -0
  39. data/lib/tasks/sufia-models_tasks.rake +58 -2
  40. data/sufia-models.gemspec +11 -11
  41. metadata +45 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee13e1774ba0de53ce7735b6bb93176a2e27e882
4
- data.tar.gz: 0760211d652447c4c47680af22c5cb29afb215c0
3
+ metadata.gz: 82546f98afb1a657c9bfba8eafcaad863373a979
4
+ data.tar.gz: 15a4dd50704723c213b51cf82b1de921609826a7
5
5
  SHA512:
6
- metadata.gz: dca80059d96ab1b9f09c53af4e76374fc0d8644ba44f1faf4fcc2d94365e75e49e1321dd2542390a1ee14459f098c8e64b16caf30bc1c104194c6a7562ac4b23
7
- data.tar.gz: da74a7e90d7d9cd3f6a3da5bb67e7e2c0288b366322cb6d1431d0089b43845346188313c3cdca0bcbcf89bfdc22d654006a7133f273c08aab9e442c683b2fcca
6
+ metadata.gz: 52bf6d0263f5cfbabb55ad19eb8c847f77e2a2b313cd07a9147622348940af4d6b926b0a789a052b6f48c8f84a34ca0f3d99aee6fd9d4eadc68585171b760d8b
7
+ data.tar.gz: b34150a1691b2cd26c1a6b206e635105bb96b9676973ed898cc9dbc08220fad281c9f42c8b0e812cceb3fa832e719944407c199e245152b0e8bf9efc7f323a91
@@ -17,12 +17,12 @@ module Sufia::GenericFile
17
17
  generic_file.apply_depositor_metadata(user)
18
18
  generic_file.date_uploaded = Date.today
19
19
  generic_file.date_modified = Date.today
20
- generic_file.creator = user.name
20
+ generic_file.creator = [user.name]
21
21
 
22
22
  if batch_id
23
- generic_file.add_relationship("isPartOf", "info:fedora/#{Sufia::Noid.namespaceize(batch_id)}")
23
+ generic_file.batch_id = Sufia::Noid.namespaceize(batch_id)
24
24
  else
25
- logger.warn "unable to find batch to attach to"
25
+ ActiveFedora::Base.logger.warn "unable to find batch to attach to"
26
26
  end
27
27
  yield(generic_file) if block_given?
28
28
  end
@@ -59,6 +59,7 @@ module Sufia::GenericFile
59
59
  generic_file.attributes = generic_file.sanitize_attributes(attributes)
60
60
  generic_file.visibility = visibility
61
61
  generic_file.date_modified = DateTime.now
62
+ remove_from_feature_works if generic_file.visibility_changed? && !generic_file.public?
62
63
  save_and_record_committer do
63
64
  if Sufia.config.respond_to?(:after_update_metadata)
64
65
  Sufia.config.after_update_metadata.call(generic_file, user)
@@ -69,6 +70,7 @@ module Sufia::GenericFile
69
70
  def destroy
70
71
  pid = generic_file.pid #Work around for https://github.com/projecthydra/active_fedora/issues/422
71
72
  generic_file.destroy
73
+ FeaturedWork.where(generic_file_id: pid).destroy_all
72
74
  if Sufia.config.respond_to?(:after_destroy)
73
75
  Sufia.config.after_destroy.call(pid, user)
74
76
  end
@@ -87,7 +89,7 @@ module Sufia::GenericFile
87
89
  begin
88
90
  return false unless generic_file.save
89
91
  rescue RSolr::Error::Http => error
90
- logger.warn "Sufia::GenericFile::Actor::save_and_record_committer Caught RSOLR error #{error.inspect}"
92
+ ActiveFedora::Base.logger.warn "Sufia::GenericFile::Actor::save_and_record_committer Caught RSOLR error #{error.inspect}"
91
93
  save_tries+=1
92
94
  # fail for good if the tries is greater than 3
93
95
  raise error if save_tries >=3
@@ -107,12 +109,19 @@ module Sufia::GenericFile
107
109
  def virus_check(file)
108
110
  path = file.is_a?(String) ? file : file.path
109
111
  unless defined?(ClamAV)
110
- logger.warn "Virus checking disabled, #{path} not checked"
112
+ ActiveFedora::Base.logger.warn "Virus checking disabled, #{path} not checked"
111
113
  return
112
114
  end
113
115
  scan_result = ClamAV.instance.scanfile(path)
114
116
  raise Sufia::VirusFoundError.new("A virus was found in #{path}: #{scan_result}") unless scan_result == 0
115
117
  end
116
118
  end
119
+
120
+ private
121
+ def remove_from_feature_works
122
+ featured_work = FeaturedWork.find_by_generic_file_id(generic_file.noid)
123
+ featured_work.destroy unless featured_work.nil?
124
+ end
125
+
117
126
  end
118
127
  end
@@ -15,25 +15,19 @@ class AuditJob < ActiveFedoraPidBasedJob
15
15
  end
16
16
 
17
17
  def run
18
- #logger.info "GF is #{generic_file.pid}"
19
18
  if generic_file
20
19
  datastream = generic_file.datastreams[datastream_id]
21
- #logger.info "DS is #{datastream.inspect}"
22
20
  if datastream
23
- #logger.info "Datastream for audit = #{datastream.inspect}"
24
21
  version = datastream.versions.select { |v| v.versionID == version_id}.first
25
22
  log = run_audit(version)
26
23
 
27
24
  # look up the user for sending the message to
28
25
  login = generic_file.depositor
29
- #logger.info "User login is #{login}"`
30
- #logger.info "All users = #{User.all}"
31
26
  if login
32
27
  user = User.find_by_user_key(login)
33
- logger.warn "User '#{login}' not found" unless user
34
- #logger.info "ZZZ user = #{user.inspect}"
28
+ ActiveFedora::Base.logger.warn "User '#{login}' not found" unless user
35
29
  job_user = User.audituser()
36
- #send the user a message about the failing audit
30
+ # send the user a message about the failing audit
37
31
  unless (log.pass == 1)
38
32
  message = "The audit run at #{log.created_at} for #{log.pid}:#{log.dsid}:#{log.version} was #{log.pass == 1 ? 'passing' : 'failing'}."
39
33
  subject = (log.pass == 1 ? PASS : FAIL)
@@ -41,10 +35,10 @@ class AuditJob < ActiveFedoraPidBasedJob
41
35
  end
42
36
  end
43
37
  else
44
- logger.warn "No datastream for audit!!!!! pid: #{pid} dsid: #{datastream_id}"
38
+ ActiveFedora::Base.logger.warn "No datastream for audit!!!!! pid: #{pid} dsid: #{datastream_id}"
45
39
  end
46
40
  else
47
- logger.warn "No generic file for data stream audit!!!!! pid: #{pid} dsid: #{datastream_id}"
41
+ ActiveFedora::Base.logger.warn "No generic file for data stream audit!!!!! pid: #{pid} dsid: #{datastream_id}"
48
42
  end
49
43
  end
50
44
 
@@ -1,12 +1,12 @@
1
1
  class BatchUpdateJob
2
2
  include Hydra::PermissionsQuery
3
- include Rails.application.routes.url_helpers
3
+ include Sufia::Messages
4
4
 
5
5
  def queue_name
6
6
  :batch_update
7
7
  end
8
8
 
9
- attr_accessor :login, :title, :file_attributes, :batch_id, :visibility
9
+ attr_accessor :login, :title, :file_attributes, :batch_id, :visibility, :saved, :denied
10
10
 
11
11
  def initialize(login, params)
12
12
  self.login = login
@@ -14,32 +14,29 @@ class BatchUpdateJob
14
14
  self.file_attributes = params[:generic_file]
15
15
  self.visibility = params[:visibility]
16
16
  self.batch_id = params[:id]
17
+ self.saved = []
18
+ self.denied = []
17
19
  end
18
20
 
19
21
  def run
20
22
  batch = Batch.find_or_create(self.batch_id)
21
23
  user = User.find_by_user_key(self.login)
22
- @saved = []
23
- @denied = []
24
24
 
25
25
  batch.generic_files.each do |gf|
26
26
  update_file(gf, user)
27
27
  end
28
28
  batch.update_attributes({status:["Complete"]})
29
-
30
- job_user = User.batchuser()
31
-
32
- message = '<span class="batchid ui-helper-hidden">ss-'+batch.noid+'</span>The file(s) '+ file_list(@saved)+ " have been saved." unless @saved.empty?
33
- job_user.send_message(user, message, 'Batch upload complete') unless @saved.empty?
34
-
35
- message = '<span class="batchid ui-helper-hidden">'+batch.noid+'</span>The file(s) '+ file_list(@denied)+" could not be updated. You do not have sufficient privileges to edit it." unless @denied.empty?
36
- job_user.send_message(user, message, 'Batch upload permission denied') unless @denied.empty?
29
+ if denied.empty?
30
+ send_user_success_message(user, batch) unless saved.empty?
31
+ else
32
+ send_user_failure_message(user, batch)
33
+ end
37
34
  end
38
35
 
39
36
  def update_file(gf, user)
40
37
  unless user.can? :edit, gf
41
- logger.error "User #{user.user_key} DENIED access to #{gf.pid}!"
42
- @denied << gf
38
+ ActiveFedora::Base.logger.error "User #{user.user_key} DENIED access to #{gf.pid}!"
39
+ denied << gf
43
40
  return
44
41
  end
45
42
  gf.title = title[gf.pid] if title[gf.pid] rescue gf.label
@@ -51,17 +48,24 @@ class BatchUpdateJob
51
48
  gf.save!
52
49
  rescue RSolr::Error::Http => error
53
50
  save_tries += 1
54
- logger.warn "BatchUpdateJob caught RSOLR error on #{gf.pid}: #{error.inspect}"
51
+ ActiveFedora::Base.logger.warn "BatchUpdateJob caught RSOLR error on #{gf.pid}: #{error.inspect}"
55
52
  # fail for good if the tries is greater than 3
56
53
  raise error if save_tries >=3
57
54
  sleep 0.01
58
55
  retry
59
56
  end #
60
57
  Sufia.queue.push(ContentUpdateEventJob.new(gf.pid, login))
61
- @saved << gf
58
+ saved << gf
59
+ end
60
+
61
+ def send_user_success_message user, batch
62
+ message = saved.count > 1 ? multiple_success(batch.noid, saved) : single_success(batch.noid, saved.first)
63
+ User.batchuser.send_message(user, message, success_subject, sanitize_text = false)
62
64
  end
63
65
 
64
- def file_list ( files)
65
- files.map { |gf| '<a href="'+Sufia::Engine.routes.url_helpers.generic_files_path+'/'+gf.noid+'">'+gf.to_s+'</a>' }.join(', ')
66
+ def send_user_failure_message user, batch
67
+ message = denied.count > 1 ? multiple_failure(batch.noid, denied) : single_failure(batch.noid, denied.first)
68
+ User.batchuser.send_message(user, message, failure_subject, sanitize_text = false)
66
69
  end
70
+
67
71
  end
File without changes
File without changes
File without changes
@@ -1,41 +1,3 @@
1
1
  class Collection < ActiveFedora::Base
2
- include Hydra::Collection
3
- include Sufia::ModelMethods
4
- include Sufia::Noid
5
- include Sufia::GenericFile::Permissions
6
- include Sufia::GenericFile::WebForm # provides initialize_fields method
7
-
8
- before_save :update_permissions
9
- validates :title, presence: true
10
-
11
- has_metadata "properties", type: PropertiesDatastream
12
-
13
- def terms_for_display
14
- [:title, :creator, :description, :date_modified, :date_uploaded]
15
- end
16
-
17
- def terms_for_editing
18
- terms_for_display - [:date_modified, :date_uploaded]
19
- end
20
-
21
- # Test to see if the given field is required
22
- # @param [Symbol] key a field
23
- # @return [Boolean] is it required or not
24
- def required?(key)
25
- self.class.validators_on(key).any?{|v| v.kind_of? ActiveModel::Validations::PresenceValidator}
26
- end
27
-
28
- def to_param
29
- noid
30
- end
31
-
32
- def to_solr(solr_doc={}, opts={})
33
- super(solr_doc, opts)
34
- solr_doc[Solrizer.solr_name("noid", Sufia::GenericFile.noid_indexer)] = noid
35
- return solr_doc
36
- end
37
-
38
- def update_permissions
39
- self.visibility = "open"
40
- end
2
+ include Sufia::Collection
41
3
  end
File without changes
@@ -0,0 +1,55 @@
1
+ module Sufia
2
+ module Collection
3
+ extend ActiveSupport::Concern
4
+ include Hydra::Collection
5
+ include Sufia::ModelMethods
6
+ include Sufia::Noid
7
+ include Sufia::GenericFile::Permissions
8
+ include Sufia::GenericFile::WebForm # provides initialize_fields method
9
+
10
+ included do
11
+ before_save :update_permissions
12
+ validates :title, presence: true
13
+
14
+ has_metadata "properties", type: PropertiesDatastream
15
+ end
16
+
17
+ def terms_for_display
18
+ terms_for_editing - [:title, :description]
19
+ end
20
+
21
+ def terms_for_editing
22
+ [:resource_type, :title, :creator, :contributor, :description, :tag,
23
+ :rights, :publisher, :date_created, :subject, :language, :identifier,
24
+ :based_near, :related_url]
25
+ end
26
+
27
+ # Test to see if the given field is required
28
+ # @param [Symbol] key a field
29
+ # @return [Boolean] is it required or not
30
+ def required?(key)
31
+ self.class.validators_on(key).any?{|v| v.kind_of? ActiveModel::Validations::PresenceValidator}
32
+ end
33
+
34
+ def to_param
35
+ noid
36
+ end
37
+
38
+ def to_solr(solr_doc={}, opts={})
39
+ super(solr_doc, opts)
40
+ solr_doc[Solrizer.solr_name("noid", Sufia::GenericFile.noid_indexer)] = noid
41
+ return solr_doc
42
+ end
43
+
44
+ def update_permissions
45
+ self.visibility = "open"
46
+ end
47
+
48
+ # Compute the sum of each file in the collection
49
+ # Return an integer of the result
50
+ def bytes
51
+ members.reduce(0) { |sum, gf| sum + gf.file_size.first.to_i }
52
+ end
53
+
54
+ end
55
+ end
@@ -18,6 +18,7 @@ module Sufia
18
18
  include Sufia::GenericFile::Versions
19
19
  include Sufia::GenericFile::VirusCheck
20
20
  include Sufia::GenericFile::ReloadOnSave
21
+ include Sufia::GenericFile::FullTextIndexing
21
22
  include Hydra::Collections::Collectible
22
23
 
23
24
  included do
@@ -69,17 +70,9 @@ module Sufia
69
70
  # until all objects are done uploading and the user is redirected to
70
71
  # BatchController#edit. Therefore, we must handle the case where
71
72
  # self.batch_id is set but self.batch returns nil.
72
- # This can get a major overhaul with ActiveFedora 7
73
73
  def related_files
74
- relateds = begin
75
- self.batch.generic_files
76
- rescue NoMethodError => e
77
- #batch is nil - When would this ever happen?
78
- batch_id = self.object_relations["isPartOf"].first || self.object_relations[:is_part_of].first
79
- return [] if batch_id.nil?
80
- self.class.find(Solrizer.solr_name('is_part_of', :symbol) => batch_id)
81
- end
82
- relateds.reject { |gf| gf.pid == self.pid }
74
+ return [] if batch.nil?
75
+ batch.generic_files.reject { |sibling| sibling.id == id }
83
76
  end
84
77
 
85
78
  # Unstemmed, searchable, stored
@@ -93,6 +86,7 @@ module Sufia
93
86
  solr_doc[Solrizer.solr_name('noid', Sufia::GenericFile.noid_indexer)] = noid
94
87
  solr_doc[Solrizer.solr_name('file_format')] = file_format
95
88
  solr_doc[Solrizer.solr_name('file_format', :facetable)] = file_format
89
+ solr_doc['all_text_timv'] = full_text.content
96
90
  solr_doc = index_collection_pids(solr_doc)
97
91
  end
98
92
  end
@@ -100,7 +94,7 @@ module Sufia
100
94
  def label=(new_label)
101
95
  @inner_object.label = new_label
102
96
  if self.title.empty?
103
- self.title = new_label
97
+ self.title = [new_label].compact
104
98
  end
105
99
  end
106
100
 
@@ -2,8 +2,6 @@ module Sufia
2
2
  module GenericFile
3
3
  module Audit
4
4
  extend ActiveSupport::Concern
5
- included do
6
- end
7
5
 
8
6
  NO_RUNS = 999
9
7
 
@@ -17,6 +15,7 @@ module Sufia
17
15
 
18
16
  def per_version(&block)
19
17
  self.datastreams.each do |dsid, ds|
18
+ next if ds == full_text
20
19
  ds.versions.each do |ver|
21
20
  block.call(ver)
22
21
  end
@@ -42,9 +42,11 @@ module Sufia
42
42
 
43
43
  ## Extract the metadata from the content datastream and record it in the characterization datastream
44
44
  def characterize
45
- self.characterization.ng_xml = self.content.extract_metadata
45
+ metadata = self.content.extract_metadata
46
+ self.characterization.ng_xml = metadata if metadata.present?
46
47
  self.append_metadata
47
- self.filename = self.label
48
+ self.filename = [self.label]
49
+ extract_content
48
50
  save
49
51
  end
50
52
 
@@ -0,0 +1,27 @@
1
+ module Sufia
2
+ module GenericFile
3
+ module FullTextIndexing
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_file_datastream 'full_text', versionable: false
8
+ end
9
+
10
+ def extract_content
11
+ url = Blacklight.solr_config[:url] ? Blacklight.solr_config[:url] : Blacklight.solr_config["url"] ? Blacklight.solr_config["url"] : Blacklight.solr_config[:fulltext] ? Blacklight.solr_config[:fulltext]["url"] : Blacklight.solr_config[:default]["url"]
12
+ uri = URI("#{url}/update/extract?extractOnly=true&wt=json&extractFormat=text")
13
+ req = Net::HTTP.new(uri.host, uri.port)
14
+ resp = req.post(uri.to_s, self.content.content, {
15
+ 'Content-type' => "#{self.mime_type};charset=utf-8",
16
+ 'Content-Length' => self.content.content.size.to_s
17
+ })
18
+ raise "URL '#{uri}' returned code #{resp.code}" unless resp.code == "200"
19
+ self.content.content.rewind if self.content.content.respond_to?(:rewind)
20
+ extracted_text = JSON.parse(resp.body)[''].rstrip
21
+ full_text.content = extracted_text if extracted_text.present?
22
+ rescue => e
23
+ logger.error("Error extracting content from #{self.pid}: #{e.inspect}")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -53,6 +53,7 @@ module Sufia
53
53
  ['text/rtf',
54
54
  'application/msword',
55
55
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
56
+ 'application/vnd.oasis.opendocument.text',
56
57
  'application/vnd.ms-excel',
57
58
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
58
59
  'application/vnd.ms-powerpoint',
@@ -2,57 +2,10 @@ module Sufia
2
2
  module GenericFile
3
3
  module Permissions
4
4
  extend ActiveSupport::Concern
5
- #we're overriding the permissions= method which is in Hydra::AccessControls::Permissions
6
- include Hydra::AccessControls::Permissions
7
- include Hydra::AccessControls::Visibility
8
5
 
9
- included do
10
- has_metadata "rightsMetadata", type: ParanoidRightsDatastream
11
- validate :paranoid_permissions
12
- end
6
+ include Sufia::Permissions::Writable
7
+ include Sufia::Permissions::Readable
13
8
 
14
- def paranoid_permissions
15
- # let the rightsMetadata ds make this determination
16
- # - the object instance is passed in for easier access to the props ds
17
- rightsMetadata.validate(self)
18
- end
19
-
20
- ## Updates those permissions that are provided to it. Does not replace any permissions unless they are provided
21
- def permissions=(params)
22
- perm_hash = permission_hash
23
- params[:new_user_name].each { |name, access| perm_hash['person'][name] = access } if params[:new_user_name].present?
24
- params[:new_group_name].each { |name, access| perm_hash['group'][name] = access } if params[:new_group_name].present?
25
-
26
- params[:user].each { |name, access| perm_hash['person'][name] = access} if params[:user]
27
- params[:group].each { |name, access| perm_hash['group'][name] = access if ['read', 'edit'].include?(access)} if params[:group]
28
-
29
- rightsMetadata.update_permissions(perm_hash)
30
- end
31
-
32
- def permissions
33
- perms = super
34
- perms.map {|p| { name: p.name, access: p.access, type:p.type } }
35
- end
36
-
37
- def public?
38
- read_groups.include?('public')
39
- end
40
-
41
- private
42
-
43
- def permission_hash
44
- old_perms = self.permissions
45
- user_perms = {}
46
- old_perms.select{|r| r[:type] == 'user'}.each do |r|
47
- user_perms[r[:name]] = r[:access]
48
- end
49
- user_perms
50
- group_perms = {}
51
- old_perms.select{|r| r[:type] == 'group'}.each do |r|
52
- group_perms[r[:name]] = r[:access]
53
- end
54
- {'person'=>user_perms, 'group'=>group_perms}
55
- end
56
9
  end
57
10
  end
58
11
  end