ddr-models 2.7.6 → 2.8.0.rc1

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/collection.rb +1 -1
  3. data/app/models/component.rb +22 -31
  4. data/config/initializers/active_fedora_base.rb +8 -0
  5. data/config/locales/ddr-models.en.yml +4 -0
  6. data/lib/ddr/datastreams.rb +12 -10
  7. data/lib/ddr/datastreams/administrative_metadata_datastream.rb +6 -0
  8. data/lib/ddr/datastreams/streamable_media_datastream.rb +5 -0
  9. data/lib/ddr/index/fields.rb +7 -5
  10. data/lib/ddr/managers/derivatives_manager.rb +12 -7
  11. data/lib/ddr/models.rb +19 -9
  12. data/lib/ddr/models/base.rb +10 -3
  13. data/lib/ddr/models/file_management.rb +1 -1
  14. data/lib/ddr/models/has_admin_metadata.rb +8 -9
  15. data/lib/ddr/models/indexing.rb +18 -3
  16. data/lib/ddr/models/language.rb +31 -0
  17. data/lib/ddr/models/media_type.rb +22 -0
  18. data/lib/ddr/models/{licenses/license.rb → rights_statement.rb} +3 -7
  19. data/lib/ddr/models/solr_document.rb +22 -2
  20. data/lib/ddr/models/streamable.rb +22 -0
  21. data/lib/ddr/models/version.rb +1 -1
  22. data/lib/ddr/utils.rb +4 -4
  23. data/lib/ddr/vocab/asset.rb +8 -0
  24. data/spec/factories/collection_factories.rb +1 -0
  25. data/spec/index/fields_spec.rb +18 -0
  26. data/spec/managers/derivatives_manager_spec.rb +2 -5
  27. data/spec/models/active_fedora_base_spec.rb +3 -0
  28. data/spec/models/admin_set_spec.rb +2 -1
  29. data/spec/models/attachment_spec.rb +1 -0
  30. data/spec/models/collection_spec.rb +4 -7
  31. data/spec/models/component_spec.rb +20 -5
  32. data/spec/models/has_struct_metadata_spec.rb +0 -1
  33. data/spec/models/indexing_spec.rb +91 -44
  34. data/spec/models/item_spec.rb +1 -0
  35. data/spec/models/language_spec.rb +59 -0
  36. data/spec/models/media_type_spec.rb +46 -0
  37. data/spec/models/{license_spec.rb → rights_statement_spec.rb} +9 -12
  38. data/spec/models/solr_document_spec.rb +57 -2
  39. data/spec/models/target_spec.rb +1 -0
  40. data/spec/spec_helper.rb +11 -0
  41. data/spec/support/shared_examples_for_ddr_models.rb +12 -0
  42. data/spec/support/shared_examples_for_governables.rb +2 -1
  43. data/spec/support/shared_examples_for_streamable_media.rb +22 -0
  44. metadata +17 -13
  45. data/lib/ddr/models/licenses/admin_policy_license.rb +0 -11
  46. data/lib/ddr/models/licenses/effective_license.rb +0 -9
  47. data/lib/ddr/models/licenses/inherited_license.rb +0 -9
  48. data/lib/ddr/models/licenses/parent_license.rb +0 -11
  49. data/spec/models/effective_license_spec.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb09816423a70527f2896ba5ada6668bf0cc3725
4
- data.tar.gz: a989e2330e2bc993e73af0e75efba97be293bf2d
3
+ metadata.gz: b0a6fc7039cab0864972b389421c54237721aa5a
4
+ data.tar.gz: b3d4b6c668ea5df6435848d18421e324d49ee1ac
5
5
  SHA512:
6
- metadata.gz: 2fd4878f7451fe570bc7c3a26126656c0b66e378c765987ff3d1438d35cb060baa23274446dd70a4b2c0626f66f692e398d0c133cfcc210fd6c5d8219e51744b
7
- data.tar.gz: c182db4d3dcedccee776cae12616788692723a56cbd761481aa7b62eab6ae7de7a808d23e5ed14182e95927248bc780e4a805e424c3cb4d42292d26adfd7b88b
6
+ metadata.gz: 40416d278fcb502dab7e4e36d2436b52ed0bacefe51f5bf8fd15fd1a3f0e413ff18e812f56c8269cf0c81bf03b7a1c938a4620609b79d5f98f4e1275332da82a
7
+ data.tar.gz: 53a3e965d7ee5bfa142dc112fb6983d6d616a634b4119283a2de9c04b5437004b0427a677f38fb3d3f81a764196d834275210ce2abe59415b561c4bf98f3e111
@@ -15,7 +15,7 @@ class Collection < Ddr::Models::Base
15
15
 
16
16
  after_create :set_admin_policy, unless: :admin_policy
17
17
 
18
- validates_presence_of :title
18
+ validates_presence_of :admin_set, :title
19
19
 
20
20
  # Returns the SolrDocuments for Components associated with the Collection.
21
21
  #
@@ -9,6 +9,7 @@ class Component < Ddr::Models::Base
9
9
  include Ddr::Models::HasIntermediateFile
10
10
  include Ddr::Models::HasMultiresImage
11
11
  include Ddr::Models::HasStructMetadata
12
+ include Ddr::Models::Streamable
12
13
 
13
14
  belongs_to :parent, :property => :is_part_of, :class_name => 'Item'
14
15
  belongs_to :target, :property => :has_external_target, :class_name => 'Target'
@@ -44,42 +45,32 @@ class Component < Ddr::Models::Base
44
45
  structmap = structure.add_structmap(type: Ddr::Models::Structure::TYPE_DEFAULT)
45
46
  div = structure.add_div(parent: structmap)
46
47
  filegrp = structure.add_filegrp(parent: filesec)
47
- add_original_file(structure, filegrp, div)
48
- add_preservation_master_file(structure, filegrp, div)
49
- add_intermediate_file(structure, filegrp, div) if has_intermediate_file?
50
- add_service_file(structure, filegrp, div)
51
- add_thumbnail_image(structure, filegrp, div) if has_thumbnail?
48
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_ORIGINAL_FILE,
49
+ Ddr::Datastreams::CONTENT)
50
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_PRESERVATION_MASTER_FILE,
51
+ Ddr::Datastreams::CONTENT)
52
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_INTERMEDIATE_FILE,
53
+ Ddr::Datastreams::INTERMEDIATE_FILE) if has_intermediate_file?
54
+ add_service_file_uses_to_default_structure(structure, filegrp, div)
55
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_THUMBNAIL_IMAGE,
56
+ Ddr::Datastreams::THUMBNAIL) if has_thumbnail?
52
57
  structure
53
58
  end
54
59
 
55
- def add_original_file(structure, filegrp, div)
56
- file = structure.add_file(parent: filegrp, use: Ddr::Models::Structure::USE_ORIGINAL_FILE)
57
- structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: Ddr::Datastreams::CONTENT)
58
- structure.add_fptr(parent: div, fileid: file['ID'])
59
- end
60
-
61
- def add_preservation_master_file(structure, filegrp, div)
62
- file = structure.add_file(parent: filegrp, use: Ddr::Models::Structure::USE_PRESERVATION_MASTER_FILE)
63
- structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: Ddr::Datastreams::CONTENT)
64
- structure.add_fptr(parent: div, fileid: file['ID'])
65
- end
66
-
67
- def add_intermediate_file(structure, filegrp, div)
68
- file = structure.add_file(parent: filegrp, use: Ddr::Models::Structure::USE_INTERMEDIATE_FILE)
69
- structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: Ddr::Datastreams::INTERMEDIATE_FILE)
70
- structure.add_fptr(parent: div, fileid: file['ID'])
71
- end
72
-
73
- def add_service_file(structure, filegrp, div)
74
- file = structure.add_file(parent: filegrp, use: Ddr::Models::Structure::USE_SERVICE_FILE)
75
- service_file = has_multires_image? ? Ddr::Datastreams::MULTIRES_IMAGE : Ddr::Datastreams::CONTENT
76
- structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: service_file)
77
- structure.add_fptr(parent: div, fileid: file['ID'])
60
+ def add_service_file_uses_to_default_structure(structure, filegrp, div)
61
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_SERVICE_FILE,
62
+ Ddr::Datastreams::MULTIRES_IMAGE) if has_multires_image?
63
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_SERVICE_FILE,
64
+ Ddr::Datastreams::STREAMABLE_MEDIA) if streamable?
65
+ if !has_multires_image? && !streamable?
66
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_SERVICE_FILE,
67
+ Ddr::Datastreams::CONTENT)
68
+ end
78
69
  end
79
70
 
80
- def add_thumbnail_image(structure, filegrp, div)
81
- file = structure.add_file(parent: filegrp, use: Ddr::Models::Structure::USE_THUMBNAIL_IMAGE)
82
- structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: Ddr::Datastreams::THUMBNAIL)
71
+ def add_use_to_structure(structure, filegrp, div, use, datastream_name)
72
+ file = structure.add_file(parent: filegrp, use: use)
73
+ structure.add_flocat(parent: file, loctype: 'OTHER', otherloctype: 'AttachedFile', href: datastream_name)
83
74
  structure.add_fptr(parent: div, fileid: file['ID'])
84
75
  end
85
76
 
@@ -69,6 +69,14 @@ module ActiveFedora
69
69
  can_have_thumbnail? && thumbnail.has_content?
70
70
  end
71
71
 
72
+ def can_be_streamable?
73
+ datastreams.include? Ddr::Datastreams::STREAMABLE_MEDIA
74
+ end
75
+
76
+ def streamable?
77
+ can_be_streamable? && datastreams[Ddr::Datastreams::STREAMABLE_MEDIA].has_content?
78
+ end
79
+
72
80
  def safe_id
73
81
  id.sub(/:/, "-")
74
82
  end
@@ -8,6 +8,8 @@ en:
8
8
  active_fedora_model:
9
9
  label: Model
10
10
  heading: model
11
+ aleph_id:
12
+ label: "Aleph ID"
11
13
  aspace_id:
12
14
  label: "ArchivesSpace ID"
13
15
  doi:
@@ -16,6 +18,8 @@ en:
16
18
  label: "EAD ID"
17
19
  local_id:
18
20
  label: "Local ID"
21
+ streamable_media_url:
22
+ label: "Streamable Media URL"
19
23
  system_create:
20
24
  label: "Creation Date"
21
25
  heading: creation_date
@@ -4,17 +4,18 @@ module Ddr
4
4
  module Datastreams
5
5
  extend ActiveSupport::Autoload
6
6
 
7
- ADMIN_METADATA = "adminMetadata"
8
- CONTENT = "content"
9
- DC = "DC"
10
- DESC_METADATA = "descMetadata"
11
- EXTRACTED_TEXT = "extractedText"
12
- FITS = "fits".freeze
7
+ ADMIN_METADATA = "adminMetadata"
8
+ CONTENT = "content"
9
+ DC = "DC"
10
+ DESC_METADATA = "descMetadata"
11
+ EXTRACTED_TEXT = "extractedText"
12
+ FITS = "fits".freeze
13
13
  INTERMEDIATE_FILE = "intermediateFile".freeze
14
- MULTIRES_IMAGE = "multiresImage"
15
- RELS_EXT = "RELS-EXT"
16
- STRUCT_METADATA = "structMetadata"
17
- THUMBNAIL = "thumbnail"
14
+ MULTIRES_IMAGE = "multiresImage"
15
+ RELS_EXT = "RELS-EXT"
16
+ STREAMABLE_MEDIA = "streamableMedia"
17
+ STRUCT_METADATA = "structMetadata"
18
+ THUMBNAIL = "thumbnail"
18
19
 
19
20
  SAVE = "save.repo_file"
20
21
  DELETE = "delete.repo_file"
@@ -38,6 +39,7 @@ module Ddr
38
39
  autoload :MetadataDatastream
39
40
  autoload :MultiresImageDatastream
40
41
  autoload :PlainTextDatastream
42
+ autoload :StreamableMediaDatastream
41
43
  autoload :StructuralMetadataDatastream
42
44
 
43
45
  mattr_accessor :update_derivatives_on_changed do
@@ -61,6 +61,12 @@ module Ddr
61
61
  property :rights_note,
62
62
  predicate: Ddr::Vocab::Asset.rightsNote
63
63
 
64
+ property :aleph_id,
65
+ predicate: Ddr::Vocab::Asset.alephId
66
+
67
+ property :affiliation,
68
+ predicate: Ddr::Vocab::Asset.affiliation
69
+
64
70
  end
65
71
  end
66
72
  end
@@ -0,0 +1,5 @@
1
+ module Ddr::Datastreams
2
+ class StreamableMediaDatastream < ExternalFileDatastream
3
+
4
+ end
5
+ end
@@ -9,6 +9,9 @@ module Ddr::Index
9
9
  ADMIN_SET = Field.new :admin_set, :stored_sortable
10
10
  ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
11
11
  ADMIN_SET_TITLE = Field.new :admin_set_title, :stored_sortable
12
+ AFFILIATION = Field.new :affiliation, :stored_searchable
13
+ AFFILIATION_FACET = Field.new :affiliation_facet, :facetable
14
+ ALEPH_ID = Field.new :aleph_id, :stored_sortable
12
15
  ALL_TEXT = Field.new :all_text, solr_name: "all_text_timv"
13
16
  ARRANGER_FACET = Field.new :arranger_facet, :facetable
14
17
  ASPACE_ID = Field.new :aspace_id, :stored_sortable
@@ -56,6 +59,8 @@ module Ddr::Index
56
59
  IS_MEMBER_OF = Field.new :is_member_of, :symbol
57
60
  IS_MEMBER_OF_COLLECTION = Field.new :is_member_of_collection, :symbol
58
61
  IS_PART_OF = Field.new :is_part_of, :symbol
62
+ LANGUAGE_FACET = Field.new :language_facet, :facetable
63
+ LANGUAGE_NAME = Field.new :language_name, :stored_searchable
59
64
  LAST_FIXITY_CHECK_ON = Field.new :last_fixity_check_on, :stored_sortable, type: :date
60
65
  LAST_FIXITY_CHECK_OUTCOME = Field.new :last_fixity_check_outcome, :symbol
61
66
  LAST_VIRUS_CHECK_ON = Field.new :last_virus_check_on, :stored_sortable, type: :date
@@ -89,11 +94,8 @@ module Ddr::Index
89
94
  SERIES_FACET = Field.new :series_facet, :facetable
90
95
  SETTING_FACET = Field.new :setting_facet, :facetable
91
96
  SPATIAL_FACET = Field.new :spatial_facet, :facetable
92
- # STRUCT is interim index field to facilitate conversion of the STRUCTURE index field from
93
- # stored and indexed to just stored. The STRUCTURE field will eventually be pointed to this
94
- # Field definition.
95
- STRUCT = Field.new :structure, solr_name: "structure_ss"
96
- STRUCTURE = Field.new :structure, :stored_sortable
97
+ STREAMABLE_MEDIA_TYPE = Field.new :streamable_media_type, :stored_sortable
98
+ STRUCTURE = Field.new :structure, solr_name: "structure_ss"
97
99
  STRUCTURE_SOURCE = Field.new :structure_source, :stored_sortable
98
100
  SUBJECT_FACET = Field.new :subject_facet, :facetable
99
101
  SUBSERIES_FACET = Field.new :subseries_facet, :facetable
@@ -45,12 +45,12 @@ module Ddr::Managers
45
45
  tempdir_path = File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname('',nil))
46
46
  begin
47
47
  tempdir = FileUtils.mkdir(tempdir_path).first
48
- generator_source = create_source_file(tempdir)
49
- generator_output = File.new(File.join(tempdir, "output.out"), 'wb')
50
- exitstatus = derivative.generator.new(generator_source.path, generator_output.path, derivative.options).generate
51
- generator_source.close unless generator_source.closed?
48
+ generator_source_path = source_datastream.external? ? source_datastream.file_path
49
+ : create_source_file(source_datastream,tempdir)
50
+ generator_output_path = File.new(File.join(tempdir, "output.out"), 'wb').path
51
+ exitstatus = derivative.generator.new(generator_source_path, generator_output_path, derivative.options).generate
52
52
  if exitstatus == 0
53
- generator_output = File.open(generator_output, 'rb')
53
+ generator_output = File.open(generator_output_path, 'rb')
54
54
  object.reload if object.persisted?
55
55
  object.add_file generator_output, derivative.datastream, mime_type: derivative.generator.output_mime_type
56
56
  object.save!
@@ -75,6 +75,11 @@ module Ddr::Managers
75
75
 
76
76
  alias_method :delete_derivative, :delete_derivative!
77
77
 
78
+ def source_datastream
79
+ @source_datastream ||= object.has_intermediate_file? ? object.datastreams[Ddr::Datastreams::INTERMEDIATE_FILE]
80
+ : object.datastreams[Ddr::Datastreams::CONTENT]
81
+ end
82
+
78
83
  class DerivativeJob
79
84
  @queue = :derivatives
80
85
  def self.perform(pid, derivative_name)
@@ -86,9 +91,9 @@ module Ddr::Managers
86
91
 
87
92
  private
88
93
 
89
- def create_source_file(dir)
94
+ def create_source_file(datastream, dir)
90
95
  generator_source = File.new(File.join(dir, "source"), "wb")
91
- source_content = object.has_intermediate_file? ? object.intermediateFile.content : object.content.content
96
+ source_content = datastream.content
92
97
  generator_source.write(source_content)
93
98
  generator_source.close
94
99
  generator_source
@@ -58,24 +58,19 @@ module Ddr
58
58
  autoload :HasStructMetadata
59
59
  autoload :HasThumbnail
60
60
  autoload :Indexing
61
+ autoload :Language
62
+ autoload :MediaType
61
63
  autoload :NotFoundError, 'ddr/models/error'
62
64
  autoload :PermanentId
65
+ autoload :RightsStatement
63
66
  autoload :SolrDocument
67
+ autoload :Streamable
64
68
  autoload :Structure
65
69
  autoload :WithContentFile
66
70
  autoload :YearFacet
67
71
 
68
- autoload_under "licenses" do
69
- autoload :AdminPolicyLicense
70
- autoload :EffectiveLicense
71
- autoload :License
72
- autoload :InheritedLicense
73
- autoload :ParentLicense
74
- end
75
-
76
72
  module Structures
77
73
  extend ActiveSupport::Autoload
78
-
79
74
  autoload :Agent
80
75
  autoload :Div
81
76
  autoload :File
@@ -136,6 +131,21 @@ module Ddr
136
131
  "application/octet-stream"
137
132
  end
138
133
 
134
+ # Maps file extensions to preferred media types
135
+ mattr_accessor :preferred_media_types do
136
+ {
137
+ '.mp4' => 'video/mp4',
138
+ '.flv' => 'video/flv',
139
+ '.webm' => 'video/webm',
140
+ '.aac' => 'audio/mp4',
141
+ '.m4a' => 'audio/mp4',
142
+ '.f4a' => 'audio/mp4',
143
+ '.mp3' => 'audio/mpeg',
144
+ '.ogg' => 'audio/ogg',
145
+ '.oga' => 'audio/ogg',
146
+ }
147
+ end
148
+
139
149
  # Yields an object with module configuration accessors
140
150
  def self.configure
141
151
  yield self
@@ -1,6 +1,9 @@
1
1
  module Ddr
2
2
  module Models
3
3
  class Base < ActiveFedora::Base
4
+ extend Deprecation
5
+
6
+ self.deprecation_horizon = 'ddr-models v3.0'
4
7
 
5
8
  # Lifecycle events
6
9
  INGEST = "ingest.repo_object"
@@ -36,6 +39,12 @@ module Ddr
36
39
  around_deaccession :notify_deaccession
37
40
  around_destroy :notify_delete
38
41
 
42
+ def rights_statement
43
+ RightsStatement.call(self)
44
+ end
45
+ alias_method :effective_license, :rights_statement
46
+ deprecation_deprecate :effective_license
47
+
39
48
  def deaccession
40
49
  run_callbacks :deaccession do
41
50
  delete
@@ -102,9 +111,7 @@ module Ddr
102
111
  private
103
112
 
104
113
  def grant_default_roles
105
- if default_roles.present?
106
- roles.grant *default_roles
107
- end
114
+ roles.grant *default_roles
108
115
  end
109
116
 
110
117
  def default_roles
@@ -20,7 +20,7 @@ module Ddr::Models
20
20
  # Not required for external datastream classes
21
21
  # or datastream instances having controlGroup 'E'.
22
22
  def add_file(file, dsid, mime_type: nil, external: false, original_filename: nil)
23
- mime_type ||= Ddr::Utils.mime_type_for(file)
23
+ mime_type ||= MediaType.call(file) # XXX Should we use original_filename, if present?
24
24
  source_path = Ddr::Utils.file_path(file)
25
25
  original_filename ||= Ddr::Utils.file_name(file)
26
26
  file_to_add = FileToAdd.new(dsid, source_path, original_filename)
@@ -1,6 +1,9 @@
1
1
  module Ddr::Models
2
2
  module HasAdminMetadata
3
3
  extend ActiveSupport::Concern
4
+ extend Deprecation
5
+
6
+ self.deprecation_horizon = 'ddr-models v3.0'
4
7
 
5
8
  included do
6
9
  has_metadata "adminMetadata",
@@ -23,10 +26,14 @@ module Ddr::Models
23
26
  :doi,
24
27
  :ingested_by,
25
28
  :ingestion_date,
29
+ :aleph_id,
26
30
  datastream: "adminMetadata",
27
31
  multiple: false
28
32
 
29
- has_attributes :rights_note, datastream: "adminMetadata", multiple: true
33
+ has_attributes :affiliation,
34
+ :rights_note,
35
+ datastream: "adminMetadata",
36
+ multiple: true
30
37
 
31
38
  delegate :publish!, :unpublish!, :published?, :unpublished?,
32
39
  to: :workflow
@@ -62,14 +69,6 @@ module Ddr::Models
62
69
  Ddr::Models::Contact.call(research_help_contact) if research_help_contact
63
70
  end
64
71
 
65
- def effective_license
66
- EffectiveLicense.call(self)
67
- end
68
-
69
- def inherited_license
70
- InheritedLicense.call(self)
71
- end
72
-
73
72
  def finding_aid
74
73
  if ead_id
75
74
  FindingAid.new(ead_id)
@@ -19,6 +19,9 @@ module Ddr::Models
19
19
  ACCESS_ROLE => roles.to_json,
20
20
  ADMIN_SET => admin_set,
21
21
  ADMIN_SET_TITLE => admin_set_title,
22
+ AFFILIATION => affiliation,
23
+ AFFILIATION_FACET => affiliation,
24
+ ALEPH_ID => aleph_id,
22
25
  ARRANGER_FACET => desc_metadata_values('arranger'),
23
26
  ASPACE_ID => aspace_id,
24
27
  ATTACHED_FILES_HAVING_CONTENT => attached_files_having_content.keys,
@@ -50,6 +53,8 @@ module Ddr::Models
50
53
  INTERVIEWER_NAME_FACET => desc_metadata_values('interviewer_name'),
51
54
  IS_FORMAT_OF => desc_metadata_values('isFormatOf'),
52
55
  IS_LOCKED => is_locked,
56
+ LANGUAGE_FACET => language_name,
57
+ LANGUAGE_NAME => language_name,
53
58
  LICENSE => license,
54
59
  LITHOGRAPHER_FACET => desc_metadata_values('lithographer'),
55
60
  LOCAL_ID => local_id,
@@ -103,14 +108,16 @@ module Ddr::Models
103
108
  fields[MULTIRES_IMAGE_FILE_PATH] = multires_image_file_path
104
109
  end
105
110
  if has_struct_metadata?
106
- # STRUCT is an interim index field to facilitate conversion of STRUCTURE field definition.
107
- fields[STRUCT] = fields[STRUCTURE] = structure.dereferenced_structure.to_json
111
+ fields[STRUCTURE] = structure.dereferenced_structure.to_json
108
112
  fields[STRUCTURE_SOURCE] = structure.repository_maintained? ? Ddr::Models::Structure::REPOSITORY_MAINTAINED
109
113
  : Ddr::Models::Structure::EXTERNALLY_PROVIDED
110
114
  end
111
115
  if has_extracted_text?
112
116
  fields[EXTRACTED_TEXT] = extractedText.content
113
117
  end
118
+ if streamable?
119
+ fields[STREAMABLE_MEDIA_TYPE] = streamable_media_type
120
+ end
114
121
  if is_a? Component
115
122
  fields[COLLECTION_URI] = collection_uri
116
123
  end
@@ -156,8 +163,10 @@ module Ddr::Models
156
163
  admin_set
157
164
  elsif associated_collection.present?
158
165
  associated_collection.admin_set
166
+ else
167
+ nil
159
168
  end
160
- if as = AdminSet.find_by_code(code)
169
+ if code && ( as = AdminSet.find_by_code(code) )
161
170
  as.title
162
171
  end
163
172
  end
@@ -178,6 +187,12 @@ module Ddr::Models
178
187
  date.first
179
188
  end
180
189
 
190
+ def language_name
191
+ language.map do |lang|
192
+ Language.find_by_code(lang).to_s rescue lang
193
+ end
194
+ end
195
+
181
196
  def year_facet
182
197
  YearFacet.call(self)
183
198
  end