hydra-works 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -8
- data/README.md +9 -9
- data/hydra-works.gemspec +3 -4
- data/lib/hydra/works.rb +22 -13
- data/lib/hydra/works/characterization.rb +31 -0
- data/lib/hydra/works/characterization/schema/audio_schema.rb +12 -0
- data/lib/hydra/works/characterization/schema/base_schema.rb +17 -0
- data/lib/hydra/works/characterization/schema/document_schema.rb +18 -0
- data/lib/hydra/works/characterization/schema/image_schema.rb +22 -0
- data/lib/hydra/works/characterization/schema/video_schema.rb +9 -0
- data/lib/hydra/works/models/characterization/already_there_strategy.rb +12 -0
- data/lib/hydra/works/models/characterization/fits_datastream.rb +162 -0
- data/lib/hydra/works/models/concerns/collection_behavior.rb +42 -34
- data/lib/hydra/works/models/concerns/file_set/characterization/audio.rb +14 -0
- data/lib/hydra/works/models/concerns/file_set/characterization/base.rb +23 -0
- data/lib/hydra/works/models/concerns/file_set/characterization/document.rb +10 -0
- data/lib/hydra/works/models/concerns/file_set/characterization/image.rb +10 -0
- data/lib/hydra/works/models/concerns/file_set/characterization/video.rb +17 -0
- data/lib/hydra/works/models/concerns/{generic_file → file_set}/contained_files.rb +1 -1
- data/lib/hydra/works/models/concerns/file_set/derivatives.rb +27 -0
- data/lib/hydra/works/models/concerns/{generic_file → file_set}/mime_types.rb +1 -1
- data/lib/hydra/works/models/concerns/{generic_file → file_set}/versioned_content.rb +2 -2
- data/lib/hydra/works/models/concerns/{generic_file → file_set}/virus_check.rb +1 -1
- data/lib/hydra/works/models/concerns/file_set_behavior.rb +67 -0
- data/lib/hydra/works/models/concerns/generic_file_behavior.rb +4 -50
- data/lib/hydra/works/models/concerns/generic_work_behavior.rb +5 -77
- data/lib/hydra/works/models/concerns/work_behavior.rb +118 -0
- data/lib/hydra/works/models/file_set.rb +7 -0
- data/lib/hydra/works/models/generic_file.rb +8 -8
- data/lib/hydra/works/models/generic_work.rb +15 -4
- data/lib/hydra/works/models/work.rb +6 -0
- data/lib/hydra/works/services/{generic_file/add_file_to_generic_file.rb → add_file_to_file_set.rb} +20 -20
- data/lib/hydra/works/services/add_file_to_generic_file.rb +8 -0
- data/lib/hydra/works/services/characterization_service.rb +118 -0
- data/lib/hydra/works/services/persist_derivative.rb +35 -0
- data/lib/hydra/works/services/{generic_file/upload_file_to_generic_file.rb → upload_file_to_file_set.rb} +3 -3
- data/lib/hydra/works/services/upload_file_to_generic_file.rb +8 -0
- data/lib/hydra/works/version.rb +1 -1
- data/lib/hydra/works/vocab/works_terms.rb +2 -2
- data/spec/fixtures/fits_0.6.2_avi.xml +29 -0
- data/spec/fixtures/fits_0.6.2_jp2.xml +36 -0
- data/spec/fixtures/fits_0.6.2_jpg.xml +43 -0
- data/spec/fixtures/fits_0.6.2_pdf.xml +42 -0
- data/spec/fixtures/fits_0.8.5_avi.xml +50 -0
- data/spec/fixtures/fits_0.8.5_docx.xml +41 -0
- data/spec/fixtures/fits_0.8.5_jp2.xml +51 -0
- data/spec/fixtures/fits_0.8.5_mp3.xml +47 -0
- data/spec/fixtures/fits_0.8.5_mp4.xml +47 -0
- data/spec/fixtures/fits_0.8.5_pdf.xml +54 -0
- data/spec/fixtures/pdf_fits.xml +54 -0
- data/spec/hydra/works/models/collection_spec.rb +58 -326
- data/spec/hydra/works/models/concerns/{generic_file → file_set}/contained_files_spec.rb +16 -16
- data/spec/hydra/works/models/concerns/{generic_file → file_set}/mime_types_spec.rb +2 -2
- data/spec/hydra/works/models/concerns/file_set/versioned_content_spec.rb +32 -0
- data/spec/hydra/works/models/concerns/{generic_file → file_set}/virus_check_spec.rb +3 -3
- data/spec/hydra/works/models/concerns/file_set_behavior_spec.rb +12 -0
- data/spec/hydra/works/models/generic_file_spec.rb +16 -13
- data/spec/hydra/works/models/generic_work_spec.rb +148 -318
- data/spec/hydra/works/services/{generic_file/add_file_to_generic_file_spec.rb → add_file_to_file_set_spec.rb} +4 -4
- data/spec/hydra/works/services/characterization_service_spec.rb +199 -0
- data/spec/hydra/works/services/persist_derivatives_spec.rb +57 -29
- data/spec/hydra/works/services/{generic_file/upload_file_spec.rb → upload_file_spec.rb} +7 -17
- data/spec/hydra/works_spec.rb +23 -59
- data/spec/spec_helper.rb +4 -2
- data/spec/support/file_set_helper.rb +14 -0
- metadata +84 -55
- data/lib/hydra/works/errors/full_text_extraction_error.rb +0 -5
- data/lib/hydra/works/models/concerns/block_child_objects.rb +0 -22
- data/lib/hydra/works/models/concerns/generic_file/derivatives.rb +0 -26
- data/lib/hydra/works/services/generic_file/full_text_extraction_service.rb +0 -57
- data/lib/hydra/works/services/generic_file/generate_thumbnail.rb +0 -13
- data/lib/hydra/works/services/generic_file/persist_derivative.rb +0 -20
- data/spec/hydra/works/models/concerns/block_child_objects_spec.rb +0 -17
- data/spec/hydra/works/models/concerns/generic_file/versioned_content_spec.rb +0 -32
- data/spec/hydra/works/models/concerns/generic_file_behavior_spec.rb +0 -12
- data/spec/hydra/works/services/full_text_extraction_service_spec.rb +0 -89
- data/spec/hydra/works/services/generic_file/generate/thumbnail_spec.rb +0 -19
@@ -0,0 +1,118 @@
|
|
1
|
+
module Hydra::Works
|
2
|
+
# This module provides all of the Behaviors of a Hydra::Works::Work
|
3
|
+
#
|
4
|
+
# behavior:
|
5
|
+
# 1) Hydra::Works::Work can aggregate Hydra::Works::Work
|
6
|
+
# 2) Hydra::Works::Work can aggregate Hydra::Works::FileSet
|
7
|
+
# 3) Hydra::Works::Work can NOT aggregate Hydra::PCDM::Collection
|
8
|
+
# 4) Hydra::Works::Work can NOT aggregate Hydra::Works::Collection
|
9
|
+
# 5) Hydra::Works::Work can NOT aggregate Works::Object unless it is also a Hydra::Works::FileSet
|
10
|
+
# 6) Hydra::Works::Work can NOT contain PCDM::File
|
11
|
+
# 7) Hydra::Works::Work can NOT aggregate non-PCDM object
|
12
|
+
# 8) Hydra::Works::Work can NOT contain Hydra::Works::FileSet
|
13
|
+
# 9) Hydra::Works::Work can have descriptive metadata
|
14
|
+
# 10) Hydra::Works::Work can have access metadata
|
15
|
+
module WorkBehavior
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
extend Deprecation
|
18
|
+
self.deprecation_horizon = "Hydra::Works 0.4.0"
|
19
|
+
include Hydra::PCDM::ObjectBehavior
|
20
|
+
|
21
|
+
included do
|
22
|
+
type [Hydra::PCDM::Vocab::PCDMTerms.Object, Vocab::WorksTerms.Work]
|
23
|
+
|
24
|
+
alias_method :generic_works, :ordered_works
|
25
|
+
deprecation_deprecate :generic_works
|
26
|
+
|
27
|
+
alias_method :generic_files, :ordered_file_sets
|
28
|
+
end
|
29
|
+
|
30
|
+
def works
|
31
|
+
members.select(&:work?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def work_ids
|
35
|
+
works.map(&:id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def ordered_works
|
39
|
+
ordered_members.to_a.select(&:work?)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ordered_work_ids
|
43
|
+
ordered_works.map(&:id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def file_sets
|
47
|
+
members.select(&:file_set?)
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_set_ids
|
51
|
+
file_sets.map(&:id)
|
52
|
+
end
|
53
|
+
|
54
|
+
def ordered_file_sets
|
55
|
+
ordered_members.to_a.select(&:file_set?)
|
56
|
+
end
|
57
|
+
|
58
|
+
def ordered_file_set_ids
|
59
|
+
ordered_file_sets.map(&:id)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Boolean] whether this instance is a Hydra::Works Collection.
|
63
|
+
def collection?
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method :works_collection?, :collection?
|
68
|
+
deprecation_deprecate :works_collection?
|
69
|
+
|
70
|
+
# @return [Boolean] whether this instance is a Hydra::Works Generic Work.
|
71
|
+
def work?
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :works_generic_work?, :work?
|
76
|
+
deprecation_deprecate :works_generic_work?
|
77
|
+
|
78
|
+
# @return [Boolean] whether this instance is a Hydra::Works::FileSet.
|
79
|
+
def file_set?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :works_generic_file?, :file_set?
|
84
|
+
deprecation_deprecate :works_generic_file?
|
85
|
+
|
86
|
+
def parents
|
87
|
+
Deprecation.warn WorkBehavior, '`parents` is deprecated in Hydra::Works. Please use `member_of` instead. This has a target date for removal of 10-31-2015'
|
88
|
+
member_of
|
89
|
+
end
|
90
|
+
|
91
|
+
def in_works
|
92
|
+
ordered_by.select { |parent| parent.class.included_modules.include?(Hydra::Works::WorkBehavior) }.to_a
|
93
|
+
end
|
94
|
+
|
95
|
+
alias_method :in_generic_works, :in_works
|
96
|
+
deprecation_deprecate :in_generic_works
|
97
|
+
|
98
|
+
def parent_generic_works
|
99
|
+
Deprecation.warn WorkBehavior, '`parent_generic_works` is deprecated in Hydra::Works. Please use `in_works` instead. This has a target date for removal of 10-31-2015'
|
100
|
+
in_works
|
101
|
+
end
|
102
|
+
|
103
|
+
def parent_collections
|
104
|
+
Deprecation.warn WorkBehavior, '`parent_collections` is deprecated in Hydra::Works. Please use `in_collections` instead. This has a target date for removal of 10-31-2015'
|
105
|
+
in_collections
|
106
|
+
end
|
107
|
+
|
108
|
+
def child_generic_works
|
109
|
+
Deprecation.warn WorkBehavior, '`child_generic_works` is deprecated in Hydra::Works. Please use `ordered_works` instead. This has a target date for removal of 10-31-2015'
|
110
|
+
ordered_works
|
111
|
+
end
|
112
|
+
|
113
|
+
def child_generic_work_ids
|
114
|
+
Deprecation.warn WorkBehavior, '`child_generic_work_ids` is deprecated in Hydra::Works. Please use `ordered_work_ids` instead. This has a target date for removal of 10-31-2015'
|
115
|
+
ordered_work_ids
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -3,15 +3,15 @@ module Hydra::Works
|
|
3
3
|
module GenericFile
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
|
7
|
-
autoload :MimeTypes, 'hydra/works/models/concerns/generic_file/mime_types'
|
8
|
-
autoload :ContainedFiles, 'hydra/works/models/concerns/generic_file/contained_files'
|
9
|
-
autoload :VersionedContent, 'hydra/works/models/concerns/generic_file/versioned_content'
|
10
|
-
autoload :VirusCheck, 'hydra/works/models/concerns/generic_file/virus_check'
|
11
|
-
|
12
|
-
# Base class for creating objects that behave like Hydra::Works::GenericFiles
|
6
|
+
# @deprecated Base class for creating objects that behave like Hydra::Works::GenericFiles
|
13
7
|
class Base < ActiveFedora::Base
|
14
|
-
|
8
|
+
extend Deprecation
|
9
|
+
include Hydra::Works::FileSetBehavior
|
10
|
+
after_initialize :deprecation_warning
|
11
|
+
|
12
|
+
def deprecation_warning
|
13
|
+
Deprecation.warn Base, "Hydra::Works::FileSet is deprecated and will be removed in 0.4.0. Use Hydra::Works::FileSet instead"
|
14
|
+
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,9 +1,20 @@
|
|
1
1
|
module Hydra::Works
|
2
|
-
#
|
3
|
-
|
4
|
-
|
2
|
+
# Typically used for very generic applications that don't differntiate
|
3
|
+
# between specific content types. If you want a specific type of work
|
4
|
+
# extend Active::Fedora base and include the following:
|
5
|
+
# include Hydra::Works::WorkBehavior
|
6
|
+
class GenericWork < ActiveFedora::Base
|
7
|
+
include Hydra::Works::WorkBehavior
|
8
|
+
|
9
|
+
# @deprecated Base class for creating objects that behave like Hydra::Works::GenericWorks
|
5
10
|
class Base < ActiveFedora::Base
|
6
|
-
|
11
|
+
extend Deprecation
|
12
|
+
after_initialize :deprecated_warning
|
13
|
+
include Hydra::Works::WorkBehavior
|
14
|
+
|
15
|
+
def deprecated_warning
|
16
|
+
Deprecation.warn(Base, "GenericWork is deprecated and will be removed in Hydra::Works 0.4.0. Use Hydra::Works::GenericWork instead")
|
17
|
+
end
|
7
18
|
end
|
8
19
|
end
|
9
20
|
end
|
data/lib/hydra/works/services/{generic_file/add_file_to_generic_file.rb → add_file_to_file_set.rb}
RENAMED
@@ -1,30 +1,30 @@
|
|
1
1
|
module Hydra::Works
|
2
|
-
class
|
3
|
-
# Adds a file to the
|
4
|
-
# @param [Hydra::PCDM::
|
2
|
+
class AddFileToFileSet
|
3
|
+
# Adds a file to the file_set
|
4
|
+
# @param [Hydra::PCDM::FileSet] file_set the file will be added to
|
5
5
|
# @param [IO,File,Rack::Multipart::UploadedFile, #read] object that will be the contents. If file responds to :mime_type, :content_type, :original_name, or :original_filename, those will be called to provide metadata.
|
6
|
-
# @param [RDF::URI or String] type URI for the RDF.type that identifies the file's role within the
|
7
|
-
# @param [Boolean] update_existing whether to update an existing file if there is one. When set to true, performs a create_or_update. When set to false, always creates a new file within
|
6
|
+
# @param [RDF::URI or String] type URI for the RDF.type that identifies the file's role within the file_set
|
7
|
+
# @param [Boolean] update_existing whether to update an existing file if there is one. When set to true, performs a create_or_update. When set to false, always creates a new file within file_set.files.
|
8
8
|
# @param [Boolean] versioning whether to create new version entries (only applicable if +type+ corresponds to a versionable file)
|
9
9
|
|
10
|
-
def self.call(
|
11
|
-
fail ArgumentError, 'supplied object must be a generic file' unless
|
10
|
+
def self.call(file_set, file, type, update_existing: true, versioning: true)
|
11
|
+
fail ArgumentError, 'supplied object must be a generic file' unless file_set.file_set?
|
12
12
|
fail ArgumentError, 'supplied file must respond to read' unless file.respond_to? :read
|
13
13
|
|
14
14
|
# TODO: required as a workaround for https://github.com/projecthydra/active_fedora/pull/858
|
15
|
-
|
15
|
+
file_set.save unless file_set.persisted?
|
16
16
|
|
17
17
|
updater_class = versioning ? VersioningUpdater : Updater
|
18
|
-
updater = updater_class.new(
|
18
|
+
updater = updater_class.new(file_set, type, update_existing)
|
19
19
|
status = updater.update(file)
|
20
|
-
status ?
|
20
|
+
status ? file_set : false
|
21
21
|
end
|
22
22
|
|
23
23
|
class Updater
|
24
|
-
attr_reader :
|
24
|
+
attr_reader :file_set, :current_file
|
25
25
|
|
26
|
-
def initialize(
|
27
|
-
@
|
26
|
+
def initialize(file_set, type, update_existing)
|
27
|
+
@file_set = file_set
|
28
28
|
@current_file = find_or_create_file(type, update_existing)
|
29
29
|
end
|
30
30
|
|
@@ -39,8 +39,8 @@ module Hydra::Works
|
|
39
39
|
|
40
40
|
def persist
|
41
41
|
if current_file.new_record?
|
42
|
-
# persist current_file and its membership in
|
43
|
-
|
42
|
+
# persist current_file and its membership in file_set.files container
|
43
|
+
file_set.save
|
44
44
|
else
|
45
45
|
# we updated the content of an existing file, so we need to save the file explicitly
|
46
46
|
current_file.save
|
@@ -85,16 +85,16 @@ module Hydra::Works
|
|
85
85
|
# @param [true, false] update_existing when true, try to retrieve existing element before building one
|
86
86
|
def find_or_create_file(type, update_existing)
|
87
87
|
if type.instance_of? Symbol
|
88
|
-
association =
|
89
|
-
fail ArgumentError, "you're attempting to add a file to a
|
88
|
+
association = file_set.association(type)
|
89
|
+
fail ArgumentError, "you're attempting to add a file to a file_set using '#{type}' association but the file_set does not have an association called '#{type}''" unless association
|
90
90
|
|
91
91
|
current_file = association.reader if update_existing
|
92
92
|
current_file || association.build
|
93
93
|
else
|
94
|
-
current_file =
|
94
|
+
current_file = file_set.filter_files_by_type(type_to_uri(type)).first if update_existing
|
95
95
|
unless current_file
|
96
|
-
|
97
|
-
current_file =
|
96
|
+
file_set.files.build
|
97
|
+
current_file = file_set.files.last
|
98
98
|
Hydra::PCDM::AddTypeToFile.call(current_file, type_to_uri(type))
|
99
99
|
end
|
100
100
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'hydra-file_characterization'
|
2
|
+
|
3
|
+
module Hydra::Works
|
4
|
+
class CharacterizationService
|
5
|
+
# @param [ActiveFedora::Base] object which has properties to recieve characterization values.
|
6
|
+
# @param [Symbol, String, File] source for characterization to be run on. File object, path on disk, or symbol.
|
7
|
+
# A symbol should be the name of the method call to get object that responds to content? or is the content.
|
8
|
+
# @param [Hash] options to be passed to characterization. parser_mapping:, parser_class:, tools:
|
9
|
+
def self.run(object, source = :original_file, options = {})
|
10
|
+
new(object, source, options).characterize
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :object, :source, :mapping, :parser_class, :tools
|
14
|
+
|
15
|
+
def initialize(object, source, options)
|
16
|
+
@object = object
|
17
|
+
@source = source
|
18
|
+
@mapping, @parser_class, @tools = extract_options(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get given source into form that can be passed to Hydra::FileCharacterization
|
22
|
+
# Use Hydra::FileCharacterization to extract metadata (an OM Datastream)
|
23
|
+
# Get the terms (and their values) from the extracted metadata
|
24
|
+
# Assign the values of the terms to the properties of the object
|
25
|
+
def characterize
|
26
|
+
content = source_to_content
|
27
|
+
extracted_md = extract_metadata(content)
|
28
|
+
terms = parse_metadata(extracted_md)
|
29
|
+
store_metadata(terms)
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
# Get value from opts hash, object, or use default
|
35
|
+
def extract_options(opts)
|
36
|
+
parser_mapping = fetch_or_respond(opts, :parser_mapping) || {}
|
37
|
+
parser_class = fetch_or_respond(opts, :parser_class) || FitsDatastream
|
38
|
+
ch12n_tool = opts.fetch(:ch12n_tool) { :fits }
|
39
|
+
|
40
|
+
[parser_mapping, parser_class, ch12n_tool]
|
41
|
+
end
|
42
|
+
|
43
|
+
def fetch_or_respond(opts, key)
|
44
|
+
opts.fetch(key) { object.send(key) if object.respond_to? key }
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param [String,Symbol,File]
|
48
|
+
# @return content if source is a symbol, File if source is string
|
49
|
+
def source_to_content
|
50
|
+
if source.is_a? String
|
51
|
+
File.open(source)
|
52
|
+
elsif source.is_a? Symbol
|
53
|
+
s = object.send(source)
|
54
|
+
s.respond_to?(:content) ? s.content : s
|
55
|
+
else
|
56
|
+
source
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def extract_metadata(content)
|
61
|
+
Hydra::FileCharacterization.characterize(content, temp_file_name, tools) do |cfg|
|
62
|
+
cfg[:fits] = Hydra::Derivatives.fits_path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def temp_file_name
|
67
|
+
m = %r{/([^/]*)$} .match(object.uri)
|
68
|
+
"#{m[1]}-content.tmp"
|
69
|
+
end
|
70
|
+
|
71
|
+
# Use OM to parse metadata
|
72
|
+
def parse_metadata(metadata)
|
73
|
+
datastream = parser_class.new
|
74
|
+
datastream.ng_xml = metadata if metadata.present?
|
75
|
+
characterization_terms(datastream)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get proxy terms and values from the parser
|
79
|
+
def characterization_terms(datastream)
|
80
|
+
h = {}
|
81
|
+
datastream.class.terminology.terms.each_pair do |key, target|
|
82
|
+
# a key is a proxy if its target responds to proxied_term
|
83
|
+
next unless target.respond_to? :proxied_term
|
84
|
+
begin
|
85
|
+
h[key] = datastream.send(key)
|
86
|
+
rescue NoMethodError
|
87
|
+
next
|
88
|
+
end
|
89
|
+
end
|
90
|
+
h.delete_if { |_k, v| v.empty? }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Assign values of the instance properties from the metadata mapping :prop => val
|
94
|
+
def store_metadata(terms)
|
95
|
+
terms.each_pair do |term, value|
|
96
|
+
property = property_for(term)
|
97
|
+
next if property.nil?
|
98
|
+
# Array-ify the value to avoid a conditional here
|
99
|
+
Array(value).each { |v| append_property_value(property, v) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Check parser_config then self for matching term.
|
104
|
+
# Return property symbol or nil
|
105
|
+
def property_for(term)
|
106
|
+
if mapping.key?(term) && object.respond_to?(mapping[term])
|
107
|
+
mapping[term]
|
108
|
+
else
|
109
|
+
term if object.respond_to?(term)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def append_property_value(property, value)
|
114
|
+
value = object[property] + [value] if object.class.multiple?(property)
|
115
|
+
object.send("#{property}=", value)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'hydra/derivatives'
|
2
|
+
|
3
|
+
module Hydra::Works
|
4
|
+
class PersistDerivative < Hydra::Derivatives::PersistOutputFileService
|
5
|
+
##
|
6
|
+
# Persists a derivative to a FileSet
|
7
|
+
# This Service conforms to the signature of `Hydra::Derivatives::PersistOutputFileService`.
|
8
|
+
# The purpose of this Service is for use as an alternative to the default Hydra::Derivatives::PersistOutputFileService. It's necessary because the default behavior in Hydra::Derivatives assumes that you're using LDP Basic Containment. Hydra::Works::FileSets use IndirectContainment. This Service handles that case.
|
9
|
+
# This service will always update existing and does not do versioning of persisted files.
|
10
|
+
#
|
11
|
+
# @param [#read] stream the derivative filestream
|
12
|
+
# @param [Hash] directives
|
13
|
+
# @option directives [FileSet] :object the FileSet object to attach to
|
14
|
+
# @option directives [Symbol] :label the type of derivative
|
15
|
+
# extract file type symbol (e.g. :thumbnail) from Hydra::Derivatives created destination_name
|
16
|
+
def self.call(stream, directives)
|
17
|
+
file = Hydra::Derivatives::IoDecorator.new(stream)
|
18
|
+
file.mime_type = new_mime_type(directives.fetch(:format))
|
19
|
+
object = directives.fetch(:object)
|
20
|
+
type = directives.fetch(:label)
|
21
|
+
Hydra::Works::AddFileToFileSet.call(object, file, type, update_existing: true, versioning: false)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.new_mime_type(format)
|
25
|
+
case format
|
26
|
+
when 'mp4'
|
27
|
+
'video/mp4' # default is application/mp4
|
28
|
+
when 'webm'
|
29
|
+
'video/webm' # default is audio/webm
|
30
|
+
else
|
31
|
+
MIME::Types.type_for(format).first.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module Hydra::Works
|
2
|
-
class
|
2
|
+
class UploadFileToFileSet
|
3
3
|
# Sets a file as the primary file (original_file) of the generic_file
|
4
|
-
# @param [Hydra::PCDM::
|
4
|
+
# @param [Hydra::PCDM::FileSet] generic_file the file will be added to
|
5
5
|
# @param [IO,File,Rack::Multipart::UploadedFile, #read] object that will be the contents. If file responds to :mime_type or :original_name, those will be called to provide technical metadata.
|
6
6
|
# @param [Array] additional_services (ie Generating Thumbnails) to call with generic_file after adding the file as its original_file
|
7
7
|
# @param [Boolean] update_existing whether to update an existing file if there is one. When set to true, performs a create_or_update. When set to false, always creates a new file within generic_file.files.
|
8
8
|
# @param [Boolean] versioning whether to create new version entries (only applicable if +type+ corresponds to a versionable file)
|
9
9
|
|
10
10
|
def self.call(generic_file, file, additional_services: [], update_existing: true, versioning: true)
|
11
|
-
Hydra::Works::
|
11
|
+
Hydra::Works::AddFileToFileSet.call(generic_file, file, :original_file, update_existing: update_existing, versioning: versioning)
|
12
12
|
|
13
13
|
# Call any additional services
|
14
14
|
additional_services.each do |service|
|