hydra-derivatives 0.0.2 → 0.0.3

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: 74b15261c78629ff97614bc0090102ceed0c5fa7
4
- data.tar.gz: 268d962f2ea5607db494c67455878d8cb8eab25d
3
+ metadata.gz: 6cb23951238b5918e0ea720629b80abbbf7c36f9
4
+ data.tar.gz: c518b9251a6869b1f76dc6095fcaa818f447e959
5
5
  SHA512:
6
- metadata.gz: 5c7c0aa06d5fd7059e4bb9886d2f241ff5a7f00508941bb7650907464e0a3d59e1d884fddc61208068930a263c420e952534bb91c5931deadd896695ba8fd607
7
- data.tar.gz: 5b5b6f7800798afe8dd7688638bdf88f643c6990d1cb0dad011d2f36c54238f2fc48e97f5fdaef6664d84daca620ed0b9ac9a0d8b2b0c0a51eeab843a7ecd84e
6
+ metadata.gz: fcc714f73eeda9db4e5c9d8bc3cfd62675d7f8af210abca8876d68ca9315479ff751624ac2c78c65b3314f08e1e5c369cff4c9edae21ec1c51fc20fb82ff977b
7
+ data.tar.gz: 08f350ea7eb44750e37e19c1e3082badc71c01258541f3fe5533887b4718517cad0f8591f538ce54959ed543d9991509fdafbeb0d819fe2738fc6b3e092aec5b
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/README.md CHANGED
@@ -10,15 +10,47 @@ If you have an ActiveFedora class like this:
10
10
 
11
11
  has_file_datastream :content
12
12
  attr_accessor :mime_type
13
+
14
+ # Use a block to declare which derivatives you want to generate
15
+ makes_derivatives do |obj|
16
+ case obj.mime_type
17
+ when 'application/pdf'
18
+ obj.transform_datastream :content, { :thumb => "100x100>" }
19
+ when 'audio/wav'
20
+ obj.transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
21
+ when 'video/avi'
22
+ obj.transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
23
+ when 'image/png', 'image/jpg'
24
+ obj.transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
25
+ end
26
+ end
27
+ end
28
+ ```
29
+
30
+ Or a class like this:
13
31
 
14
- makes_derivatives_of :content, when: :mime_type, is_one_of: ['image/tiff', 'image/jpeg],
15
- derivatives: { :thumbnail => {size: "200x150>", datastream: 'thumbnail'} }
16
- makes_derivatives_of :content, when: :mime_type, is: 'application/pdf',
17
- derivatives: { :thumbnail => {size: "338x493", datastream: 'thumbnail'} }
18
- makes_derivatives_of :content, when: :mime_type, is_one_of: ['video/mpeg', 'video/avi'],
19
- derivatives: { :webm => {format: "webm", datastream: 'webm'}, :mp4 => {format: "mp4", datastream: 'mp4'} }, processors: :video
20
- makes_derivatives_of :content, when: :mime_type, is_one_of: ['audio/wav', 'audio/mpeg'],
21
- derivatives: { :mp3 => {format: 'mp3', datastream: 'mp3'}, :ogg => {format: 'ogg', datastream: 'ogg'} }, processors: :audio
32
+ ```ruby
33
+ class GenericFile < ActiveFedora::Base
34
+ include Hydra::Derivatives
35
+
36
+ has_file_datastream :content
37
+ attr_accessor :mime_type
38
+
39
+ # Use a callback method to declare which derivatives you want
40
+ makes_derivatives :generate_derivatives
41
+
42
+ def generate_derivatives
43
+ case mime_type
44
+ when 'application/pdf'
45
+ transform_datastream :content, { :thumb => "100x100>" }
46
+ when 'audio/wav'
47
+ transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
48
+ when 'video/avi'
49
+ transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
50
+ when 'image/png', 'image/jpg'
51
+ transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
52
+ end
53
+ end
22
54
  end
23
55
  ```
24
56
 
@@ -34,3 +66,9 @@ And you add some content to it:
34
66
  Then when you call `obj.create_derivatives` a new datastream, called 'thumbnail' will have been created, with a downsized image in it.
35
67
 
36
68
  We recommend you run `obj.create_derivatives` in a background worker, because some derivative creation (especially videos) can take a long time.
69
+
70
+ You may want to adjust your path to add LibreOffice and Fits.sh support:
71
+ ```bash
72
+ # in .bash_profile
73
+ export PATH=${PATH}:/Users/justin/workspace/fits-0.6.2:/Applications/LibreOffice.app/Contents/MacOS
74
+ ```
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -10,105 +10,104 @@ module Hydra
10
10
  autoload :Ffmpeg
11
11
  autoload :Video
12
12
  autoload :Audio
13
+ autoload :Config
14
+ autoload :Document
13
15
  autoload :ExtractMetadata
16
+ autoload :ShellBasedProcessor
14
17
 
15
- def self.ffmpeg_path=(val)
16
- @ffmpeg_path = val
17
- end
18
- def self.ffmpeg_path
19
- #Sufia.config.ffmpeg_path
20
- @ffmpeg_path ||= 'ffmpeg'
18
+ def self.config
19
+ @config ||= reset_config!
21
20
  end
22
21
 
23
- def self.temp_file_base=(val)
24
- @temp_file_base = val
25
- end
26
- def self.temp_file_base
27
- #Sufia.config.temp_file_base
28
- @temp_file_base ||= '/tmp'
29
- end
30
-
31
- def self.fits_path=(val)
32
- @fits_path = val
33
- end
34
- def self.fits_path
35
- #Sufia.config.fits_path
36
- @fits_path ||= 'fits.sh'
22
+ def self.reset_config!
23
+ @config = Config.new
37
24
  end
38
25
 
39
- def self.enable_ffmpeg=(val)
40
- @enable_ffmpeg = val
41
- end
42
- def self.enable_ffmpeg
43
- @enable_ffmpeg ||= true
26
+ [:ffmpeg_path, :libreoffice_path, :temp_file_base, :fits_path, :enable_ffmpeg].each do |method|
27
+ module_eval <<-RUBY
28
+ def self.#{method.to_s}
29
+ config.#{method.to_s}
30
+ end
31
+ def self.#{method.to_s}= val
32
+ config.#{method.to_s}= val
33
+ end
34
+ RUBY
44
35
  end
45
36
 
46
37
  included do
47
- class_attribute :transformation_scheme
38
+ class_attribute :transformation_schemes
48
39
  end
49
40
 
50
41
 
51
42
  # Runs all of the transformations immediately.
52
43
  # You may want to run this job in the background as it may take a long time.
53
44
  def create_derivatives
54
- if transformation_scheme.present?
55
- transformation_scheme.each do |datastream, value|
56
- transform_datastream(datastream, value) if self.datastreams[datastream.to_s].has_content?
45
+ if transformation_schemes.present?
46
+ transformation_schemes.each do |transform_scheme|
47
+ if transform_scheme.instance_of?(Proc)
48
+ transform_scheme.call(self)
49
+ else
50
+ send(transform_scheme)
51
+ end
57
52
  end
58
53
  else
59
54
  logger.warn "`create_derivatives' was called on an instance of #{self.class}, but no derivatives have been requested"
60
55
  end
61
56
  end
62
57
 
63
- # Transform a single datastream
64
- def transform_datastream(datastream, directive_list)
65
- directive_list.each do |directive|
66
- if directive.applies?(self)
67
- processor = directive.processors ? Array(directive.processors).first : :image
68
- "Hydra::Derivatives::#{processor.to_s.classify}".constantize.new(self, datastream, directive.derivatives).process
69
- end
70
- end
71
-
58
+ # Create derivatives from a datastream according to transformation directives
59
+ # @param datastream_name
60
+ # @param [Hash] transform_directives - each key corresponds to a desired derivative. Associated values vary according to processor being used.
61
+ # @param [Hash] opts for specifying things like choice of :processor (processor defaults to :image)
62
+ #
63
+ # @example This will create content_thumb
64
+ # transform_datastream :content, { :thumb => "100x100>" }
65
+ #
66
+ # @example Specify the dsid for the output datastream
67
+ # transform_datastream :content, { :thumb => {size: "200x300>", datastream: 'thumbnail'} }
68
+ #
69
+ # @example Create multiple derivatives with one set of directives. This will create content_thumb and content_medium
70
+ # transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
71
+ #
72
+ # @example Specify which processor you want to use (defaults to :image)
73
+ # transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
74
+ # transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
75
+ #
76
+ def transform_datastream(datastream_name, transform_directives, opts={})
77
+ processor = opts[:processor] ? opts[:processor] : :image
78
+ "Hydra::Derivatives::#{processor.to_s.classify}".constantize.new(self, datastream_name, transform_directives).process
72
79
  end
73
80
 
74
- class TransformationDirective
75
- attr_accessor :differentiator, :selector, :derivatives, :processors
76
- # @param [Hash] args the options
77
- # @option args [Symbol] :when the method that holds the differentiator column
78
- # @option args [String, Array] :is_one_of activates this set of derivatives when the the differentiator column is includes one of these.
79
- # @option args [String, Array] :is alias for :is_one_of
80
- # @option args [Hash] :derivatives the derivatives to be produced
81
- # @option args [Symbol, Array] :processors the processors to run to produce the derivatives
82
- def initialize(args)
83
- self.differentiator = args[:when]
84
- self.selector = args[:is_one_of] || args[:is]
85
- self.derivatives = args[:derivatives]
86
- self.processors = args[:processors]
87
- end
88
-
89
- def applies?(object)
90
- selector.include?(object.send(differentiator))
91
- end
92
- end
93
81
 
94
82
  module ClassMethods
95
- # @param [Symbol, String] datastream the datastream to operate on
96
- # @param [Hash] args the options
97
- # @option args [Symbol] :when the method that holds the differentiator column
98
- # @option args [String, Array] :is_one_of activates this set of derivatives when the the differentiator column is includes one of these.
99
- # @option args [String, Array] :is alias for :is_one_of
100
- # @option args [Hash] :derivatives the derivatives to be produced
101
- # @option args [Symbol, Array] :processors the processors to run to produce the derivatives
102
- # @example
103
- # makes_derivatives_of :content, when: :mime_type, is: 'text/pdf',
104
- # derivatives: { :text => { :quality => :better }, processors: [:ocr]}
83
+ # Register transformation schemes for generating derivatives.
84
+ # You can do this using a block or by defining a callback method.
105
85
  #
106
- # makes_derivatives_of :content, when: :mime_type, is_one_of: ['image/png', 'image/jpg'],
107
- # derivatives: { :medium => "300x300>", :thumb => "100x100>" }
108
- def makes_derivatives_of(datastream, args = {})
109
- self.transformation_scheme ||= {}
110
- self.transformation_scheme[datastream.to_sym] ||= []
111
- self.transformation_scheme[datastream.to_sym] << TransformationDirective.new(args)
86
+ # @example Define transformation scheme using a block
87
+ # makes_derivatives do |obj|
88
+ # case obj.mime_type
89
+ # when 'application/pdf'
90
+ # obj.transform_datastream :content, { :thumb => "100x100>" }
91
+ # when 'audio/wav'
92
+ # obj.transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
93
+ #
94
+ # @example Define transformation scheme using a callback method
95
+ # makes_derivatives :generate_image_derivatives
96
+ #
97
+ # def generate_image_derivatives
98
+ # case mime_type
99
+ # when 'image/png', 'image/jpg'
100
+ # transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
101
+ # end
102
+ # end
103
+ def makes_derivatives(*callback_method_names, &block)
104
+ self.transformation_schemes ||= []
105
+ if block_given?
106
+ self.transformation_schemes << block
107
+ end
108
+ callback_method_names.each do |callback_name|
109
+ self.transformation_schemes << callback_name
110
+ end
112
111
  end
113
112
  end
114
113
  end
@@ -5,9 +5,6 @@ module Hydra
5
5
 
6
6
  protected
7
7
 
8
- def options_for(format)
9
- end
10
-
11
8
  def new_mime_type(format)
12
9
  case format
13
10
  when 'mp3'
@@ -0,0 +1,27 @@
1
+ module Hydra
2
+ module Derivatives
3
+ class Config
4
+ attr_writer :ffmpeg_path, :libreoffice_path, :temp_file_base, :fits_path, :enable_ffmpeg
5
+ def ffmpeg_path
6
+ @ffmpeg_path ||= 'ffmpeg'
7
+ end
8
+
9
+ def libreoffice_path
10
+ @libreoffice_path ||= 'soffice'
11
+ end
12
+
13
+ def temp_file_base
14
+ @temp_file_base ||= '/tmp'
15
+ end
16
+
17
+ def fits_path
18
+ @fits_path ||= 'fits.sh'
19
+ end
20
+
21
+ def enable_ffmpeg
22
+ @enable_ffmpeg ||= true
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ module Hydra
2
+ module Derivatives
3
+ class Document < Processor
4
+ include ShellBasedProcessor
5
+ def self.encode(path, options, output_file)
6
+ format = File.extname(output_file).sub('.', '')
7
+ outdir = File.dirname(output_file)
8
+ execute "#{Hydra::Derivatives.libreoffice_path} --invisible --headless --convert-to #{format} --outdir #{outdir} #{path}"
9
+ end
10
+
11
+ def encode_datastream(dest_dsid, file_suffix, mime_type, options = '')
12
+ output_file = Dir::Tmpname.create(['sufia', ".#{file_suffix}"], Hydra::Derivatives.temp_file_base){}
13
+ new_output = ''
14
+ source_datastream.to_tempfile do |f|
15
+ self.class.encode(f.path, options, output_file)
16
+ new_output = File.join(Hydra::Derivatives.temp_file_base, [File.basename(f.path).sub(File.extname(f.path), ''), file_suffix].join('.'))
17
+ end
18
+ out_file = File.open(new_output, "rb")
19
+ object.add_file_datastream(out_file.read, :dsid=>dest_dsid, :mimeType=>mime_type)
20
+ File.unlink(out_file)
21
+ end
22
+
23
+
24
+ def new_mime_type(format)
25
+ case format
26
+ when 'pdf'
27
+ 'application/pdf'
28
+ when 'odf'
29
+ 'application/vnd.oasis.opendocument.text'
30
+ else
31
+ raise "I don't know about the format '#{format}'"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -14,8 +14,10 @@ module Hydra
14
14
 
15
15
  def to_tempfile &block
16
16
  return unless has_content?
17
- tmp_base = Hydra::Derivatives.temp_file_base
18
- f = Tempfile.new("#{pid}-#{dsVersionID}")
17
+ list_of_extensions = MIME::Types[mimeType].first.extensions
18
+ extension = ".#{list_of_extensions.first}" if list_of_extensions
19
+
20
+ f = Tempfile.new(["#{pid}-#{dsVersionID}", extension])
19
21
  f.binmode
20
22
  if content.respond_to? :read
21
23
  f.write(content.read)
@@ -9,41 +9,14 @@ module Hydra
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
- extend Open3
12
+ include ShellBasedProcessor
13
13
  end
14
14
 
15
- def process
16
- directives.each do |name, args|
17
- format = args[:format]
18
- raise ArgumentError, "You must provide the :format you want to transcode into. You provided #{args}" unless format
19
- # TODO if the source is in the correct format, we could just copy it and skip transcoding.
20
- output_datastream_name = args[:datastream] || output_datastream_id(name)
21
- encode_datastream(output_datastream_name, format, new_mime_type(format), options_for(format))
22
- end
23
- end
24
-
25
- def encode_datastream(dest_dsid, file_suffix, mime_type, options = '')
26
- out_file = nil
27
- output_file = Dir::Tmpname.create(['sufia', ".#{file_suffix}"], Hydra::Derivatives.temp_file_base){}
28
- source_datastream.to_tempfile do |f|
29
- self.class.encode(f.path, options, output_file)
30
- end
31
- out_file = File.open(output_file, "rb")
32
- object.add_file_datastream(out_file.read, :dsid=>dest_dsid, :mimeType=>mime_type)
33
- File.unlink(output_file)
34
- end
35
15
 
36
16
  module ClassMethods
37
17
 
38
18
  def encode(path, options, output_file)
39
- command = "#{Hydra::Derivatives.ffmpeg_path} -y -i \"#{path}\" #{options} #{output_file}"
40
- stdin, stdout, stderr, wait_thr = popen3(command)
41
- stdin.close
42
- out = stdout.read
43
- stdout.close
44
- err = stderr.read
45
- stderr.close
46
- raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
19
+ execute "#{Hydra::Derivatives.ffmpeg_path} -y -i \"#{path}\" #{options} #{output_file}"
47
20
  end
48
21
  end
49
22
 
@@ -0,0 +1,58 @@
1
+ # An abstract class for asyncronous jobs that transcode files using FFMpeg
2
+
3
+ require 'tmpdir'
4
+ require 'open3'
5
+
6
+ module Hydra
7
+ module Derivatives
8
+ module ShellBasedProcessor
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ extend Open3
13
+ end
14
+
15
+ def process
16
+ directives.each do |name, args|
17
+ format = args[:format]
18
+ raise ArgumentError, "You must provide the :format you want to transcode into. You provided #{args}" unless format
19
+ # TODO if the source is in the correct format, we could just copy it and skip transcoding.
20
+ output_datastream_name = args[:datastream] || output_datastream_id(name)
21
+ encode_datastream(output_datastream_name, format, new_mime_type(format), options_for(format))
22
+ end
23
+ end
24
+
25
+ # override this method in subclass if you want to provide specific options.
26
+ def options_for(format)
27
+ end
28
+
29
+ def encode_datastream(dest_dsid, file_suffix, mime_type, options = '')
30
+ out_file = nil
31
+ output_file = Dir::Tmpname.create(['sufia', ".#{file_suffix}"], Hydra::Derivatives.temp_file_base){}
32
+ source_datastream.to_tempfile do |f|
33
+ self.class.encode(f.path, options, output_file)
34
+ end
35
+ out_file = File.open(output_file, "rb")
36
+ object.add_file_datastream(out_file.read, :dsid=>dest_dsid, :mimeType=>mime_type)
37
+ File.unlink(output_file)
38
+ end
39
+
40
+ module ClassMethods
41
+
42
+ def execute(command)
43
+ stdin, stdout, stderr, wait_thr = popen3(command)
44
+ stdin.close
45
+ out = stdout.read
46
+ stdout.close
47
+ err = stderr.read
48
+ stderr.close
49
+ raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+
58
+
Binary file
@@ -0,0 +1,68 @@
1
+ {\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
2
+ {\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}
3
+ {\f121\froman\fcharset238\fprq2 Times New Roman CE;}{\f122\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f124\froman\fcharset161\fprq2 Times New Roman Greek;}{\f125\froman\fcharset162\fprq2 Times New Roman Tur;}
4
+ {\f126\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f127\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f128\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f129\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
5
+ {\f131\fswiss\fcharset238\fprq2 Arial CE;}{\f132\fswiss\fcharset204\fprq2 Arial Cyr;}{\f134\fswiss\fcharset161\fprq2 Arial Greek;}{\f135\fswiss\fcharset162\fprq2 Arial Tur;}{\f136\fswiss\fcharset177\fprq2 Arial (Hebrew);}
6
+ {\f137\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f138\fswiss\fcharset186\fprq2 Arial Baltic;}{\f139\fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f141\fmodern\fcharset238\fprq1 Courier New CE;}{\f142\fmodern\fcharset204\fprq1 Courier New Cyr;}
7
+ {\f144\fmodern\fcharset161\fprq1 Courier New Greek;}{\f145\fmodern\fcharset162\fprq1 Courier New Tur;}{\f146\fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f147\fmodern\fcharset178\fprq1 Courier New (Arabic);}
8
+ {\f148\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f149\fmodern\fcharset163\fprq1 Courier New (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;
9
+ \red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{
10
+ \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0
11
+ \b\f1\fs32\lang1033\langfe1033\kerning32\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \styrsid2294299 heading 1;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\*
12
+ \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
13
+ \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\*\ts15\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10
14
+ \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
15
+ \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \sbasedon11 \snext15 \styrsid2294299 Table Grid;}{
16
+ \s16\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 \ssemihidden \styrsid1792631 footnote text;}{\*\cs17 \additive \super
17
+ \sbasedon10 \ssemihidden \styrsid1792631 footnote reference;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid-767292450\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360
18
+ \levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext
19
+ \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698693
20
+ \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers
21
+ ;}\f3\fbias0 \fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600
22
+ \jclisttab\tx3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\jclisttab\tx4320\lin4320 }
23
+ {\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc23
24
+ \levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0
25
+ \levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid687222349}}{\*\listoverridetable{\listoverride\listid687222349
26
+ \listoverridecount0\ls1}}{\*\rsidtbl \rsid1792631\rsid2294299}{\*\generator Microsoft Word 11.0.6113;}{\info{\title This is a test RTF}{\author Nate}{\operator Nate}{\version2}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1800\dgvorigin1440
27
+ \dghshow1\dgvshow1\jexpand\viewkind1\viewscale80\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
28
+ \asianbrkrule\rsidroot2294299\newtblstyruls\nogrowautofit \fet0{\*\ftnsep \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid1792631 \chftnsep
29
+ \par }}{\*\ftnsepc \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid1792631 \chftnsepc
30
+ \par }}{\*\aftnsep \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid1792631 \chftnsep
31
+ \par }}{\*\aftnsepc \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid1792631 \chftnsepc
32
+ \par }}\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}
33
+ {\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang
34
+ {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain
35
+ \s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid2294299 \b\f1\fs32\lang1033\langfe1033\kerning32\cgrid\langnp1033\langfenp1033 {\insrsid2294299 This is a test RTF
36
+ \par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2294299 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid2294299 Hi! I\rquote m a test file. This is some }{\b\insrsid2294299 bold}{
37
+ \insrsid2294299 text, and some }{\i\insrsid2294299 italic}{\insrsid2294299 text, as well as some }{\ul\insrsid2294299 underline}{\insrsid2294299 text. And a bit of }{\v\insrsid2294299\charrsid2294299 hidden}{\insrsid2294299 text. So we\rquote
38
+ re going to end this paragraph here and go on to a nice little list:
39
+ \par
40
+ \par {\listtext\pard\plain\f3\insrsid2294299 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ql \fi-360\li720\ri0\widctlpar\jclisttab\tx720\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid2294299 {\insrsid2294299 Item 1
41
+ \par {\listtext\pard\plain\f3\insrsid2294299 \loch\af3\dbch\af0\hich\f3 \'b7\tab}Item 2
42
+ \par {\listtext\pard\plain\f3\insrsid2294299 \loch\af3\dbch\af0\hich\f3 \'b7\tab}Item 3
43
+ \par {\listtext\pard\plain\f3\insrsid2294299 \loch\af3\dbch\af0\hich\f3 \'b7\tab}Item 4
44
+ \par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2294299 {\insrsid2294299
45
+ \par And now comes a fun table:
46
+ \par
47
+ \par }\trowd \irow0\irowband0\ts15\trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
48
+ \trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10
49
+ \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx5796\clvertalt\clbrdrt\brdrs\brdrw10
50
+ \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx8748\pard\plain \ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0\pararsid2294299\yts15
51
+ \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid2294299 Cell 1\cell Cell 2
52
+ \par More in cell 2\cell Cell 3\cell }\pard\plain \ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid2294299 \trowd \irow0\irowband0\ts15\trgaph108\trleft-108\trbrdrt
53
+ \brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
54
+ \trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10
55
+ \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx5796\clvertalt\clbrdrt\brdrs\brdrw10
56
+ \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx8748\row }\pard\plain \ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0\pararsid2294299\yts15
57
+ \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid2294299 Next row\cell Next row \cell Next row\cell }\pard\plain \ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0
58
+ \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid2294299 \trowd \irow1\irowband1\lastrow \ts15\trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv
59
+ \brdrs\brdrw10 \trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr
60
+ \brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx5796\clvertalt\clbrdrt
61
+ \brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2952\clshdrawnil \cellx8748\row }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2294299 {
62
+ \insrsid2294299
63
+ \par A page break:
64
+ \par \page And here we\rquote re on the next page.}{\insrsid1792631 }{\insrsid2294299
65
+ \par }{\insrsid1792631 This para has a }{\cs17\super\insrsid1792631 \chftn {\footnote \pard\plain \s16\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\cs17\super\insrsid1792631
66
+ \chftn }{\insrsid1792631 This is the actual content of the footnote.}}}{\insrsid1792631 footnote.
67
+ \par And here\rquote s yet another paragraph. }{\insrsid1792631\charrsid2294299
68
+ \par }}
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe "the configuration" do
4
+ subject {Hydra::Derivatives }
5
+
6
+ it "should have some configuration defaults" do
7
+ subject.ffmpeg_path.should == 'ffmpeg'
8
+ subject.enable_ffmpeg.should be_true
9
+ subject.libreoffice_path.should == 'soffice'
10
+ subject.temp_file_base.should == '/tmp'
11
+ subject.fits_path.should == 'fits.sh'
12
+ end
13
+
14
+ it "should let you change the configuration" do
15
+ subject.ffmpeg_path = '/usr/local/ffmpeg-1.0/bin/ffmpeg'
16
+ subject.ffmpeg_path.should == '/usr/local/ffmpeg-1.0/bin/ffmpeg'
17
+ end
18
+
19
+ it "should let you reset the configuration" do
20
+ subject.ffmpeg_path = '/usr/local/ffmpeg-1.0/bin/ffmpeg'
21
+ subject.reset_config!
22
+ subject.ffmpeg_path.should == 'ffmpeg'
23
+ end
24
+
25
+ end
@@ -14,25 +14,34 @@ describe "Transcoder" do
14
14
  delegate :mime_type, :to => :characterization, :unique => true
15
15
  has_file_datastream 'content', type: ContentDatastream
16
16
 
17
- makes_derivatives_of :content, when: :mime_type, is_one_of: 'application/pdf',
18
- derivatives: { :thumb => "100x100>" }
19
-
20
- makes_derivatives_of :content, when: :mime_type, is_one_of: 'audio/wav',
21
- derivatives: { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processors: :audio
22
-
23
- # -g 30 enforces keyframe generation every second (30fps)
24
- # -b:v is the video bitrate
25
- # -acodec is the audio codec
26
- size_attributes = "-s 320x240"
27
- audio_attributes = "-ac 2 -ab 96k -ar 44100"
28
- makes_derivatives_of :content, when: :mime_type, is: 'video/avi',
29
- derivatives: { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processors: :video
30
-
31
- makes_derivatives_of :content, when: :mime_type, is_one_of: ['image/png', 'image/jpg'],
32
- derivatives: { :medium => "300x300>", :thumb => "100x100>" }
17
+ makes_derivatives do |obj|
18
+ case obj.mime_type
19
+ when 'application/pdf'
20
+ obj.transform_datastream :content, { :thumb => "100x100>" }
21
+ when 'audio/wav'
22
+ obj.transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
23
+ when 'video/avi'
24
+ obj.transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
25
+ when 'image/png', 'image/jpg'
26
+ obj.transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
27
+ when 'application/vnd.ms-powerpoint'
28
+ obj.transform_datastream :content, { :access => { :format=>'pdf' } }, processor: 'document'
29
+ when 'text/rtf'
30
+ obj.transform_datastream :content, { :preservation=> {:format => 'odf' }, :access => { :format=>'pdf' } }, processor: 'document'
31
+ end
32
+ end
33
+
34
+ makes_derivatives :generate_special_derivatives
33
35
 
36
+ def generate_special_derivatives
37
+ if label == "special" && mime_type == 'image/png'
38
+ transform_datastream :content, { :medium => {size: "200x300>", datastream: 'special_ds'} }
39
+ end
40
+ end
41
+
34
42
  end
35
43
  end
44
+
36
45
  describe "with an attached image" do
37
46
  let(:attachment) { File.open(File.expand_path('../../fixtures/world.png', __FILE__))}
38
47
  let(:file) { GenericFile.new(mime_type: 'image/png').tap { |t| t.content.content = attachment; t.save } }
@@ -85,4 +94,41 @@ describe "Transcoder" do
85
94
  file.datastreams['content_webm'].mimeType.should == 'video/webm'
86
95
  end
87
96
  end
97
+
98
+ describe "using callback methods" do
99
+ let(:attachment) { File.open(File.expand_path('../../fixtures/world.png', __FILE__))}
100
+ let(:file) { GenericFile.new(mime_type: 'image/png', label: "special").tap { |t| t.content.content = attachment; t.save } }
101
+
102
+ it "should transcode" do
103
+ file.datastreams.key?('special_ds').should be_false
104
+ file.create_derivatives
105
+ file.datastreams['special_ds'].should have_content
106
+ file.datastreams['special_ds'].mimeType.should == 'image/png'
107
+ file.datastreams['special_ds'].should have_content
108
+ end
109
+ end
110
+
111
+ describe "with an attached Powerpoint", unless: ENV['TRAVIS'] == 'true' do
112
+ let(:attachment) { File.open(File.expand_path('../../fixtures/FlashPix.ppt', __FILE__))}
113
+ let(:file) { GenericFile.new(mime_type: 'application/vnd.ms-powerpoint').tap { |t| t.content.content = attachment; t.save } }
114
+
115
+ it "should transcode" do
116
+ file.create_derivatives
117
+ file.datastreams['content_access'].should have_content
118
+ file.datastreams['content_access'].mimeType.should == 'application/pdf'
119
+ end
120
+ end
121
+
122
+ describe "with an attached rich text format", unless: ENV['TRAVIS'] == 'true' do
123
+ let(:attachment) { File.open(File.expand_path('../../fixtures/sample.rtf', __FILE__))}
124
+ let(:file) { GenericFile.new(mime_type: 'text/rtf').tap { |t| t.content.content = attachment; t.save } }
125
+
126
+ it "should transcode" do
127
+ file.create_derivatives
128
+ file.datastreams['content_access'].should have_content
129
+ file.datastreams['content_access'].mimeType.should == 'application/pdf'
130
+ file.datastreams['content_preservation'].should have_content
131
+ file.datastreams['content_preservation'].mimeType.should == 'application/vnd.oasis.opendocument.text'
132
+ end
133
+ end
88
134
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-derivatives
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-24 00:00:00.000000000 Z
11
+ date: 2013-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,7 @@ extensions: []
122
122
  extra_rdoc_files: []
123
123
  files:
124
124
  - .gitignore
125
+ - .rspec
125
126
  - .travis.yml
126
127
  - CONTRIBUTING.md
127
128
  - Gemfile
@@ -134,16 +135,22 @@ files:
134
135
  - hydra-derivatives.gemspec
135
136
  - lib/hydra/derivatives.rb
136
137
  - lib/hydra/derivatives/audio.rb
138
+ - lib/hydra/derivatives/config.rb
139
+ - lib/hydra/derivatives/document.rb
137
140
  - lib/hydra/derivatives/extract_metadata.rb
138
141
  - lib/hydra/derivatives/ffmpeg.rb
139
142
  - lib/hydra/derivatives/image.rb
140
143
  - lib/hydra/derivatives/processor.rb
144
+ - lib/hydra/derivatives/shell_based_processor.rb
141
145
  - lib/hydra/derivatives/video.rb
146
+ - spec/fixtures/FlashPix.ppt
142
147
  - spec/fixtures/countdown.avi
143
148
  - spec/fixtures/piano_note.wav
149
+ - spec/fixtures/sample.rtf
144
150
  - spec/fixtures/test.pdf
145
151
  - spec/fixtures/world.png
146
152
  - spec/spec_helper.rb
153
+ - spec/units/config_spec.rb
147
154
  - spec/units/image_spec.rb
148
155
  - spec/units/transcoding_spec.rb
149
156
  - spec/units/video_spec.rb
@@ -172,11 +179,14 @@ signing_key:
172
179
  specification_version: 4
173
180
  summary: Derivative generation plugin for hydra
174
181
  test_files:
182
+ - spec/fixtures/FlashPix.ppt
175
183
  - spec/fixtures/countdown.avi
176
184
  - spec/fixtures/piano_note.wav
185
+ - spec/fixtures/sample.rtf
177
186
  - spec/fixtures/test.pdf
178
187
  - spec/fixtures/world.png
179
188
  - spec/spec_helper.rb
189
+ - spec/units/config_spec.rb
180
190
  - spec/units/image_spec.rb
181
191
  - spec/units/transcoding_spec.rb
182
192
  - spec/units/video_spec.rb