sufia-models 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da8e62620ca985d9111fbcf1486646a1fbf8aabb
4
- data.tar.gz: 83104eb983f38d1b77e9b6347452e1630dc28f4a
3
+ metadata.gz: 9476084b14b4f2ae7d223df7c2fa01adfe908d2b
4
+ data.tar.gz: 13905aa01d70e375b30ab10ab9b1976b64370076
5
5
  SHA512:
6
- metadata.gz: c446b6fbccabcf456e201e5680c09086c1b15f3fc2305a676ee30851389f822cfc011c5c718d94c8ea6b1b8d407a0c29c00f679dc3a2dd4e31dcd89f29672951
7
- data.tar.gz: e825707338bfdd0091187f82269f9834edda62ad34227dd21e27aa95d5c1500203fea6a724fbba634535f6444fc21b9c621fe0706e2cc23428948dd3d6533219
6
+ metadata.gz: 12b4d9d871804e7627179916e96e9b811589db27bdfdec2b826800e5b0cacb736d13994081e31118f06c3d93a4a4a4a7a86fab4dc1c686c2e8ebb76ff9a8b0b8
7
+ data.tar.gz: e46ccc9c4efc212f32cefea6dad8bc97cb90bd7b057f6c335371042c76f46af36bcb9d27ca59bad3a3365c58b31e58c4c46b1f1fc3154a3dbc3516acae02af2d
@@ -1,18 +1,4 @@
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
1
  class FileContentDatastream < ActiveFedora::Datastream
16
- include Sufia::FileContent::ExtractMetadata
2
+ include Hydra::Derivatives::ExtractMetadata
17
3
  include Sufia::FileContent::Versions
18
4
  end
@@ -1,5 +1,3 @@
1
- require 'active_resource'
2
-
3
1
  class GeoNamesResource < ActiveResource::Base
4
2
  self.site = "http://api.geonames.org/"
5
3
  self.element_name = "searchJSON"
data/lib/sufia/models.rb CHANGED
@@ -5,7 +5,7 @@ require 'nest'
5
5
  require 'mailboxer'
6
6
  require 'acts_as_follower'
7
7
  require 'paperclip'
8
- require 'RMagick'
8
+ require "active_resource" # used by GenericFile to catch errors & by GeoNamesResource
9
9
  begin
10
10
  # activerecord-import 0.3.1 does not support rails 4, so we don't require it.
11
11
  require 'activerecord-import'
@@ -22,6 +22,7 @@ module Sufia
22
22
  config.fits_path = "fits.sh"
23
23
  config.enable_contact_form_delivery = false
24
24
  config.dropbox_api_key = nil
25
+ config.enable_local_ingest = nil
25
26
  config.queue = Sufia::Resque::Queue
26
27
 
27
28
  config.autoload_paths += %W(
@@ -40,22 +41,32 @@ module Sufia
40
41
  end
41
42
 
42
43
  initializer 'requires' do
44
+ require 'hydra/derivatives'
43
45
  require 'sufia/models/model_methods'
44
46
  require 'sufia/models/noid'
45
47
  require 'sufia/models/file_content'
46
- require 'sufia/models/file_content/extract_metadata'
47
48
  require 'sufia/models/file_content/versions'
48
49
  require 'sufia/models/generic_file/actions'
49
50
  require 'sufia/models/generic_file/audit'
50
51
  require 'sufia/models/generic_file/characterization'
52
+ require 'sufia/models/generic_file/derivatives'
51
53
  require 'sufia/models/generic_file/export'
54
+ require 'sufia/models/generic_file/mime_types'
52
55
  require 'sufia/models/generic_file/permissions'
53
56
  require 'sufia/models/generic_file/thumbnail'
54
57
  require 'sufia/models/generic_file'
55
58
  require 'sufia/models/user'
59
+ require 'sufia/models/user_local_directory_behavior'
56
60
  require 'sufia/models/id_service'
57
61
  require 'sufia/models/solr_document_behavior'
58
62
  end
63
+
64
+ initializer 'configure' do
65
+ Hydra::Derivatives.ffmpeg_path = Sufia.config.ffmpeg_path
66
+ Hydra::Derivatives.temp_file_base = Sufia.config.temp_file_base
67
+ Hydra::Derivatives.fits_path = Sufia.config.fits_path
68
+ Hydra::Derivatives.enable_ffmpeg = Sufia.config.enable_ffmpeg
69
+ end
59
70
  end
60
71
  end
61
72
  end
@@ -1,9 +1,6 @@
1
1
  module Sufia
2
2
  module FileContent
3
3
  extend ActiveSupport::Autoload
4
-
5
- autoload :ExtractMetadata, 'sufia/models/file_content/extract_metadata'
6
4
  autoload :Versions, 'sufia/models/file_content/versions'
7
-
8
5
  end
9
6
  end
@@ -2,22 +2,20 @@ module Sufia
2
2
  module GenericFile
3
3
  extend ActiveSupport::Concern
4
4
  extend ActiveSupport::Autoload
5
- autoload :Export
6
- autoload :Thumbnail
7
- autoload :Characterization
8
- autoload :Audit
9
5
  autoload :Actions
10
6
  autoload :Permissions
11
7
  autoload :WebForm, 'sufia/models/generic_file/web_form'
12
8
  autoload :AccessibleAttributes, 'sufia/models/generic_file/accessible_attributes'
13
9
  include Sufia::ModelMethods
14
10
  include Sufia::Noid
11
+ include Sufia::GenericFile::MimeTypes
15
12
  include Sufia::GenericFile::Thumbnail
16
13
  include Sufia::GenericFile::Export
17
14
  include Sufia::GenericFile::Characterization
18
15
  include Sufia::GenericFile::Audit
19
16
  include Sufia::GenericFile::Permissions
20
17
  include Sufia::GenericFile::WebForm
18
+ include Sufia::GenericFile::Derivatives
21
19
 
22
20
  included do
23
21
  has_metadata :name => "descMetadata", :type => GenericFileRdfDatastream
@@ -52,21 +50,19 @@ module Sufia
52
50
  end
53
51
 
54
52
  def pdf?
55
- ['application/pdf'].include? self.mime_type
53
+ self.class.pdf_mime_types.include? self.mime_type
56
54
  end
57
55
 
58
56
  def image?
59
- ['image/png','image/jpeg', 'image/jpg', 'image/jp2', 'image/bmp', 'image/gif'].include? self.mime_type
57
+ self.class.image_mime_types.include? self.mime_type
60
58
  end
61
59
 
62
60
  def video?
63
- ['video/mpeg', 'video/mp4', 'video/webm', 'video/x-msvideo', 'video/avi', 'video/quicktime', 'application/mxf'].include? self.mime_type
61
+ self.class.video_mime_types.include? self.mime_type
64
62
  end
65
63
 
66
64
  def audio?
67
- # audio/x-wave is the mime type that fits 0.6.0 returns for a wav file.
68
- # audio/mpeg is the mime type that fits 0.6.0 returns for an mp3 file.
69
- ['audio/mp3', 'audio/mpeg', 'audio/x-wave', 'audio/x-wav', 'audio/ogg'].include? self.mime_type
65
+ self.class.audio_mime_types.include? self.mime_type
70
66
  end
71
67
 
72
68
  def persistent_url
@@ -3,7 +3,7 @@ module Sufia::GenericFile
3
3
  module Actions
4
4
  def self.create_metadata(generic_file, user, batch_id)
5
5
 
6
- generic_file.apply_depositor_metadata(user.user_key)
6
+ generic_file.apply_depositor_metadata(user)
7
7
  generic_file.date_uploaded = Date.today
8
8
  generic_file.date_modified = Date.today
9
9
  generic_file.creator = user.name
@@ -36,7 +36,7 @@ module Sufia
36
36
  self.characterization.ng_xml = self.content.extract_metadata
37
37
  self.append_metadata
38
38
  self.filename = self.label
39
- save unless self.new_object?
39
+ save
40
40
  end
41
41
 
42
42
  # Populate descMetadata with fields from FITS (e.g. Author from pdfs)
@@ -0,0 +1,31 @@
1
+ module Sufia
2
+ module GenericFile
3
+ module Derivatives
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Hydra::Derivatives
8
+
9
+ makes_derivatives do |obj|
10
+ case obj.mime_type
11
+ when *pdf_mime_types
12
+ obj.transform_datastream :content,
13
+ { :thumbnail => {size: "338x493", datastream: 'thumbnail'} }
14
+ when *audio_mime_types
15
+ obj.transform_datastream :content,
16
+ { :mp3 => {format: 'mp3', datastream: 'mp3'},
17
+ :ogg => {format: 'ogg', datastream: 'ogg'} }, processor: :audio
18
+ when *video_mime_types
19
+ obj.transform_datastream :content,
20
+ { :webm => {format: "webm", datastream: 'webm'},
21
+ :mp4 => {format: "mp4", datastream: 'mp4'} }, processor: :video
22
+ when *image_mime_types
23
+ obj.transform_datastream :content, { :thumbnail => {size: "200x150>", datastream: 'thumbnail'} }
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,27 @@
1
+ module Sufia
2
+ module GenericFile
3
+ module MimeTypes
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def image_mime_types
8
+ ['image/png','image/jpeg', 'image/jpg', 'image/jp2', 'image/bmp', 'image/gif']
9
+ end
10
+
11
+ def pdf_mime_types
12
+ ['application/pdf']
13
+ end
14
+
15
+ def video_mime_types
16
+ ['video/mpeg', 'video/mp4', 'video/webm', 'video/x-msvideo', 'video/avi', 'video/quicktime', 'application/mxf']
17
+ end
18
+
19
+ def audio_mime_types
20
+ # audio/x-wave is the mime type that fits 0.6.0 returns for a wav file.
21
+ # audio/mpeg is the mime type that fits 0.6.0 returns for an mp3 file.
22
+ ['audio/mp3', 'audio/mpeg', 'audio/wav', 'audio/x-wave', 'audio/x-wav', 'audio/ogg']
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,17 +1,18 @@
1
1
  module Sufia
2
2
  module GenericFile
3
3
  module Thumbnail
4
+ extend ActiveSupport::Concern
4
5
  # Create thumbnail requires that the characterization has already been run (so mime_type, width and height is available)
5
6
  # and that the object is already has a pid set
6
7
  def create_thumbnail
7
8
  return unless self.content.has_content?
8
- if pdf?
9
- create_pdf_thumbnail
10
- elsif image?
11
- create_image_thumbnail
12
- elsif video?
9
+
10
+ if video?
13
11
  create_video_thumbnail
12
+ else
13
+ create_derivatives
14
14
  end
15
+ self.save
15
16
  end
16
17
 
17
18
  protected
@@ -29,61 +30,6 @@ module Sufia
29
30
 
30
31
  self.thumbnail.content = File.open(output_file, 'rb').read
31
32
  self.thumbnail.mimeType = 'image/png'
32
- self.save
33
- end
34
-
35
- def create_pdf_thumbnail
36
- retryCnt = 0
37
- stat = false;
38
- for retryCnt in 1..3
39
- begin
40
- pdf = load_image_transformer
41
- first = pdf.to_a[0]
42
- first.format = "PNG"
43
- thumb = first.scale(338, 493)
44
- self.thumbnail.content = thumb.to_blob { self.format = "PNG" }
45
- self.thumbnail.mimeType = 'image/png'
46
- self.save
47
- break
48
- rescue => e
49
- logger.warn "Rescued an error #{e.inspect} retry count = #{retryCnt}"
50
- sleep 1
51
- end
52
- end
53
- return stat
54
- end
55
-
56
- def create_image_thumbnail
57
- self.thumbnail.content = scale_image.to_blob { self.format = "PNG" }
58
- self.thumbnail.mimeType = 'image/png'
59
- #logger.debug "Has the content before saving? #{self.content.changed?}"
60
- self.save
61
- end
62
-
63
- def scale_image
64
- img = load_image_transformer
65
- height = Float(self.height.first.to_i)
66
- width = Float(self.width.first.to_i)
67
- if width > height && width > 150 && height > 105
68
- # horizontal img
69
- scale = 150 / width
70
- img.scale(150, height * scale)
71
- elsif height >= width && width > 150 && height > 200
72
- # vertical or square
73
- scale = 200 / height
74
- img.scale(width*scale, 200)
75
- else
76
- # Too small to worry about resizing
77
- img
78
- end
79
- end
80
-
81
- # Override this method if you want a different transformer, or need to load the
82
- # raw image from a different source (e.g. external datastream)
83
- def load_image_transformer
84
- xformer = Magick::ImageList.new
85
- xformer.from_blob(content.content)
86
- xformer
87
33
  end
88
34
 
89
35
  end
@@ -0,0 +1,19 @@
1
+ class ActiveFedoraPidBasedJob
2
+ def queue_name
3
+ :pid_based
4
+ end
5
+
6
+ attr_accessor :pid
7
+ def initialize(pid)
8
+ self.pid = pid
9
+ end
10
+ def object
11
+ @object ||= ActiveFedora::Base.find(pid, cast:true)
12
+ end
13
+ alias_method :generic_file, :object
14
+ alias_method :generic_file_id, :pid
15
+
16
+ def run
17
+ raise RuntimeError, "Define #run in a subclass"
18
+ end
19
+ end
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- class AuditJob
15
+ class AuditJob < ActiveFedoraPidBasedJob
16
16
  def queue_name
17
17
  :audit
18
18
  end
@@ -20,16 +20,15 @@ class AuditJob
20
20
  PASS = 'Passing Audit Run'
21
21
  FAIL = 'Failing Audit Run'
22
22
 
23
- attr_accessor :generic_file_id, :datastream_id, :version_id
23
+ attr_accessor :pid, :datastream_id, :version_id
24
24
 
25
- def initialize(generic_file_id, datastream_id, version_id)
26
- self.generic_file_id = generic_file_id
25
+ def initialize(pid, datastream_id, version_id)
26
+ super(pid)
27
27
  self.datastream_id = datastream_id
28
28
  self.version_id = version_id
29
29
  end
30
30
 
31
31
  def run
32
- generic_file = GenericFile.find(generic_file_id)
33
32
  #logger.info "GF is #{generic_file.pid}"
34
33
  if generic_file
35
34
  datastream = generic_file.datastreams[datastream_id]
@@ -37,7 +36,7 @@ class AuditJob
37
36
  if datastream
38
37
  #logger.info "Datastream for audit = #{datastream.inspect}"
39
38
  version = datastream.versions.select { |v| v.versionID == version_id}.first
40
- log = GenericFile.run_audit(version)
39
+ log = run_audit(version)
41
40
 
42
41
  # look up the user for sending the message to
43
42
  login = generic_file.depositor
@@ -56,10 +55,15 @@ class AuditJob
56
55
  end
57
56
  end
58
57
  else
59
- logger.warn "No datastream for audit!!!!! pid: #{generic_file_id} dsid: #{datastream_id}"
58
+ logger.warn "No datastream for audit!!!!! pid: #{pid} dsid: #{datastream_id}"
60
59
  end
61
60
  else
62
- logger.warn "No generic file for data stream audit!!!!! pid: #{generic_file_id} dsid: #{datastream_id}"
61
+ logger.warn "No generic file for data stream audit!!!!! pid: #{pid} dsid: #{datastream_id}"
63
62
  end
64
63
  end
64
+
65
+ private
66
+ def run_audit(version)
67
+ object.class.run_audit(version)
68
+ end
65
69
  end
@@ -12,20 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- class CharacterizeJob
15
+ class CharacterizeJob < ActiveFedoraPidBasedJob
16
16
 
17
17
  def queue_name
18
18
  :characterize
19
19
  end
20
20
 
21
- attr_accessor :generic_file_id, :generic_file
22
-
23
- def initialize(generic_file_id)
24
- self.generic_file_id = generic_file_id
25
- end
26
-
27
21
  def run
28
- self.generic_file = GenericFile.find(generic_file_id)
29
22
  generic_file.characterize
30
23
  after_characterize
31
24
  end
@@ -35,9 +28,9 @@ class CharacterizeJob
35
28
  generic_file.create_thumbnail
36
29
  end
37
30
  if generic_file.video?
38
- Sufia.queue.push(TranscodeVideoJob.new(generic_file_id, 'content'))
31
+ Sufia.queue.push(TranscodeVideoJob.new(generic_file_id))
39
32
  elsif generic_file.audio?
40
- Sufia.queue.push(TranscodeAudioJob.new(generic_file_id, 'content'))
33
+ Sufia.queue.push(TranscodeAudioJob.new(generic_file_id))
41
34
  end
42
35
  end
43
36
  end
@@ -2,20 +2,13 @@ require 'net/https'
2
2
  require 'uri'
3
3
  require 'tempfile'
4
4
 
5
- class ImportUrlJob
5
+ class ImportUrlJob < ActiveFedoraPidBasedJob
6
6
 
7
7
  def queue_name
8
8
  :import_url
9
9
  end
10
10
 
11
- attr_accessor :pid
12
-
13
- def initialize(pid)
14
- self.pid = pid
15
- end
16
-
17
11
  def run
18
- generic_file = GenericFile.find(self.pid)
19
12
  f = Tempfile.new(self.pid)
20
13
  f.binmode
21
14
 
@@ -26,7 +19,7 @@ class ImportUrlJob
26
19
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
27
20
 
28
21
  http.start do
29
- http.request_get(uri) do |resp|
22
+ http.request_get(uri.request_uri) do |resp|
30
23
  resp.read_body do |segment|
31
24
  f.write(segment)
32
25
  end
@@ -18,6 +18,13 @@ class ResolrizeJob
18
18
  end
19
19
 
20
20
  def run
21
- ActiveFedora::Base.reindex_everything
21
+ require 'active_fedora/version'
22
+ active_fedora_version = Gem::Version.new(ActiveFedora::VERSION)
23
+ minimum_feature_version = Gem::Version.new('6.4.4')
24
+ if active_fedora_version >= minimum_feature_version
25
+ ActiveFedora::Base.reindex_everything("pid~#{Sufia.config.id_namespace}:*")
26
+ else
27
+ ActiveFedora::Base.reindex_everything
28
+ end
22
29
  end
23
30
  end
@@ -2,38 +2,14 @@
2
2
  # 7 Feb 2013
3
3
  # An asyncronous job for transcoding audio files using FFMpeg
4
4
 
5
- class TranscodeAudioJob < FfmpegTranscodeJob
5
+ class TranscodeAudioJob < ActiveFedoraPidBasedJob
6
6
  def queue_name
7
7
  :audio
8
8
  end
9
9
 
10
- def process
11
- encode_mp3()
12
- encode_ogg()
10
+ def run
11
+ generic_file.create_derivatives
12
+ generic_file.save
13
13
  end
14
14
 
15
- private
16
- def encode_ogg
17
- opts = ""
18
- if generic_file.mime_type == 'audio/ogg'
19
- # Don't re-encode, just copy
20
- generic_file.add_file_datastream(generic_file.content.read, :dsid=>'ogg', :mimeType=>'audio/ogg')
21
- #generic_file.content.rewind
22
- else
23
- encode_datastream('ogg', 'audio/ogg', opts)
24
- end
25
- end
26
-
27
- def encode_mp3
28
- opts = ""
29
- if generic_file.mime_type == 'audio/mpeg'
30
- # Don't re-encode, just copy
31
- generic_file.add_file_datastream(generic_file.content.read, :dsid=>'mp3', :mimeType=>'audio/mpeg')
32
- else
33
- encode_datastream('mp3', 'audio/mpeg', opts)
34
- end
35
- end
36
-
37
-
38
15
  end
39
-
@@ -2,38 +2,14 @@
2
2
  # 13 Dec 2012
3
3
  # An asyncronous job for transcoding video files using FFMpeg
4
4
 
5
- class TranscodeVideoJob < FfmpegTranscodeJob
5
+ class TranscodeVideoJob < ActiveFedoraPidBasedJob
6
6
  def queue_name
7
7
  :video
8
8
  end
9
9
 
10
- def process
11
- encode_mp4()
12
- encode_webm()
13
- end
14
-
15
- private
16
-
17
- def encode_webm
18
- # -g 30 enforces keyframe generation every second (30fps)
19
- # -b:v is the video bitrate
20
- # -acodec is the audio codec
21
- opts = "#{size_attributes} -g 30 -b:v 345k -acodec libvorbis #{audio_attributes}"
22
- encode_datastream('webm', 'video/webm', opts)
23
- end
24
-
25
- def encode_mp4
26
- opts = "#{size_attributes} -b:v 345k -vcodec libx264 -acodec libfaac #{audio_attributes} "
27
- encode_datastream('mp4', 'video/mp4', opts)
28
- end
29
-
30
-
31
- def size_attributes
32
- "-s 320x240"
33
- end
34
-
35
- def audio_attributes
36
- "-ac 2 -ab 96k -ar 44100"
10
+ def run
11
+ generic_file.create_derivatives
12
+ generic_file.save
37
13
  end
38
14
  end
39
15
 
@@ -12,19 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- class UnzipJob
15
+ class UnzipJob < ActiveFedoraPidBasedJob
16
16
  def queue_name
17
17
  :unzip
18
18
  end
19
19
 
20
- attr_accessor :pid
21
-
22
- def initialize(pid)
23
- self.pid = pid
24
- end
25
-
26
20
  def run
27
- Zip::Archive.open_buffer(zip_file.content.content) do |archive|
21
+ Zip::Archive.open_buffer(object.content.content) do |archive|
28
22
  archive.each do |f|
29
23
  if f.directory?
30
24
  create_directory(f)
@@ -41,14 +35,9 @@ class UnzipJob
41
35
  # @param file [Zip::File]
42
36
  def create_file(file)
43
37
  @generic_file = GenericFile.new
44
- @generic_file.batch_id = zip_file.batch.pid
45
- file_name = file.name
46
- mime_types = MIME::Types.of(file_name)
47
- mime_type = mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
48
- options = {:label=>file_name, :dsid=>'content', :mimeType=>mime_type}
49
- @generic_file.add_file_datastream(file.read, options)
50
- @generic_file.set_title_and_label( file_name, :only_if_blank=>true )
51
- @generic_file.apply_depositor_metadata(zip_file.edit_users.first)
38
+ @generic_file.batch_id = object.batch.pid
39
+ @generic_file.add_file(file.read, 'content', file.name)
40
+ @generic_file.apply_depositor_metadata(object.edit_users.first)
52
41
  @generic_file.date_uploaded = Time.now.ctime
53
42
  @generic_file.date_modified = Time.now.ctime
54
43
  @generic_file.save
@@ -60,7 +49,4 @@ class UnzipJob
60
49
  def create_directory(file)
61
50
  end
62
51
 
63
- def zip_file
64
- @zip_file ||= GenericFile.find(pid)
65
- end
66
52
  end
@@ -1,18 +1,3 @@
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
- require 'hydra/model_methods'
16
1
  module Sufia
17
2
  module ModelMethods
18
3
  extend ActiveSupport::Concern
@@ -26,9 +11,10 @@ module Sufia
26
11
  # Adds metadata about the depositor to the asset
27
12
  # Most important behavior: if the asset has a rightsMetadata datastream, this method will add +depositor_id+ to its individual edit permissions.
28
13
 
29
- def apply_depositor_metadata(depositor_id)
14
+ def apply_depositor_metadata(depositor)
30
15
  rights_ds = self.datastreams["rightsMetadata"]
31
16
  prop_ds = self.datastreams["properties"]
17
+ depositor_id = depositor.respond_to?(:user_key) ? depositor.user_key : depositor
32
18
 
33
19
  rights_ds.update_indexed_attributes([:edit_access, :person]=>depositor_id) unless rights_ds.nil?
34
20
  prop_ds.depositor = depositor_id unless prop_ds.nil?
@@ -0,0 +1,29 @@
1
+ # To enable local file ingest,
2
+ # - Make User model define .directory method that returns a String corresponding to the User's personal import directory on the server. This can be a simple ActiveRecord attribute on the User model, or it can be something more elaborate.
3
+ # - Include this module in your User model, or define a .files() method that behaves the same
4
+ # - Set Sufia.config.enable_local_ingest to true
5
+ #
6
+ module Sufia::UserLocalDirectoryBehavior
7
+
8
+ # You can use this validator in your User model.
9
+ # Ensures that a string defining the path to the user's directory has been provided
10
+ # and corresponds to a real directory on the server.
11
+ # @example
12
+ # validate :directory_must_exist
13
+ def directory_must_exist
14
+ unless directory.blank? || File.directory?(directory)
15
+ errors.add(:directory, "must be an existing directory")
16
+ end
17
+ end
18
+
19
+ # List the contents of the user's directory on the server
20
+ # Indicates whether each item is a directory or not.
21
+ def files
22
+ return [] unless directory.present? && File.directory?(directory)
23
+ Dir[File.join(directory, '*')].inject([]) do |accum, val|
24
+ accum << { name: File.basename(val), directory: File.directory?(val)}
25
+ accum
26
+ end
27
+ end
28
+
29
+ end
@@ -1,5 +1,5 @@
1
1
  module Sufia
2
2
  module Models
3
- VERSION = "3.0.0"
3
+ VERSION = "3.1.0"
4
4
  end
5
5
  end
data/sufia-models.gemspec CHANGED
@@ -38,9 +38,9 @@ Gem::Specification.new do |spec|
38
38
  spec.add_dependency 'noid', '~> 0.6.6'
39
39
  spec.add_dependency 'curationexperts-mailboxer', '0.10.3'
40
40
  spec.add_dependency 'acts_as_follower', '0.1.1'
41
- spec.add_dependency 'rmagick'
42
41
  spec.add_dependency 'paperclip', '~> 3.4.0'
43
42
  spec.add_dependency 'zipruby', '0.3.6'
43
+ spec.add_dependency 'hydra-derivatives', '~> 0.0.5'
44
44
  # https://github.com/zdennis/activerecord-import/pull/79
45
45
  #spec.add_dependency 'activerecord-import', '0.3.0' # 0.3.1 caused a bug in testing: "SQLite3::SQLException: near ",": syntax error: INSERT INTO..."
46
46
  end
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: 3.0.0
4
+ version: 3.1.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: 2013-07-22 00:00:00.000000000 Z
11
+ date: 2013-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -184,20 +184,6 @@ dependencies:
184
184
  - - '='
185
185
  - !ruby/object:Gem::Version
186
186
  version: 0.1.1
187
- - !ruby/object:Gem::Dependency
188
- name: rmagick
189
- requirement: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - '>='
192
- - !ruby/object:Gem::Version
193
- version: '0'
194
- type: :runtime
195
- prerelease: false
196
- version_requirements: !ruby/object:Gem::Requirement
197
- requirements:
198
- - - '>='
199
- - !ruby/object:Gem::Version
200
- version: '0'
201
187
  - !ruby/object:Gem::Dependency
202
188
  name: paperclip
203
189
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +212,20 @@ dependencies:
226
212
  - - '='
227
213
  - !ruby/object:Gem::Version
228
214
  version: 0.3.6
215
+ - !ruby/object:Gem::Dependency
216
+ name: hydra-derivatives
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ~>
220
+ - !ruby/object:Gem::Version
221
+ version: 0.0.5
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ~>
227
+ - !ruby/object:Gem::Version
228
+ version: 0.0.5
229
229
  description: Models and services for sufia
230
230
  email:
231
231
  - jeremy.n.friesen@gmail.com
@@ -264,22 +264,23 @@ files:
264
264
  - lib/sufia/models/active_support/core_ext/marshal.rb
265
265
  - lib/sufia/models/engine.rb
266
266
  - lib/sufia/models/file_content.rb
267
- - lib/sufia/models/file_content/extract_metadata.rb
268
267
  - lib/sufia/models/file_content/versions.rb
269
268
  - lib/sufia/models/generic_file.rb
270
269
  - lib/sufia/models/generic_file/accessible_attributes.rb
271
270
  - lib/sufia/models/generic_file/actions.rb
272
271
  - lib/sufia/models/generic_file/audit.rb
273
272
  - lib/sufia/models/generic_file/characterization.rb
273
+ - lib/sufia/models/generic_file/derivatives.rb
274
274
  - lib/sufia/models/generic_file/export.rb
275
+ - lib/sufia/models/generic_file/mime_types.rb
275
276
  - lib/sufia/models/generic_file/permissions.rb
276
277
  - lib/sufia/models/generic_file/thumbnail.rb
277
278
  - lib/sufia/models/generic_file/web_form.rb
278
279
  - lib/sufia/models/id_service.rb
280
+ - lib/sufia/models/jobs/active_fedora_pid_based_job.rb
279
281
  - lib/sufia/models/jobs/audit_job.rb
280
282
  - lib/sufia/models/jobs/batch_update_job.rb
281
283
  - lib/sufia/models/jobs/characterize_job.rb
282
- - lib/sufia/models/jobs/ffmpeg_transcode_job.rb
283
284
  - lib/sufia/models/jobs/import_url_job.rb
284
285
  - lib/sufia/models/jobs/resolrize_job.rb
285
286
  - lib/sufia/models/jobs/transcode_audio_job.rb
@@ -290,6 +291,7 @@ files:
290
291
  - lib/sufia/models/resque.rb
291
292
  - lib/sufia/models/solr_document_behavior.rb
292
293
  - lib/sufia/models/user.rb
294
+ - lib/sufia/models/user_local_directory_behavior.rb
293
295
  - lib/sufia/models/utils.rb
294
296
  - lib/sufia/models/version.rb
295
297
  - lib/tasks/resque.rake
@@ -315,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
317
  version: '0'
316
318
  requirements: []
317
319
  rubyforge_project:
318
- rubygems_version: 2.0.3
320
+ rubygems_version: 2.0.5
319
321
  signing_key:
320
322
  specification_version: 4
321
323
  summary: Models and services for sufia
@@ -1,60 +0,0 @@
1
- require 'open3'
2
- module Sufia
3
- module FileContent
4
- module ExtractMetadata
5
- include Open3
6
-
7
- def extract_metadata
8
- out = nil
9
- to_tempfile do |f|
10
- out = run_fits!(f.path)
11
- end
12
- out
13
- end
14
-
15
- def to_tempfile &block
16
- return unless has_content?
17
- tmp_base = Sufia.config.temp_file_base
18
- f = Tempfile.new("#{pid}-#{dsVersionID}")
19
- f.binmode
20
- if content.respond_to? :read
21
- f.write(content.read)
22
- else
23
- f.write(content)
24
- end
25
- f.close
26
- content.rewind if content.respond_to? :rewind
27
- yield(f)
28
- f.unlink
29
- end
30
-
31
- # Return true if the content is present
32
- # You can override this method if your content is an external datastream
33
- def has_content?
34
- !content.nil?
35
- end
36
-
37
- private
38
-
39
-
40
- def run_fits!(file_path)
41
- command = "#{fits_path} -i \"#{file_path}\""
42
- stdin, stdout, stderr, wait_thr = popen3(command)
43
- stdin.close
44
- out = stdout.read
45
- stdout.close
46
- err = stderr.read
47
- stderr.close
48
- exit_status = wait_thr.value
49
- raise "Unable to execute command \"#{command}\"\n#{err}" unless exit_status.success?
50
- out
51
- end
52
-
53
-
54
- def fits_path
55
- Sufia.config.fits_path
56
- end
57
-
58
- end
59
- end
60
- end
@@ -1,61 +0,0 @@
1
- # Created by: Justin Coyne
2
- # 7 Feb 2013
3
- # An abstract class for asyncronous jobs that transcode files using FFMpeg
4
-
5
- require 'tmpdir'
6
-
7
- class FfmpegTranscodeJob
8
- extend Open3
9
-
10
- attr_accessor :generic_file_id, :datastream_in, :datastream, :generic_file
11
-
12
- def initialize(generic_file_id, datastream_in)
13
- self.generic_file_id = generic_file_id
14
- self.datastream_in = datastream_in
15
- end
16
-
17
- def process
18
- raise "You attempted to call process() on an abstract class. Implement process() on the concrete class"
19
- end
20
-
21
- def run
22
- return unless Sufia.config.enable_ffmpeg
23
- self.generic_file = GenericFile.find(generic_file_id)
24
- self.datastream = generic_file.datastreams[datastream_in]
25
- if datastream
26
- process
27
- generic_file.save!
28
- else
29
- logger.warn "No datastream for transcoding!!!!! pid: #{generic_file_id} dsid: #{datastream_in}"
30
- end
31
- end
32
-
33
- def encode_datastream(dest_dsid, mime_type, options)
34
- file_suffix = dest_dsid
35
- out_file = nil
36
- output_file = Dir::Tmpname.create(['sufia', ".#{file_suffix}"], Sufia.config.temp_file_base){}
37
- datastream.to_tempfile do |f|
38
- self.class.encode(f.path, options, output_file)
39
- end
40
- out_file = File.open(output_file, "rb")
41
- generic_file.add_file_datastream(out_file.read, :dsid=>dest_dsid, :mimeType=>mime_type)
42
- File.unlink(output_file)
43
- end
44
-
45
- def self.encode(path, options, output_file)
46
- command = "#{ffmpeg_path} -y -i \"#{path}\" #{options} #{output_file}"
47
- stdin, stdout, stderr, wait_thr = popen3(command)
48
- stdin.close
49
- out = stdout.read
50
- stdout.close
51
- err = stderr.read
52
- stderr.close
53
- raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
54
- end
55
-
56
- def self.ffmpeg_path
57
- Sufia.config.ffmpeg_path
58
- end
59
- end
60
-
61
-