sufia 0.0.1.pre2 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -5
- data/README.md +44 -12
- data/app/assets/javascripts/{scholarsphere.js → sufia.js} +0 -0
- data/app/assets/stylesheets/{scholarsphere.css → sufia.css} +0 -0
- data/app/controllers/batch_controller.rb +2 -3
- data/app/controllers/batch_edits_controller.rb +4 -4
- data/app/controllers/dashboard_controller.rb +5 -3
- data/app/controllers/generic_files_controller.rb +77 -41
- data/app/controllers/users_controller.rb +9 -21
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
- data/app/helpers/sufia_helper.rb +23 -2
- data/app/models/datastreams/file_content_datastream.rb +17 -9
- data/app/models/generic_file.rb +1 -809
- data/app/views/_add_assets_links.html.erb +1 -1
- data/app/views/_user_util_links.html.erb +2 -2
- data/app/views/batch/_metadata.html.erb +16 -16
- data/app/views/batch/edit.html.erb +16 -10
- data/app/views/batch_edits/_metadata.html.erb +16 -16
- data/app/views/catalog/_index_partials/_list_files.html.erb +2 -2
- data/app/views/catalog/index.html.erb +5 -0
- data/app/views/dashboard/_facet_limit.html.erb +1 -1
- data/app/views/dashboard/_facet_pagination.html.erb +4 -4
- data/app/views/dashboard/_facet_selected.html.erb +1 -1
- data/app/views/dashboard/_index_partials/_list_files.html.erb +8 -8
- data/app/views/dashboard/_search_form.html.erb +1 -1
- data/app/views/dashboard/_sort_and_per_page.html.erb +1 -1
- data/app/views/dashboard/index.html.erb +0 -1
- data/app/views/generic_files/_breadcrumbs.html.erb +1 -1
- data/app/views/generic_files/_descriptions.html.erb +3 -3
- data/app/views/generic_files/_field_form +3 -3
- data/app/views/generic_files/_media_display.html.erb +5 -4
- data/app/views/generic_files/_permission.html.erb +5 -5
- data/app/views/generic_files/_versioning.html.erb +1 -1
- data/app/views/generic_files/edit.html.erb +2 -2
- data/app/views/generic_files/show.html.erb +3 -3
- data/app/views/static/versions.html.erb +1 -1
- data/app/views/users/edit.html.erb +5 -3
- data/app/views/users/index.html.erb +3 -3
- data/app/views/users/show.html.erb +6 -6
- data/config/jetty.yml +6 -0
- data/config/routes.rb +8 -4
- data/features/browse_dashboard_files.feature +11 -1
- data/features/browse_files.feature +6 -5
- data/features/contact_form.feature +4 -0
- data/features/display_dashboard.feature +6 -3
- data/features/ingest_upload_files.feature +2 -2
- data/features/step_definitions/fixture_steps.rb +6 -5
- data/features/step_definitions/scholarsphere.rb +24 -1
- data/features/step_definitions/user_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -1
- data/features/support/env.rb +26 -0
- data/features/users.feature +18 -0
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/generators/sufia/sufia_generator.rb +18 -2
- data/lib/generators/sufia/templates/catalog_controller.rb +3 -4
- data/{spec/support → lib/generators/sufia/templates}/config/redis.yml +0 -0
- data/lib/generators/sufia/templates/config/sufia.rb +68 -0
- data/lib/generators/sufia/templates/migrations/add_ldap_attrs_to_user.rb +41 -0
- data/lib/kaminari/helpers/tag.rb +11 -0
- data/lib/sufia.rb +30 -7
- data/lib/sufia/controller.rb +1 -5
- data/lib/sufia/generic_file.rb +200 -0
- data/lib/sufia/generic_file/audit.rb +119 -0
- data/lib/sufia/generic_file/characterization.rb +82 -0
- data/lib/sufia/generic_file/export.rb +339 -0
- data/lib/sufia/generic_file/permissions.rb +64 -0
- data/lib/sufia/generic_file/thumbnail.rb +68 -0
- data/{app/models → lib/sufia/jobs}/audit_job.rb +13 -3
- data/lib/sufia/jobs/batch_update_job.rb +86 -0
- data/lib/sufia/jobs/characterize_job.rb +35 -0
- data/{app/models → lib/sufia/jobs}/content_delete_event_job.rb +3 -1
- data/{app/models → lib/sufia/jobs}/content_deposit_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/content_new_version_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/content_restored_version_event_job.rb +8 -0
- data/{app/models → lib/sufia/jobs}/content_update_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/event_job.rb +7 -3
- data/{app/models → lib/sufia/jobs}/resolrize_job.rb +4 -2
- data/lib/sufia/jobs/transcode_video_job.rb +79 -0
- data/{app/models → lib/sufia/jobs}/unzip_job.rb +11 -3
- data/{app/models → lib/sufia/jobs}/user_edit_profile_event_job.rb +6 -0
- data/{app/models → lib/sufia/jobs}/user_follow_event_job.rb +9 -4
- data/{app/models → lib/sufia/jobs}/user_unfollow_event_job.rb +6 -0
- data/lib/sufia/queue/resque.rb +30 -0
- data/lib/sufia/role_mapper.rb +0 -1
- data/{app/models/characterize_job.rb → lib/sufia/solr_document_behavior.rb} +6 -7
- data/lib/sufia/user.rb +3 -3
- data/lib/sufia/version.rb +1 -1
- data/lib/tasks/fixtures.rake +38 -38
- data/lib/tasks/resque.rake +1 -0
- data/solr_conf/conf/solrconfig.xml +32 -1615
- data/solr_conf/solr.xml +1 -1
- data/spec/active_fedora/unsaved_digital_object_spec.rb +4 -4
- data/spec/config/host_to_vhost_spec.rb +4 -4
- data/spec/controllers/authorities_controller_spec.rb +1 -1
- data/spec/controllers/batch_controller_spec.rb +12 -10
- data/spec/controllers/catalog_controller_spec.rb +13 -13
- data/spec/controllers/dashboard_controller_spec.rb +15 -15
- data/spec/controllers/downloads_controller_spec.rb +14 -14
- data/spec/controllers/generic_files_controller_spec.rb +88 -46
- data/spec/controllers/mailbox_controller_spec.rb +2 -2
- data/spec/controllers/sessions_controller_spec.rb +1 -1
- data/spec/controllers/single_use_link_controller_spec.rb +18 -18
- data/spec/controllers/users_controller_spec.rb +47 -31
- data/spec/fixtures/countdown.avi +0 -0
- data/spec/fixtures/sufia/.gitignore +1 -0
- data/spec/fixtures/{scholarsphere → sufia}/bg_header.jpg +0 -0
- data/spec/fixtures/sufia/sufia_test1.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere → sufia}/sufia_test1.foxml.erb +2 -2
- data/spec/fixtures/{scholarsphere/scholarsphere_test1.txt → sufia/sufia_test1.txt} +0 -0
- data/spec/fixtures/sufia/sufia_test2.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test2.docx → sufia/sufia_test2.docx} +0 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test2.foxml.erb → sufia/sufia_test2.foxml.erb} +6 -6
- data/spec/fixtures/sufia/sufia_test3.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test3.foxml.erb → sufia/sufia_test3.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test3.xls → sufia/sufia_test3.xls} +0 -0
- data/spec/fixtures/sufia/sufia_test4.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test4.foxml.erb → sufia/sufia_test4.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test4.pdf → sufia/sufia_test4.pdf} +0 -0
- data/spec/fixtures/sufia/sufia_test5.descMeta.txt +19 -0
- data/spec/fixtures/{scholarsphere → sufia}/sufia_test5.foxml.erb +3 -3
- data/spec/fixtures/{scholarsphere/scholarsphere_test5.mp3 → sufia/sufia_test5.mp3} +0 -0
- data/spec/fixtures/sufia/sufia_test5.txt +1 -0
- data/spec/fixtures/sufia/sufia_test6.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test6.foxml.erb → sufia/sufia_test6.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test6.jp2 → sufia/sufia_test6.jp2} +0 -0
- data/spec/fixtures/sufia/sufia_test6.txt +1 -0
- data/spec/fixtures/sufia_generic_stub.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere_generic_stub.foxml.erb → sufia_generic_stub.foxml.erb} +3 -3
- data/spec/fixtures/sufia_generic_stub.txt +1 -0
- data/spec/lib/sufia/role_mapper_spec.rb +1 -1
- data/spec/models/audit_job_spec.rb +8 -11
- data/spec/models/batch_spec.rb +5 -5
- data/spec/models/batch_update_job_spec.rb +18 -15
- data/spec/models/checksum_audit_log_spec.rb +6 -19
- data/spec/models/event_jobs_spec.rb +23 -23
- data/spec/models/file_content_datastream_spec.rb +14 -14
- data/spec/models/fits_datastream_spec.rb +1 -1
- data/spec/models/generic_file_spec.rb +88 -41
- data/spec/models/single_use_link_spec.rb +3 -3
- data/spec/models/transcode_video_job_spec.rb +30 -0
- data/spec/models/unzip_job_spec.rb +6 -4
- data/spec/rake/{scholarsphere_fixtures_spec.rb → sufia_fixtures_spec.rb} +16 -16
- data/spec/routing/route_spec.rb +4 -8
- data/spec/spec_helper.rb +0 -7
- data/spec/support/Gemfile +4 -2
- data/spec/support/fedora_conf/fedora.fcfg +953 -0
- data/spec/support/lib/generators/test_app_generator.rb +1 -11
- data/sufia.gemspec +5 -3
- data/tasks/{scholarsphere-db.rake → sufia-db.rake} +1 -1
- data/tasks/{scholarsphere-dev.rake → sufia-dev.rake} +7 -3
- data/tasks/{scholarsphere-fixtures.rake → sufia-fixtures.rake} +43 -43
- data/tasks/{scholarsphere.rake → sufia.rake} +2 -2
- metadata +126 -95
- data/app/models/batch_update_job.rb +0 -82
- data/app/models/solr_document.rb +0 -50
- data/lib/sufia/permissions.rb +0 -43
- data/spec/fixtures/scholarsphere/scholarsphere_test1.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test2.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test3.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test4.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test5.descMeta.txt +0 -19
- data/spec/fixtures/scholarsphere/scholarsphere_test5.txt +0 -1
- data/spec/fixtures/scholarsphere/scholarsphere_test6.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test6.txt +0 -1
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.foxml.erb +0 -79
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.txt +0 -1
- data/spec/fixtures/scholarsphere_generic_stub.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere_generic_stub.txt +0 -1
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'datastreams/paranoid_rights_datastream'
|
2
|
+
module Sufia
|
3
|
+
module GenericFile
|
4
|
+
module Permissions
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
#we're overriding the permissions= method which is in RightsMetadata
|
7
|
+
include Hydra::ModelMixins::RightsMetadata
|
8
|
+
included do
|
9
|
+
has_metadata :name => "rightsMetadata", :type => ParanoidRightsDatastream
|
10
|
+
validate :paranoid_permissions
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_visibility(visibility)
|
14
|
+
# only set explicit permissions
|
15
|
+
case visibility
|
16
|
+
when "open"
|
17
|
+
self.datastreams["rightsMetadata"].permissions({:group=>"public"}, "read")
|
18
|
+
when "psu"
|
19
|
+
self.datastreams["rightsMetadata"].permissions({:group=>"registered"}, "read")
|
20
|
+
self.datastreams["rightsMetadata"].permissions({:group=>"public"}, "none")
|
21
|
+
when "restricted"
|
22
|
+
self.datastreams["rightsMetadata"].permissions({:group=>"registered"}, "none")
|
23
|
+
self.datastreams["rightsMetadata"].permissions({:group=>"public"}, "none")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def paranoid_permissions
|
29
|
+
# let the rightsMetadata ds make this determination
|
30
|
+
# - the object instance is passed in for easier access to the props ds
|
31
|
+
rightsMetadata.validate(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
## Updates those permissions that are provided to it. Does not replace any permissions unless they are provided
|
35
|
+
def permissions=(params)
|
36
|
+
perm_hash = permission_hash
|
37
|
+
params[:new_user_name].each { |name, access| perm_hash['person'][name] = access } if params[:new_user_name].present?
|
38
|
+
params[:new_group_name].each { |name, access| perm_hash['group'][name] = access } if params[:new_group_name].present?
|
39
|
+
|
40
|
+
params[:user].each { |name, access| perm_hash['person'][name] = access} if params[:user]
|
41
|
+
params[:group].each { |name, access| perm_hash['group'][name] = access} if params[:group]
|
42
|
+
rightsMetadata.update_permissions(perm_hash)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def permission_hash
|
48
|
+
old_perms = self.permissions
|
49
|
+
user_perms = {}
|
50
|
+
old_perms.select{|r| r[:type] == 'user'}.each do |r|
|
51
|
+
user_perms[r[:name]] = r[:access]
|
52
|
+
end
|
53
|
+
user_perms
|
54
|
+
group_perms = {}
|
55
|
+
old_perms.select{|r| r[:type] == 'group'}.each do |r|
|
56
|
+
group_perms[r[:name]] = r[:access]
|
57
|
+
end
|
58
|
+
{'person'=>user_perms, 'group'=>group_perms}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Sufia
|
2
|
+
module GenericFile
|
3
|
+
module Thumbnail
|
4
|
+
# Create thumbnail requires that the characterization has already been run (so mime_type, width and height is available)
|
5
|
+
# and that the object is already has a pid set
|
6
|
+
def create_thumbnail
|
7
|
+
return if self.content.content.nil?
|
8
|
+
if pdf?
|
9
|
+
create_pdf_thumbnail
|
10
|
+
elsif image?
|
11
|
+
create_image_thumbnail
|
12
|
+
# elsif video?
|
13
|
+
# create_video_thumbnail
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_pdf_thumbnail
|
18
|
+
retryCnt = 0
|
19
|
+
stat = false;
|
20
|
+
for retryCnt in 1..3
|
21
|
+
begin
|
22
|
+
pdf = Magick::ImageList.new
|
23
|
+
pdf.from_blob(content.content)
|
24
|
+
first = pdf.to_a[0]
|
25
|
+
first.format = "PNG"
|
26
|
+
thumb = first.scale(338, 493)
|
27
|
+
self.thumbnail.content = thumb.to_blob { self.format = "PNG" }
|
28
|
+
#logger.debug "Has the content changed before saving? #{self.content.changed?}"
|
29
|
+
self.terms_of_service = '1'
|
30
|
+
stat = self.save
|
31
|
+
break
|
32
|
+
rescue => e
|
33
|
+
logger.warn "Rescued an error #{e.inspect} retry count = #{retryCnt}"
|
34
|
+
sleep 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return stat
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_image_thumbnail
|
41
|
+
img = Magick::ImageList.new
|
42
|
+
img.from_blob(content.content)
|
43
|
+
# horizontal img
|
44
|
+
height = self.height.first.to_i
|
45
|
+
width = self.width.first.to_i
|
46
|
+
scale = height / width
|
47
|
+
if width > height
|
48
|
+
if width > 150 and height > 105
|
49
|
+
thumb = img.scale(150, height/scale)
|
50
|
+
else
|
51
|
+
thumb = img.scale(width, height)
|
52
|
+
end
|
53
|
+
# vertical img
|
54
|
+
else
|
55
|
+
if width > 150 and height > 200
|
56
|
+
thumb = img.scale(150*scale, 200)
|
57
|
+
else
|
58
|
+
thumb = img.scale(width, height)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
self.thumbnail.content = thumb.to_blob
|
62
|
+
self.terms_of_service = '1'
|
63
|
+
#logger.debug "Has the content before saving? #{self.content.changed?}"
|
64
|
+
self.save
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -13,13 +13,23 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class AuditJob
|
16
|
-
|
16
|
+
def queue_name
|
17
|
+
:audit
|
18
|
+
end
|
17
19
|
|
18
20
|
PASS = 'Passing Audit Run'
|
19
21
|
FAIL = 'Failing Audit Run'
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
+
attr_accessor :generic_file_id, :datastream_id, :version_id
|
24
|
+
|
25
|
+
def initialize(generic_file_id, datastream_id, version_id)
|
26
|
+
self.generic_file_id = generic_file_id
|
27
|
+
self.datastream_id = datastream_id
|
28
|
+
self.version_id = version_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
32
|
+
generic_file = GenericFile.find(generic_file_id)
|
23
33
|
#logger.info "GF is #{generic_file.pid}"
|
24
34
|
if generic_file
|
25
35
|
datastream = generic_file.datastreams[datastream_id]
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright © 2012 The Pennsylvania State University
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
class BatchUpdateJob
|
16
|
+
include Hydra::AccessControlsEnforcement
|
17
|
+
include GenericFileHelper
|
18
|
+
include Rails.application.routes.url_helpers
|
19
|
+
|
20
|
+
def queue_name
|
21
|
+
:batch_update
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :login, :title, :file_attributes, :batch_id, :visibility
|
25
|
+
|
26
|
+
def initialize(login, params)
|
27
|
+
self.login = login
|
28
|
+
self.title = params[:title]
|
29
|
+
self.file_attributes = params[:generic_file]
|
30
|
+
self.visibility = params[:visibility]
|
31
|
+
self.batch_id = params[:id]
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def run
|
36
|
+
batch = Batch.find_or_create(self.batch_id)
|
37
|
+
user = User.find_by_user_key(self.login)
|
38
|
+
@saved = []
|
39
|
+
@denied = []
|
40
|
+
|
41
|
+
batch.generic_files.each do |gf|
|
42
|
+
update_file(gf, user)
|
43
|
+
end
|
44
|
+
batch.update_attributes({status:["Complete"]})
|
45
|
+
|
46
|
+
job_user = User.batchuser()
|
47
|
+
|
48
|
+
message = '<a class="batchid ui-helper-hidden">ss-'+batch.noid+'</a>The file(s) '+ file_list(@saved)+ " have been saved." unless @saved.empty?
|
49
|
+
job_user.send_message(user, message, 'Batch upload complete') unless @saved.empty?
|
50
|
+
|
51
|
+
message = '<a class="batchid ui-helper-hidden">'+batch.noid+'</a>The file(s) '+ file_list(@denied)+" could not be updated. You do not have sufficient privileges to edit it." unless @denied.empty?
|
52
|
+
job_user.send_message(user, message, 'Batch upload permission denied') unless @denied.empty?
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_file(gf, user)
|
57
|
+
unless user.can? :edit, get_permissions_solr_response_for_doc_id(gf.pid)[1]
|
58
|
+
logger.error "User #{user.user_key} DEEEENIED access to #{gf.pid}!"
|
59
|
+
@denied << gf
|
60
|
+
return
|
61
|
+
end
|
62
|
+
gf.title = title[gf.pid] if title[gf.pid] rescue gf.label
|
63
|
+
gf.update_attributes(file_attributes)
|
64
|
+
gf.set_visibility(visibility)
|
65
|
+
|
66
|
+
save_tries = 0
|
67
|
+
begin
|
68
|
+
gf.save
|
69
|
+
rescue RSolr::Error::Http => error
|
70
|
+
save_tries += 1
|
71
|
+
logger.warn "BatchUpdateJob caught RSOLR error on #{gf.pid}: #{error.inspect}"
|
72
|
+
# fail for good if the tries is greater than 3
|
73
|
+
rescue_action_without_handler(error) if save_tries >=3
|
74
|
+
sleep 0.01
|
75
|
+
retry
|
76
|
+
end #
|
77
|
+
Sufia.queue.push(ContentUpdateEventJob.new(gf.pid, login))
|
78
|
+
@saved << gf
|
79
|
+
end
|
80
|
+
|
81
|
+
def file_list ( files)
|
82
|
+
return files.map {|gf| '<a href="'+Sufia::Engine.routes.url_helpers.generic_files_path+'/'+gf.noid+'">'+display_title(gf)+'</a>'}.join(', ')
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright © 2012 The Pennsylvania State University
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
class CharacterizeJob
|
16
|
+
|
17
|
+
def queue_name
|
18
|
+
:characterize
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :generic_file_id
|
22
|
+
|
23
|
+
def initialize(generic_file_id)
|
24
|
+
self.generic_file_id = generic_file_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
generic_file = GenericFile.find(generic_file_id)
|
29
|
+
generic_file.characterize
|
30
|
+
generic_file.create_thumbnail
|
31
|
+
if generic_file.video?
|
32
|
+
Sufia.queue.push(TranscodeVideoJob.new(generic_file_id, 'content'))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -13,7 +13,9 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class ContentDeleteEventJob < EventJob
|
16
|
-
|
16
|
+
|
17
|
+
|
18
|
+
def run
|
17
19
|
action = "User #{link_to_profile depositor_id} has deleted file '#{generic_file_id}'"
|
18
20
|
timestamp = Time.now.to_i
|
19
21
|
depositor = User.find_by_user_key(depositor_id)
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class ContentDepositEventJob < EventJob
|
16
|
-
def
|
16
|
+
def run
|
17
17
|
gf = GenericFile.find(generic_file_id)
|
18
18
|
action = "User #{link_to_profile depositor_id} has deposited #{link_to gf.title.first, Sufia::Engine.routes.url_helpers.generic_file_path(gf.noid)}"
|
19
19
|
timestamp = Time.now.to_i
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class ContentNewVersionEventJob < EventJob
|
16
|
-
def
|
16
|
+
def run
|
17
17
|
gf = GenericFile.find(generic_file_id)
|
18
18
|
action = "User #{link_to_profile depositor_id} has added a new version of #{link_to gf.title.first, Sufia::Engine.routes.url_helpers.generic_file_path(gf.noid)}"
|
19
19
|
timestamp = Time.now.to_i
|
@@ -13,7 +13,15 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class ContentRestoredVersionEventJob < EventJob
|
16
|
+
attr_accessor :revision_id
|
17
|
+
|
16
18
|
def initialize(generic_file_id, depositor_id, revision_id)
|
19
|
+
self.generic_file_id = generic_file_id
|
20
|
+
self.depositor_id = depositor_id
|
21
|
+
self.revision_id = revision_id
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
17
25
|
gf = GenericFile.find(generic_file_id)
|
18
26
|
action = "User #{link_to_profile depositor_id} has restored a version '#{revision_id}' of #{link_to gf.title.first, Sufia::Engine.routes.url_helpers.generic_file_path(gf.noid)}"
|
19
27
|
timestamp = Time.now.to_i
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
class ContentUpdateEventJob < EventJob
|
16
|
-
def
|
16
|
+
def run
|
17
17
|
gf = GenericFile.find(generic_file_id)
|
18
18
|
action = "User #{link_to_profile depositor_id} has updated #{link_to gf.title.first, Sufia::Engine.routes.url_helpers.generic_file_path(gf.noid)}"
|
19
19
|
timestamp = Time.now.to_i
|
@@ -19,11 +19,15 @@ class EventJob
|
|
19
19
|
include Hydra::AccessControlsEnforcement
|
20
20
|
include SufiaHelper
|
21
21
|
|
22
|
-
def
|
22
|
+
def queue_name
|
23
23
|
:event
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
attr_accessor :generic_file_id, :depositor_id
|
27
|
+
|
28
|
+
def initialize(generic_file_id, depositor_id)
|
29
|
+
self.generic_file_id = generic_file_id
|
30
|
+
self.depositor_id = depositor_id
|
28
31
|
end
|
32
|
+
|
29
33
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Created by: Justin Coyne
|
2
|
+
# 13 Dec 2012
|
3
|
+
# An asyncronous job for transcoding video files using FFMpeg
|
4
|
+
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
class TranscodeVideoJob
|
8
|
+
extend Open3
|
9
|
+
def queue_name
|
10
|
+
:video
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :generic_file_id, :datastream_in
|
14
|
+
|
15
|
+
def initialize(generic_file_id, datastream_in)
|
16
|
+
self.generic_file_id = generic_file_id
|
17
|
+
self.datastream_in = datastream_in
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
@generic_file = GenericFile.find(generic_file_id)
|
22
|
+
@datastream = @generic_file.datastreams[datastream_in]
|
23
|
+
if @datastream
|
24
|
+
encode_mp4()
|
25
|
+
encode_webm()
|
26
|
+
@generic_file.save!
|
27
|
+
else
|
28
|
+
logger.warn "No datastream for transcoding!!!!! pid: #{generic_file_id} dsid: #{datastream_in}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def encode_webm
|
33
|
+
opts = "#{size_attributes} -b:v 345k -acodec libvorbis #{audio_attributes}"
|
34
|
+
encode_datastream('webm', 'video/webm', opts)
|
35
|
+
end
|
36
|
+
|
37
|
+
def encode_mp4
|
38
|
+
opts = "#{size_attributes} -b:v 345k -vcodec libx264 -acodec libfaac #{audio_attributes} "
|
39
|
+
encode_datastream('mp4', 'video/mp4', opts)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def size_attributes
|
44
|
+
"-s 320x240"
|
45
|
+
end
|
46
|
+
|
47
|
+
def audio_attributes
|
48
|
+
"-ac 2 -ab 96k -ar 44100"
|
49
|
+
end
|
50
|
+
|
51
|
+
def encode_datastream(dest_dsid, mime_type, options)
|
52
|
+
file_suffix = dest_dsid
|
53
|
+
out_file = nil
|
54
|
+
output_file = Dir::Tmpname.create('sufia'){} + ".#{file_suffix}"
|
55
|
+
@datastream.to_tempfile do |f|
|
56
|
+
self.class.encode(f.path, options, output_file)
|
57
|
+
end
|
58
|
+
out_file = File.open(output_file, "rb")
|
59
|
+
@generic_file.add_file_datastream(out_file.read, :dsid=>dest_dsid, :mimeType=>mime_type)
|
60
|
+
File.unlink(output_file)
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO tmp file for output
|
64
|
+
def self.encode(path, options, output_file)
|
65
|
+
command = "#{ffmpeg_path} -y -i #{path} #{options} #{output_file}"
|
66
|
+
stdin, stdout, stderr, wait_thr = popen3(command)
|
67
|
+
stdin.close
|
68
|
+
out = stdout.read
|
69
|
+
stdout.close
|
70
|
+
err = stderr.read
|
71
|
+
stderr.close
|
72
|
+
raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.ffmpeg_path
|
76
|
+
Sufia::Engine.config.ffmpeg_path
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|