sufia-models 6.0.0.rc4 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/actors/sufia/generic_file/actor.rb +1 -1
- data/app/jobs/active_fedora_id_based_job.rb +22 -0
- data/app/jobs/active_fedora_pid_based_job.rb +5 -20
- data/app/jobs/audit_job.rb +5 -6
- data/app/jobs/characterize_job.rb +1 -1
- data/app/jobs/create_derivatives_job.rb +1 -1
- data/app/jobs/import_url_job.rb +2 -2
- data/app/models/batch.rb +18 -4
- data/app/models/checksum_audit_log.rb +2 -2
- data/app/models/concerns/sufia/ability.rb +7 -1
- data/app/models/concerns/sufia/collection_behavior.rb +1 -1
- data/app/models/concerns/sufia/generic_file/full_text_indexing.rb +23 -14
- data/app/models/concerns/sufia/generic_file/proxy_deposit.rb +1 -1
- data/app/models/datastreams/fits_datastream.rb +1 -36
- data/app/models/proxy_deposit_request.rb +6 -6
- data/app/services/sufia/generic_file_audit_service.rb +1 -1
- data/app/services/sufia/generic_file_indexing_service.rb +0 -1
- data/app/services/sufia/id_service.rb +2 -3
- data/app/services/sufia/noid.rb +1 -1
- data/lib/generators/sufia/models/templates/config/sufia.rb +1 -1
- data/lib/generators/sufia/models/templates/migrations/change_audit_log_pid_to_generic_file_id.rb +5 -0
- data/lib/generators/sufia/models/templates/migrations/change_proxy_deposit_request_pid_to_generic_file_id.rb +5 -0
- data/lib/generators/sufia/models/upgrade600_generator.rb +21 -0
- data/lib/sufia/models/stats/user_stat_importer.rb +20 -1
- data/lib/sufia/models/version.rb +1 -1
- data/lib/tasks/batch_cleanup.rake +19 -0
- data/lib/tasks/migrate.rake +21 -0
- data/lib/tasks/sufia-models_tasks.rake +55 -38
- data/sufia-models.gemspec +1 -1
- metadata +21 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c12a4f1425665634659dfd88233a2c365594589d
|
4
|
+
data.tar.gz: 06d1405c0b4f1537c071700faadc20a0264f34e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07a66fa4a7b7c950459a91143ac460859ce38edc9a7d336badb586bbaed916c168fe468dcdcad36405fa8d653774db8ad1acc9a9da07ab42b06e066ba18a6c1e
|
7
|
+
data.tar.gz: ae73b9db8e0607bfb3dcfcab6aef808a8b88be53b8447c66db279a6071ec8433f024dfdac404a5c5167865a6df153f22b03854e625df929175fe07f98cb6a93b
|
@@ -31,7 +31,7 @@ module Sufia::GenericFile
|
|
31
31
|
def create_content(file, file_name, path, mime_type)
|
32
32
|
generic_file.add_file(file, path: path, original_name: file_name, mime_type: mime_type)
|
33
33
|
generic_file.label ||= file_name
|
34
|
-
generic_file.title = [
|
34
|
+
generic_file.title = [generic_file.label] if generic_file.title.blank?
|
35
35
|
save_characterize_and_record_committer do
|
36
36
|
if Sufia.config.respond_to?(:after_create_content)
|
37
37
|
Sufia.config.after_create_content.call(generic_file, user)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class ActiveFedoraIdBasedJob
|
2
|
+
def queue_name
|
3
|
+
:id_based
|
4
|
+
end
|
5
|
+
|
6
|
+
attr_accessor :id
|
7
|
+
|
8
|
+
def initialize(id)
|
9
|
+
self.id = id
|
10
|
+
end
|
11
|
+
|
12
|
+
def object
|
13
|
+
@object ||= ActiveFedora::Base.find(id)
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :generic_file, :object
|
17
|
+
alias_method :generic_file_id, :id
|
18
|
+
|
19
|
+
def run
|
20
|
+
raise RuntimeError, "Define #run in a subclass"
|
21
|
+
end
|
22
|
+
end
|
@@ -1,22 +1,7 @@
|
|
1
|
-
class ActiveFedoraPidBasedJob
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
attr_accessor :pid
|
7
|
-
|
8
|
-
def initialize(pid)
|
9
|
-
self.pid = pid
|
10
|
-
end
|
11
|
-
|
12
|
-
def object
|
13
|
-
@object ||= ActiveFedora::Base.find(pid)
|
14
|
-
end
|
15
|
-
|
16
|
-
alias_method :generic_file, :object
|
17
|
-
alias_method :generic_file_id, :pid
|
18
|
-
|
19
|
-
def run
|
20
|
-
raise RuntimeError, "Define #run in a subclass"
|
1
|
+
class ActiveFedoraPidBasedJob < ActiveFedoraIdBasedJob
|
2
|
+
extend Deprecation
|
3
|
+
def self.extended(document)
|
4
|
+
Deprecation.warn ActiveFedoraPidBasedJob, "ActiveFedoraPidBasedJob is deprecated; use ActiveFedoraIdBasedJob instead."
|
21
5
|
end
|
22
6
|
end
|
7
|
+
|
data/app/jobs/audit_job.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class AuditJob <
|
1
|
+
class AuditJob < ActiveFedoraIdBasedJob
|
2
2
|
def queue_name
|
3
3
|
:audit
|
4
4
|
end
|
@@ -6,7 +6,7 @@ class AuditJob < ActiveFedoraPidBasedJob
|
|
6
6
|
PASS = 'Passing Audit Run'
|
7
7
|
FAIL = 'Failing Audit Run'
|
8
8
|
|
9
|
-
attr_accessor :uri, :
|
9
|
+
attr_accessor :uri, :id, :path
|
10
10
|
|
11
11
|
# URI of the resource to audit.
|
12
12
|
# This URI could include the actual resource (e.g. content) and the version to audit:
|
@@ -14,8 +14,7 @@ class AuditJob < ActiveFedoraPidBasedJob
|
|
14
14
|
# but it could also just be:
|
15
15
|
# http://localhost:8983/fedora/rest/test/a/b/c/abcxyz/content
|
16
16
|
def initialize(id, path, uri)
|
17
|
-
super(
|
18
|
-
self.pid = id
|
17
|
+
super(id)
|
19
18
|
self.path = path
|
20
19
|
self.uri = uri
|
21
20
|
end
|
@@ -49,12 +48,12 @@ class AuditJob < ActiveFedoraPidBasedJob
|
|
49
48
|
|
50
49
|
if fixity_ok
|
51
50
|
passing = 1
|
52
|
-
ChecksumAuditLog.prune_history(
|
51
|
+
ChecksumAuditLog.prune_history(id, path)
|
53
52
|
else
|
54
53
|
logger.warn "***AUDIT*** Audit failed for #{uri} #{error_msg}"
|
55
54
|
passing = 0
|
56
55
|
end
|
57
|
-
ChecksumAuditLog.create!(pass: passing,
|
56
|
+
ChecksumAuditLog.create!(pass: passing, generic_file_id: id, version: uri, dsid: path)
|
58
57
|
end
|
59
58
|
|
60
59
|
def logger
|
data/app/jobs/import_url_job.rb
CHANGED
@@ -2,7 +2,7 @@ require 'net/https'
|
|
2
2
|
require 'uri'
|
3
3
|
require 'tempfile'
|
4
4
|
|
5
|
-
class ImportUrlJob <
|
5
|
+
class ImportUrlJob < ActiveFedoraIdBasedJob
|
6
6
|
|
7
7
|
def queue_name
|
8
8
|
:import_url
|
@@ -11,7 +11,7 @@ class ImportUrlJob < ActiveFedoraPidBasedJob
|
|
11
11
|
def run
|
12
12
|
user = User.find_by_user_key(generic_file.depositor)
|
13
13
|
|
14
|
-
Tempfile.open(
|
14
|
+
Tempfile.open(id.gsub('/', '_')) do |f|
|
15
15
|
path, mime_type = copy_remote_file(generic_file.import_url, f)
|
16
16
|
# attach downloaded file to generic file stubbed out
|
17
17
|
if Sufia::GenericFile::Actor.new(generic_file, user).create_content(f, path, 'content', mime_type)
|
data/app/models/batch.rb
CHANGED
@@ -10,13 +10,27 @@ class Batch < ActiveFedora::Base
|
|
10
10
|
property :status, predicate: ::RDF::DC.type
|
11
11
|
|
12
12
|
def self.find_or_create(id)
|
13
|
-
# FIXME potential race condition in this method. Consider that `find' may raise
|
14
|
-
# ObjectNotFound in multiple processes. However, Fedora should raise an error
|
15
|
-
# if we try to create two objects with the same id.
|
16
13
|
begin
|
17
14
|
Batch.find(id)
|
18
15
|
rescue ActiveFedora::ObjectNotFoundError
|
19
|
-
|
16
|
+
safe_create(id)
|
20
17
|
end
|
21
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# This method handles most race conditions gracefully.
|
23
|
+
# If a batch with the same ID is created by another thread
|
24
|
+
# we fetch the batch that was created (rather than throwing
|
25
|
+
# an error) and continute.
|
26
|
+
def self.safe_create(id)
|
27
|
+
begin
|
28
|
+
Batch.create(id: id)
|
29
|
+
rescue ActiveFedora::IllegalOperation => ex
|
30
|
+
# This is the exception thrown by LDP when we attempt to
|
31
|
+
# create a duplicate object. If we can find the object
|
32
|
+
# then we are good to go.
|
33
|
+
Batch.find(id)
|
34
|
+
end
|
35
|
+
end
|
22
36
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class ChecksumAuditLog < ActiveRecord::Base
|
2
2
|
|
3
3
|
def self.get_audit_log(id, path, version_uri)
|
4
|
-
ChecksumAuditLog.find_or_create_by(
|
4
|
+
ChecksumAuditLog.find_or_create_by(generic_file_id: id, dsid: path, version: version_uri)
|
5
5
|
end
|
6
6
|
|
7
7
|
# Check to see if there are previous passing logs that we can delete
|
@@ -16,6 +16,6 @@ class ChecksumAuditLog < ActiveRecord::Base
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.logs_for(id, path)
|
19
|
-
ChecksumAuditLog.where(
|
19
|
+
ChecksumAuditLog.where(generic_file_id: id, dsid: path).order('created_at desc, id desc')
|
20
20
|
end
|
21
21
|
end
|
@@ -8,6 +8,7 @@ module Sufia
|
|
8
8
|
|
9
9
|
def sufia_abilities
|
10
10
|
generic_file_abilities
|
11
|
+
user_abilities
|
11
12
|
featured_work_abilities
|
12
13
|
editor_abilities
|
13
14
|
stats_abilities
|
@@ -23,7 +24,10 @@ module Sufia
|
|
23
24
|
can :reject, ProxyDepositRequest, receiving_user_id: current_user.id, status: 'pending'
|
24
25
|
# a user who sent a proxy deposit request can cancel it if it's pending.
|
25
26
|
can :destroy, ProxyDepositRequest, sending_user_id: current_user.id, status: 'pending'
|
26
|
-
|
27
|
+
end
|
28
|
+
|
29
|
+
def user_abilities
|
30
|
+
can [:edit, :update, :toggle_trophy], ::User, id: current_user.id
|
27
31
|
end
|
28
32
|
|
29
33
|
def featured_work_abilities
|
@@ -31,6 +35,7 @@ module Sufia
|
|
31
35
|
end
|
32
36
|
|
33
37
|
def generic_file_abilities
|
38
|
+
can :view_share_work, [GenericFile]
|
34
39
|
can :create, [GenericFile, Collection] if user_groups.include? 'registered'
|
35
40
|
end
|
36
41
|
|
@@ -51,5 +56,6 @@ module Sufia
|
|
51
56
|
def depositor_for_document(document_id)
|
52
57
|
::GenericFile.load_instance_from_solr(document_id).depositor
|
53
58
|
end
|
59
|
+
|
54
60
|
end
|
55
61
|
end
|
@@ -18,7 +18,7 @@ module Sufia
|
|
18
18
|
# Compute the sum of each file in the collection
|
19
19
|
# Return an integer of the result
|
20
20
|
def bytes
|
21
|
-
members.reduce(0) { |sum, gf| sum + gf.
|
21
|
+
members.reduce(0) { |sum, gf| sum + gf.content.size.to_i }
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -14,21 +14,30 @@ module Sufia
|
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
def extract_content
|
18
|
+
uri = URI("#{connection_url}/update/extract?extractOnly=true&wt=json&extractFormat=text")
|
19
|
+
req = Net::HTTP.new(uri.host, uri.port)
|
20
|
+
resp = req.post(uri.to_s, self.content.content, {
|
21
|
+
'Content-type' => "#{self.mime_type};charset=utf-8",
|
22
|
+
'Content-Length' => self.content.content.size.to_s
|
23
|
+
})
|
24
|
+
raise "URL '#{uri}' returned code #{resp.code}" unless resp.code == "200"
|
25
|
+
self.content.content.rewind if self.content.content.respond_to?(:rewind)
|
26
|
+
extracted_text = JSON.parse(resp.body)[''].rstrip
|
27
|
+
full_text.content = extracted_text if extracted_text.present?
|
28
|
+
rescue => e
|
29
|
+
logger.error("Error extracting content from #{self.id}: #{e.inspect}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def connection_url
|
33
|
+
case
|
34
|
+
when Blacklight.connection_config[:url] then Blacklight.connection_config[:url]
|
35
|
+
when Blacklight.connection_config["url"] then Blacklight.connection_config["url"]
|
36
|
+
when Blacklight.connection_config[:fulltext] then Blacklight.connection_config[:fulltext]["url"]
|
37
|
+
else Blacklight.connection_config[:default]["url"]
|
31
38
|
end
|
39
|
+
end
|
40
|
+
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
@@ -24,7 +24,7 @@ module Sufia
|
|
24
24
|
def request_transfer_to(target)
|
25
25
|
raise ArgumentError, "Must provide a target" unless target
|
26
26
|
deposit_user = ::User.find_by_user_key(depositor)
|
27
|
-
ProxyDepositRequest.create!(
|
27
|
+
ProxyDepositRequest.create!(generic_file_id: id, receiving_user: target, sending_user: deposit_user)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -144,42 +144,7 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
144
144
|
http://hul.harvard.edu/ois/xml/xsd/fits/fits_output.xsd",
|
145
145
|
version: "0.6.0",
|
146
146
|
timestamp: "1/25/12 11:04 AM") {
|
147
|
-
xml.identification {
|
148
|
-
xml.identity(format: '', mimetype: '',
|
149
|
-
toolname: 'FITS', toolversion: '') {
|
150
|
-
xml.tool(toolname: '', toolversion: '')
|
151
|
-
xml.version(toolname: '', toolversion: '')
|
152
|
-
xml.externalIdentifier(toolname: '', toolversion: '')
|
153
|
-
}
|
154
|
-
}
|
155
|
-
xml.fileinfo {
|
156
|
-
xml.size(toolname: '', toolversion: '')
|
157
|
-
xml.creatingApplicatioName(toolname: '', toolversion: '',
|
158
|
-
status: '')
|
159
|
-
xml.lastmodified(toolname: '', toolversion: '', status: '')
|
160
|
-
xml.filepath(toolname: '', toolversion: '', status: '')
|
161
|
-
xml.filename(toolname: '', toolversion: '', status: '')
|
162
|
-
xml.md5checksum(toolname: '', toolversion: '', status: '')
|
163
|
-
xml.fslastmodified(toolname: '', toolversion: '', status: '')
|
164
|
-
}
|
165
|
-
xml.filestatus {
|
166
|
-
xml.tag! "well-formed", toolname: '', toolversion: '', status: ''
|
167
|
-
xml.valid(toolname: '', toolversion: '', status: '')
|
168
|
-
}
|
169
|
-
xml.metadata {
|
170
|
-
xml.document {
|
171
|
-
xml.title(toolname: '', toolversion: '', status: '')
|
172
|
-
xml.author(toolname: '', toolversion: '', status: '')
|
173
|
-
xml.pageCount(toolname: '', toolversion: '')
|
174
|
-
xml.isTagged(toolname: '', toolversion: '')
|
175
|
-
xml.hasOutline(toolname: '', toolversion: '')
|
176
|
-
xml.hasAnnotations(toolname: '', toolversion: '')
|
177
|
-
xml.isRightsManaged(toolname: '', toolversion: '',
|
178
|
-
status: '')
|
179
|
-
xml.isProtected(toolname: '', toolversion: '')
|
180
|
-
xml.hasForms(toolname: '', toolversion: '', status: '')
|
181
|
-
}
|
182
|
-
}
|
147
|
+
xml.identification { xml.identity(toolname: 'FITS') }
|
183
148
|
}
|
184
149
|
end
|
185
150
|
builder.doc
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class ProxyDepositRequest < ActiveRecord::Base
|
2
|
-
include Blacklight::
|
2
|
+
include Blacklight::SearchHelper
|
3
3
|
include ActionView::Helpers::UrlHelper
|
4
4
|
|
5
5
|
belongs_to :receiving_user, class_name: 'User'
|
6
6
|
belongs_to :sending_user, class_name: 'User'
|
7
7
|
|
8
|
-
validates :sending_user, :
|
8
|
+
validates :sending_user, :generic_file_id, presence: true
|
9
9
|
validate :transfer_to_should_be_a_valid_username
|
10
10
|
validate :sending_user_should_not_be_receiving_user
|
11
11
|
validate :should_not_be_already_part_of_a_transfer
|
@@ -28,7 +28,7 @@ class ProxyDepositRequest < ActiveRecord::Base
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def should_not_be_already_part_of_a_transfer
|
31
|
-
transfers = ProxyDepositRequest.where(
|
31
|
+
transfers = ProxyDepositRequest.where(generic_file_id: generic_file_id, status: 'pending')
|
32
32
|
errors.add(:open_transfer, 'must close open transfer on the file before creating a new one') unless transfers.blank? || ( transfers.count == 1 && transfers[0].id == self.id)
|
33
33
|
end
|
34
34
|
|
@@ -53,7 +53,7 @@ class ProxyDepositRequest < ActiveRecord::Base
|
|
53
53
|
|
54
54
|
# @param [Boolean] reset (false) should the access controls be reset. This means revoking edit access from the depositor
|
55
55
|
def transfer!(reset = false)
|
56
|
-
Sufia.queue.push(ContentDepositorChangeEventJob.new(
|
56
|
+
Sufia.queue.push(ContentDepositorChangeEventJob.new(generic_file_id, receiving_user.user_key, reset))
|
57
57
|
self.status = 'accepted'
|
58
58
|
self.fulfillment_date = Time.now
|
59
59
|
save!
|
@@ -73,12 +73,12 @@ class ProxyDepositRequest < ActiveRecord::Base
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def deleted_file?
|
76
|
-
!GenericFile.exists?(
|
76
|
+
!GenericFile.exists?(generic_file_id)
|
77
77
|
end
|
78
78
|
|
79
79
|
def title
|
80
80
|
return 'file not found' if deleted_file?
|
81
|
-
query = ActiveFedora::SolrQueryBuilder.construct_query_for_ids([
|
81
|
+
query = ActiveFedora::SolrQueryBuilder.construct_query_for_ids([generic_file_id])
|
82
82
|
solr_response = ActiveFedora::SolrService.query(query, raw: true)
|
83
83
|
SolrDocument.new(solr_response['response']['docs'].first, solr_response).title
|
84
84
|
end
|
@@ -63,7 +63,7 @@ module Sufia
|
|
63
63
|
latest_audit = ChecksumAuditLog.logs_for(generic_file.id, file).first
|
64
64
|
return latest_audit unless needs_audit?(latest_audit)
|
65
65
|
Sufia.queue.push(AuditJob.new(generic_file.id, file, uri))
|
66
|
-
latest_audit || ChecksumAuditLog.new(pass: NO_RUNS,
|
66
|
+
latest_audit || ChecksumAuditLog.new(pass: NO_RUNS, generic_file_id: generic_file.id, dsid: file, version: label)
|
67
67
|
end
|
68
68
|
|
69
69
|
def needs_audit?(latest_audit)
|
@@ -6,7 +6,6 @@ module Sufia
|
|
6
6
|
solr_doc[Solrizer.solr_name('file_format')] = object.file_format
|
7
7
|
solr_doc[Solrizer.solr_name('file_format', :facetable)] = object.file_format
|
8
8
|
solr_doc['all_text_timv'] = object.full_text.content
|
9
|
-
solr_doc = object.index_collection_ids(solr_doc)
|
10
9
|
end
|
11
10
|
end
|
12
11
|
end
|
@@ -8,7 +8,6 @@ module Sufia
|
|
8
8
|
end
|
9
9
|
|
10
10
|
@minter = ::Noid::Minter.new(template: noid_template)
|
11
|
-
@pid = $$
|
12
11
|
@semaphore = Mutex.new
|
13
12
|
def self.valid?(identifier)
|
14
13
|
# remove the fedora namespace since it's not part of the noid
|
@@ -18,8 +17,8 @@ module Sufia
|
|
18
17
|
def self.mint
|
19
18
|
@semaphore.synchronize do
|
20
19
|
while true
|
21
|
-
|
22
|
-
return
|
20
|
+
id = self.next_id
|
21
|
+
return id unless ActiveFedora::Base.exists?(id)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
data/app/services/sufia/noid.rb
CHANGED
@@ -2,7 +2,7 @@ module Sufia
|
|
2
2
|
module Noid
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
## This overrides the default behavior, which is to ask Fedora for
|
5
|
+
## This overrides the default behavior, which is to ask Fedora for an id
|
6
6
|
# @see ActiveFedora::Persistence.assign_id
|
7
7
|
def assign_id
|
8
8
|
Sufia::IdService.mint if Sufia.config.enable_noids
|
@@ -123,7 +123,7 @@ Sufia.config do |config|
|
|
123
123
|
# NOTE: if you have always sent analytics to GA for downloads and page views leave this commented out
|
124
124
|
# config.analytic_start_date = DateTime.new(2014,9,10)
|
125
125
|
#
|
126
|
-
# Method of converting
|
126
|
+
# Method of converting ids into URIs for storage in Fedora
|
127
127
|
# config.translate_uri_to_id = lambda { |uri| uri.to_s.split('/')[-1] }
|
128
128
|
# config.translate_id_to_uri = lambda { |id|
|
129
129
|
# "#{ActiveFedora.fedora.host}#{ActiveFedora.fedora.base_path}/#{Sufia::Noid.treeify(id)}" }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'abstract_migration_generator'
|
2
|
+
|
3
|
+
class Sufia::Models::Upgrade600Generator < Sufia::Models::AbstractMigrationGenerator
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
desc """
|
7
|
+
This generator for upgrading sufia-models to 6.0 makes the following changes to your application:
|
8
|
+
1. Creates several database migrations if they do not exist in /db/migrate
|
9
|
+
"""
|
10
|
+
|
11
|
+
# Setup the database migrations
|
12
|
+
def copy_migrations
|
13
|
+
[
|
14
|
+
'change_audit_log_pid_to_generic_file_id.rb',
|
15
|
+
'change_proxy_deposit_request_pid_to_generic_file_id.rb'
|
16
|
+
].each do |file|
|
17
|
+
better_migration_template file
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -1,23 +1,28 @@
|
|
1
1
|
module Sufia
|
2
2
|
class UserStatImporter
|
3
3
|
|
4
|
+
UserRecord = Struct.new("UserRecord", :id, :user_key, :last_stats_update)
|
5
|
+
|
4
6
|
def initialize(options={})
|
5
7
|
@verbose = options[:verbose]
|
6
8
|
@logging = options[:logging]
|
9
|
+
@delay_secs = options[:delay_secs].to_f
|
7
10
|
end
|
8
11
|
|
9
12
|
def import
|
10
13
|
log_message('Begin import of User stats.')
|
11
|
-
|
14
|
+
sorted_users.each do |user|
|
12
15
|
start_date = date_since_last_cache(user)
|
13
16
|
|
14
17
|
stats = {}
|
15
18
|
file_ids_for_user(user).each do |file_id|
|
16
19
|
view_stats = FileViewStat.statistics(file_id, start_date, user.id)
|
17
20
|
stats = tally_results(view_stats, :views, stats)
|
21
|
+
delay
|
18
22
|
|
19
23
|
dl_stats = FileDownloadStat.statistics(file_id, start_date, user.id)
|
20
24
|
stats = tally_results(dl_stats, :downloads, stats)
|
25
|
+
delay
|
21
26
|
end
|
22
27
|
|
23
28
|
create_or_update_user_stats(stats, user)
|
@@ -25,9 +30,23 @@ module Sufia
|
|
25
30
|
log_message('User stats import complete.')
|
26
31
|
end
|
27
32
|
|
33
|
+
# Returns an array of users sorted by the date of their last
|
34
|
+
# stats update. Users that have not been recently updated
|
35
|
+
# will be at the top of the array.
|
36
|
+
def sorted_users
|
37
|
+
users = []
|
38
|
+
::User.find_each do |user|
|
39
|
+
users.push(UserRecord.new(user.id, user.user_key, date_since_last_cache(user)))
|
40
|
+
end
|
41
|
+
users.sort! {|a, b| a.last_stats_update <=> b.last_stats_update}
|
42
|
+
end
|
28
43
|
|
29
44
|
private
|
30
45
|
|
46
|
+
def delay
|
47
|
+
sleep @delay_secs
|
48
|
+
end
|
49
|
+
|
31
50
|
def date_since_last_cache(user)
|
32
51
|
last_cached_stat = UserStat.where(user_id: user.id).order(date: :asc).last
|
33
52
|
|
data/lib/sufia/models/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
namespace :sufia do
|
2
|
+
|
3
|
+
desc "Reports on and optionally removes empty batches that contain no associated files"
|
4
|
+
task :empty_batches, [:remove] => :environment do |t, args|
|
5
|
+
option = args.to_hash.fetch(:remove, "keep")
|
6
|
+
Batch.all.each do |batch|
|
7
|
+
if batch.generic_files.empty?
|
8
|
+
print "#{batch.id} contains no files - "
|
9
|
+
if option == "remove"
|
10
|
+
batch.destroy
|
11
|
+
puts "deleted"
|
12
|
+
else
|
13
|
+
puts "to delete, rerun with the remove option: rake sufia:empty_batches[remove]"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :sufia do
|
2
|
+
namespace :migrate do
|
3
|
+
|
4
|
+
desc "Migrate proxy deposits"
|
5
|
+
task proxy_deposits: :environment do
|
6
|
+
ProxyDepositRequest.all.each do |pd|
|
7
|
+
pd.generic_file_id = pd.generic_file_id.delete "#{Sufia.config.redis_namespace}:"
|
8
|
+
pd.save
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Migrate audit logs"
|
13
|
+
task audit_logs: :environment do
|
14
|
+
ChecksumAuditLog.all.each do |cs|
|
15
|
+
cs.generic_file_id = cs.generic_file_id.delete "#{Sufia.config.redis_namespace}:"
|
16
|
+
cs.save
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
1
3
|
namespace :solr do
|
2
4
|
desc "Enqueue a job to resolrize the repository objects"
|
3
5
|
task reindex: :environment do
|
@@ -7,6 +9,41 @@ end
|
|
7
9
|
|
8
10
|
namespace :sufia do
|
9
11
|
namespace :jetty do
|
12
|
+
|
13
|
+
FULLTEXT_JARS = %w(
|
14
|
+
org/apache/james/apache-mime4j-core/0.7.2/apache-mime4j-core-0.7.2.jar
|
15
|
+
org/apache/james/apache-mime4j-dom/0.7.2/apache-mime4j-dom-0.7.2.jar
|
16
|
+
org/apache/solr/solr-cell/4.0.0/solr-cell-4.0.0.jar
|
17
|
+
org/bouncycastle/bcmail-jdk15/1.45/bcmail-jdk15-1.45.jar
|
18
|
+
org/bouncycastle/bcprov-jdk15/1.45/bcprov-jdk15-1.45.jar
|
19
|
+
de/l3s/boilerpipe/boilerpipe/1.1.0/boilerpipe-1.1.0.jar
|
20
|
+
org/apache/commons/commons-compress/1.4.1/commons-compress-1.4.1.jar
|
21
|
+
dom4j/dom4j/1.6.1/dom4j-1.6.1.jar
|
22
|
+
org/apache/pdfbox/fontbox/1.7.0/fontbox-1.7.0.jar
|
23
|
+
com/ibm/icu/icu4j/49.1/icu4j-49.1.jar
|
24
|
+
com/googlecode/mp4parser/isoparser/1.0-RC-1/isoparser-1.0-RC-1.jar
|
25
|
+
jdom/jdom/1.0/jdom-1.0.jar
|
26
|
+
org/apache/pdfbox/jempbox/1.7.0/jempbox-1.7.0.jar
|
27
|
+
com/googlecode/juniversalchardet/juniversalchardet/1.0.3/juniversalchardet-1.0.3.jar
|
28
|
+
com/drewnoakes/metadata-extractor/2.4.0-beta-1/metadata-extractor-2.4.0-beta-1.jar
|
29
|
+
edu/ucar/netcdf/4.2-min/netcdf-4.2-min.jar
|
30
|
+
org/apache/pdfbox/pdfbox/1.7.0/pdfbox-1.7.0.jar
|
31
|
+
org/apache/poi/poi/3.8/poi-3.8.jar
|
32
|
+
org/apache/poi/poi-ooxml/3.8/poi-ooxml-3.8.jar
|
33
|
+
org/apache/poi/poi-ooxml-schemas/3.8/poi-ooxml-schemas-3.8.jar
|
34
|
+
org/apache/poi/poi-scratchpad/3.8/poi-scratchpad-3.8.jar
|
35
|
+
rome/rome/0.9/rome-0.9.jar
|
36
|
+
org/ccil/cowan/tagsoup/tagsoup/1.2.1/tagsoup-1.2.1.jar
|
37
|
+
org/apache/tika/tika-core/1.2/tika-core-1.2.jar
|
38
|
+
org/apache/tika/tika-parsers/1.2/tika-parsers-1.2.jar
|
39
|
+
org/gagravarr/vorbis-java-core/0.1/vorbis-java-core-0.1.jar
|
40
|
+
org/gagravarr/vorbis-java-tika/0.1/vorbis-java-tika-0.1.jar
|
41
|
+
xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar
|
42
|
+
org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar
|
43
|
+
org/tukaani/xz/1.0/xz-1.0.jar
|
44
|
+
org/aspectj/aspectjrt/1.8.5/aspectjrt-1.8.5.jar
|
45
|
+
)
|
46
|
+
|
10
47
|
desc 'Configure jetty with full-text indexing'
|
11
48
|
task config: :download_jars do
|
12
49
|
Rake::Task['jetty:config'].invoke
|
@@ -15,49 +52,29 @@ namespace :sufia do
|
|
15
52
|
desc 'Download Solr full-text extraction jars'
|
16
53
|
task :download_jars do
|
17
54
|
puts "Downloading full-text jars from maven.org ..."
|
18
|
-
url_prefix = 'http://search.maven.org/remotecontent?filepath='
|
19
55
|
fulltext_dir = 'jetty/solr/lib/contrib/extraction/lib'
|
20
|
-
jars = %w(
|
21
|
-
org/apache/james/apache-mime4j-core/0.7.2/apache-mime4j-core-0.7.2.jar
|
22
|
-
org/apache/james/apache-mime4j-dom/0.7.2/apache-mime4j-dom-0.7.2.jar
|
23
|
-
org/apache/solr/solr-cell/4.0.0/solr-cell-4.0.0.jar
|
24
|
-
org/bouncycastle/bcmail-jdk15/1.45/bcmail-jdk15-1.45.jar
|
25
|
-
org/bouncycastle/bcprov-jdk15/1.45/bcprov-jdk15-1.45.jar
|
26
|
-
de/l3s/boilerpipe/boilerpipe/1.1.0/boilerpipe-1.1.0.jar
|
27
|
-
org/apache/commons/commons-compress/1.4.1/commons-compress-1.4.1.jar
|
28
|
-
dom4j/dom4j/1.6.1/dom4j-1.6.1.jar
|
29
|
-
org/apache/pdfbox/fontbox/1.7.0/fontbox-1.7.0.jar
|
30
|
-
com/ibm/icu/icu4j/49.1/icu4j-49.1.jar
|
31
|
-
com/googlecode/mp4parser/isoparser/1.0-RC-1/isoparser-1.0-RC-1.jar
|
32
|
-
jdom/jdom/1.0/jdom-1.0.jar
|
33
|
-
org/apache/pdfbox/jempbox/1.7.0/jempbox-1.7.0.jar
|
34
|
-
com/googlecode/juniversalchardet/juniversalchardet/1.0.3/juniversalchardet-1.0.3.jar
|
35
|
-
com/drewnoakes/metadata-extractor/2.4.0-beta-1/metadata-extractor-2.4.0-beta-1.jar
|
36
|
-
edu/ucar/netcdf/4.2-min/netcdf-4.2-min.jar
|
37
|
-
org/apache/pdfbox/pdfbox/1.7.0/pdfbox-1.7.0.jar
|
38
|
-
org/apache/poi/poi/3.8/poi-3.8.jar
|
39
|
-
org/apache/poi/poi-ooxml/3.8/poi-ooxml-3.8.jar
|
40
|
-
org/apache/poi/poi-ooxml-schemas/3.8/poi-ooxml-schemas-3.8.jar
|
41
|
-
org/apache/poi/poi-scratchpad/3.8/poi-scratchpad-3.8.jar
|
42
|
-
rome/rome/0.9/rome-0.9.jar
|
43
|
-
org/ccil/cowan/tagsoup/tagsoup/1.2.1/tagsoup-1.2.1.jar
|
44
|
-
org/apache/tika/tika-core/1.2/tika-core-1.2.jar
|
45
|
-
org/apache/tika/tika-parsers/1.2/tika-parsers-1.2.jar
|
46
|
-
org/gagravarr/vorbis-java-core/0.1/vorbis-java-core-0.1.jar
|
47
|
-
org/gagravarr/vorbis-java-tika/0.1/vorbis-java-tika-0.1.jar
|
48
|
-
xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar
|
49
|
-
org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar
|
50
|
-
org/tukaani/xz/1.0/xz-1.0.jar
|
51
|
-
)
|
52
56
|
FileUtils.mkdir_p(fulltext_dir) unless File.directory?(fulltext_dir)
|
53
57
|
Dir.chdir(fulltext_dir) do
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
puts "Fetching #{url}" unless File.exists?(jarfile)
|
58
|
-
system "wget --quiet --no-clobber #{url} -O #{jarfile}"
|
58
|
+
FULLTEXT_JARS.each do |jar|
|
59
|
+
destination = jar.split('/').last
|
60
|
+
download_from_maven(jar, destination) unless File.exists?(destination)
|
59
61
|
end
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
66
|
+
|
67
|
+
def download_from_maven url, dst
|
68
|
+
full_url = '/remotecontent?filepath=' + url
|
69
|
+
file = File.open(dst, "w")
|
70
|
+
Net::HTTP.start("search.maven.org") do |http|
|
71
|
+
puts "Fetching #{full_url}"
|
72
|
+
begin
|
73
|
+
http.request_get(full_url) do |resp|
|
74
|
+
resp.read_body { |segment| file.write(segment) }
|
75
|
+
end
|
76
|
+
ensure
|
77
|
+
file.close
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/sufia-models.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_dependency "hydra-head", "~> 9.0"
|
33
33
|
spec.add_dependency "active-fedora", "~> 9.0"
|
34
|
-
spec.add_dependency "hydra-collections", "
|
34
|
+
spec.add_dependency "hydra-collections", [">= 5.0.2", "< 6.0"]
|
35
35
|
spec.add_dependency 'hydra-derivatives', '~> 1.0'
|
36
36
|
spec.add_dependency 'nest', '~> 1.1'
|
37
37
|
spec.add_dependency 'resque', '~> 1.23'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sufia-models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,16 +98,22 @@ dependencies:
|
|
98
98
|
name: hydra-collections
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 5.0.2
|
104
|
+
- - "<"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '6.0'
|
104
107
|
type: :runtime
|
105
108
|
prerelease: false
|
106
109
|
version_requirements: !ruby/object:Gem::Requirement
|
107
110
|
requirements:
|
108
|
-
- - "
|
111
|
+
- - ">="
|
109
112
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
113
|
+
version: 5.0.2
|
114
|
+
- - "<"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '6.0'
|
111
117
|
- !ruby/object:Gem::Dependency
|
112
118
|
name: hydra-derivatives
|
113
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -309,6 +315,7 @@ files:
|
|
309
315
|
- README.md
|
310
316
|
- Rakefile
|
311
317
|
- app/actors/sufia/generic_file/actor.rb
|
318
|
+
- app/jobs/active_fedora_id_based_job.rb
|
312
319
|
- app/jobs/active_fedora_pid_based_job.rb
|
313
320
|
- app/jobs/audit_job.rb
|
314
321
|
- app/jobs/batch_update_job.rb
|
@@ -401,6 +408,8 @@ files:
|
|
401
408
|
- lib/generators/sufia/models/templates/migrations/add_linkedin_to_users.rb
|
402
409
|
- lib/generators/sufia/models/templates/migrations/add_orcid_to_users.rb
|
403
410
|
- lib/generators/sufia/models/templates/migrations/add_social_to_users.rb
|
411
|
+
- lib/generators/sufia/models/templates/migrations/change_audit_log_pid_to_generic_file_id.rb
|
412
|
+
- lib/generators/sufia/models/templates/migrations/change_proxy_deposit_request_pid_to_generic_file_id.rb
|
404
413
|
- lib/generators/sufia/models/templates/migrations/create_checksum_audit_logs.rb
|
405
414
|
- lib/generators/sufia/models/templates/migrations/create_content_blocks.rb
|
406
415
|
- lib/generators/sufia/models/templates/migrations/create_featured_works.rb
|
@@ -416,6 +425,7 @@ files:
|
|
416
425
|
- lib/generators/sufia/models/templates/migrations/create_version_committers.rb
|
417
426
|
- lib/generators/sufia/models/update_content_blocks_generator.rb
|
418
427
|
- lib/generators/sufia/models/upgrade400_generator.rb
|
428
|
+
- lib/generators/sufia/models/upgrade600_generator.rb
|
419
429
|
- lib/generators/sufia/models/usagestats_generator.rb
|
420
430
|
- lib/generators/sufia/models/user_stats_generator.rb
|
421
431
|
- lib/sufia/messages.rb
|
@@ -434,6 +444,8 @@ files:
|
|
434
444
|
- lib/sufia/permissions.rb
|
435
445
|
- lib/sufia/permissions/readable.rb
|
436
446
|
- lib/sufia/permissions/writable.rb
|
447
|
+
- lib/tasks/batch_cleanup.rake
|
448
|
+
- lib/tasks/migrate.rake
|
437
449
|
- lib/tasks/resque.rake
|
438
450
|
- lib/tasks/stats_tasks.rake
|
439
451
|
- lib/tasks/sufia-models_tasks.rake
|
@@ -453,12 +465,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
453
465
|
version: '0'
|
454
466
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
455
467
|
requirements:
|
456
|
-
- - "
|
468
|
+
- - ">="
|
457
469
|
- !ruby/object:Gem::Version
|
458
|
-
version:
|
470
|
+
version: '0'
|
459
471
|
requirements: []
|
460
472
|
rubyforge_project:
|
461
|
-
rubygems_version: 2.4.
|
473
|
+
rubygems_version: 2.4.6
|
462
474
|
signing_key:
|
463
475
|
specification_version: 4
|
464
476
|
summary: Models and services for sufia
|