sufia-models 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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
-