ddr-models 2.8.0 → 2.9.0.rc1

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: 4826c97c7faaee06b8ecd52dc5a322bc5a56acb9
4
- data.tar.gz: 42e1c7666e775cd37451848e53cc07e378022d77
3
+ metadata.gz: 0cc0364fbbf04479e361ddf450e21d70aa9d9f21
4
+ data.tar.gz: a18facc359b48603080daf6cbf8f82b22e41a15e
5
5
  SHA512:
6
- metadata.gz: 1e6d24131304e7d017acd556de2db085496b103f59f58dc5d8350d9a9e95caea811254dc44be950c758629fcc97665a971803926a7ee5d1ef263e73f07fa064b
7
- data.tar.gz: a13fa84b44a46e9890135443b36780d30e39c3923ed7eed54712b29069b556a5f94e6dfb87833103950600088f66e4dfe85143e5fd43f4b529e74652a4fc0148
6
+ metadata.gz: 08988037c01145241f52c2914b5f0330d93b79865e1effbdcea509f79b42b2a926956ec8aa049b406a788385d534f252f180aad054899618175598eefd1fcc87
7
+ data.tar.gz: 4bdc44aaf67465193eac2c5302a5f30abcefe6b60df8bb44653083f8f3f0441346a907df6a7b74fa53c880dd8cf9820537ca1365a0ca8d9802c7d5f7233c6864
@@ -1,3 +1,4 @@
1
+ require 'htmlentities'
1
2
  #
2
3
  # A Collection is a conceptual and administrative entity containing a set of items.
3
4
  #
@@ -51,6 +52,10 @@ class Collection < Ddr::Models::Base
51
52
  true
52
53
  end
53
54
 
55
+ def default_structure
56
+ build_default_structure
57
+ end
58
+
54
59
  private
55
60
 
56
61
  def default_roles
@@ -69,4 +74,54 @@ class Collection < Ddr::Models::Base
69
74
  save!
70
75
  end
71
76
 
77
+ def build_default_structure
78
+ document = Ddr::Models::Structure.xml_template
79
+ structure = Ddr::Models::Structure.new(document)
80
+ metshdr = structure.add_metshdr
81
+ structure.add_agent(parent: metshdr, role: Ddr::Models::Structures::Agent::ROLE_CREATOR,
82
+ name: Ddr::Models::Structures::Agent::NAME_REPOSITORY_DEFAULT)
83
+ structmap = structure.add_structmap(type: Ddr::Models::Structure::TYPE_DEFAULT)
84
+ add_items_to_structure(structure, structmap)
85
+ structure
86
+ end
87
+
88
+ def add_items_to_structure(structure, structmap)
89
+ sorted_items_for_structure.each do |item|
90
+ if path = item[Ddr::Index::Fields::NESTED_PATH]
91
+ nest = path.split(File::SEPARATOR)
92
+ else
93
+ nest = []
94
+ end
95
+ find_or_create_div(structure, structmap, nest, item[Ddr::Index::Fields::PERMANENT_ID])
96
+ end
97
+ end
98
+
99
+ def find_or_create_div(structure, parent, nest, permanent_id)
100
+ label = nest.shift
101
+ order = parent.elements.count + 1
102
+ if nest.empty?
103
+ div = structure.add_div(parent: parent, order: order)
104
+ add_mptr(structure, div, permanent_id)
105
+ else
106
+ label = HTMLEntities.new.encode(label)
107
+ div = parent.xpath(%Q[xmlns:div[@LABEL="#{label}"]]).first ||
108
+ structure.add_div(parent: parent, type: 'Directory', label: label, order: order)
109
+ find_or_create_div(structure, div, nest, permanent_id)
110
+ end
111
+ end
112
+
113
+ def add_mptr(structure, div, permanent_id)
114
+ structure.add_mptr(parent: div, href: permanent_id)
115
+ end
116
+
117
+ def sorted_items_for_structure
118
+ ActiveFedora::SolrService.query(association_query(:children), sort: item_sort_for_structure, rows: 999999)
119
+ end
120
+
121
+ def item_sort_for_structure
122
+ "#{Ddr::Index::Fields::NESTED_PATH} ASC,
123
+ #{Ddr::Index::Fields::LOCAL_ID} ASC,
124
+ #{Ddr::Index::Fields::OBJECT_CREATE_DATE} ASC"
125
+ end
126
+
72
127
  end
@@ -5,6 +5,7 @@
5
5
  #
6
6
  class Component < Ddr::Models::Base
7
7
 
8
+ include Ddr::Models::Captionable
8
9
  include Ddr::Models::HasContent
9
10
  include Ddr::Models::HasIntermediateFile
10
11
  include Ddr::Models::HasMultiresImage
@@ -17,6 +18,10 @@ class Component < Ddr::Models::Base
17
18
  alias_method :item, :parent
18
19
  alias_method :item=, :parent=
19
20
 
21
+ STRUCTURALLY_RELEVANT_DATASTREAMS = [ Ddr::Datastreams::CAPTION, Ddr::Datastreams::CONTENT,
22
+ Ddr::Datastreams::INTERMEDIATE_FILE, Ddr::Datastreams::MULTIRES_IMAGE,
23
+ Ddr::Datastreams::STREAMABLE_MEDIA, Ddr::Datastreams::THUMBNAIL ]
24
+
20
25
  def collection
21
26
  self.parent.parent rescue nil
22
27
  end
@@ -30,7 +35,7 @@ class Component < Ddr::Models::Base
30
35
  end
31
36
 
32
37
  def default_structure
33
- build_default_structure if has_content?
38
+ build_default_structure
34
39
  end
35
40
 
36
41
  private
@@ -41,19 +46,24 @@ class Component < Ddr::Models::Base
41
46
  metshdr = structure.add_metshdr
42
47
  structure.add_agent(parent: metshdr, role: Ddr::Models::Structures::Agent::ROLE_CREATOR,
43
48
  name: Ddr::Models::Structures::Agent::NAME_REPOSITORY_DEFAULT)
44
- filesec = structure.add_filesec
45
49
  structmap = structure.add_structmap(type: Ddr::Models::Structure::TYPE_DEFAULT)
46
- div = structure.add_div(parent: structmap)
47
- filegrp = structure.add_filegrp(parent: filesec)
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?
50
+ if has_content?
51
+ filesec = structure.add_filesec
52
+ div = structure.add_div(parent: structmap)
53
+ filegrp = structure.add_filegrp(parent: filesec)
54
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_ORIGINAL_FILE,
55
+ Ddr::Datastreams::CONTENT)
56
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_PRESERVATION_MASTER_FILE,
57
+ Ddr::Datastreams::CONTENT)
58
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_INTERMEDIATE_FILE,
59
+ Ddr::Datastreams::INTERMEDIATE_FILE) if has_intermediate_file?
60
+ add_service_file_uses_to_default_structure(structure, filegrp, div)
61
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_THUMBNAIL_IMAGE,
62
+ Ddr::Datastreams::THUMBNAIL) if has_thumbnail?
63
+ add_use_to_structure(structure, filegrp, div, Ddr::Models::Structure::USE_TRANSCRIPT,
64
+ Ddr::Datastreams::CAPTION) if captioned?
65
+
66
+ end
57
67
  structure
58
68
  end
59
69
 
data/app/models/item.rb CHANGED
@@ -11,6 +11,8 @@ class Item < Ddr::Models::Base
11
11
  has_many :children, property: :is_part_of, class_name: 'Component'
12
12
  belongs_to :parent, property: :is_member_of_collection, class_name: 'Collection'
13
13
 
14
+ has_attributes :nested_path, datastream: Ddr::Datastreams::ADMIN_METADATA, multiple: false
15
+
14
16
  alias_method :components, :children
15
17
  alias_method :component_ids, :child_ids
16
18
 
@@ -37,4 +39,30 @@ class Item < Ddr::Models::Base
37
39
  children_having_extracted_text.docs.map(&:extracted_text).flatten
38
40
  end
39
41
 
42
+ def default_structure
43
+ build_default_structure
44
+ end
45
+
46
+ private
47
+
48
+ def build_default_structure
49
+ document = Ddr::Models::Structure.xml_template
50
+ structure = Ddr::Models::Structure.new(document)
51
+ metshdr = structure.add_metshdr
52
+ structure.add_agent(parent: metshdr, role: Ddr::Models::Structures::Agent::ROLE_CREATOR,
53
+ name: Ddr::Models::Structures::Agent::NAME_REPOSITORY_DEFAULT)
54
+ structmap = structure.add_structmap(type: Ddr::Models::Structure::TYPE_DEFAULT)
55
+ add_components_to_structure(structure, structmap)
56
+ structure
57
+ end
58
+
59
+ def add_components_to_structure(structure, structmap)
60
+ count = 0
61
+ sorted_children.each do |child|
62
+ count += 1
63
+ div = structure.add_div(parent: structmap, order: count)
64
+ structure.add_mptr(parent: div, href: child[Ddr::Index::Fields::PERMANENT_ID])
65
+ end
66
+ end
67
+
40
68
  end
@@ -69,6 +69,14 @@ module ActiveFedora
69
69
  can_have_thumbnail? && thumbnail.has_content?
70
70
  end
71
71
 
72
+ def captionable?
73
+ datastreams.include? Ddr::Datastreams::CAPTION
74
+ end
75
+
76
+ def captioned?
77
+ captionable? && datastreams[Ddr::Datastreams::CAPTION].has_content?
78
+ end
79
+
72
80
  def can_be_streamable?
73
81
  datastreams.include? Ddr::Datastreams::STREAMABLE_MEDIA
74
82
  end
@@ -5,6 +5,7 @@ module Ddr
5
5
  extend ActiveSupport::Autoload
6
6
 
7
7
  ADMIN_METADATA = "adminMetadata"
8
+ CAPTION = "caption"
8
9
  CONTENT = "content"
9
10
  DC = "DC"
10
11
  DESC_METADATA = "descMetadata"
@@ -29,6 +30,7 @@ module Ddr
29
30
  CHECKSUM_TYPES = [ CHECKSUM_TYPE_MD5, CHECKSUM_TYPE_SHA1, CHECKSUM_TYPE_SHA256, CHECKSUM_TYPE_SHA384, CHECKSUM_TYPE_SHA512 ]
30
31
 
31
32
  autoload :AdministrativeMetadataDatastream
33
+ autoload :CaptionDatastream
32
34
  autoload :ContentDatastream
33
35
  autoload :DatastreamBehavior
34
36
  autoload :DeleteExternalFiles
@@ -15,6 +15,9 @@ module Ddr
15
15
  index.as :stored_sortable
16
16
  end
17
17
 
18
+ property :nested_path,
19
+ predicate: Ddr::Vocab::Asset.nestedPath
20
+
18
21
  property :workflow_state,
19
22
  predicate: Ddr::Vocab::Asset.workflowState
20
23
 
@@ -0,0 +1,5 @@
1
+ module Ddr::Datastreams
2
+ class CaptionDatastream < ExternalFileDatastream
3
+
4
+ end
5
+ end
@@ -74,6 +74,8 @@ module Ddr::Index
74
74
  MEDIA_TYPE = Field.new :content_media_type, :symbol
75
75
  MEDIUM_FACET = Field.new :medium_facet, :facetable
76
76
  MULTIRES_IMAGE_FILE_PATH = Field.new :multires_image_file_path, :stored_sortable
77
+ NESTED_PATH = Field.new :nested_path, :stored_sortable
78
+ NESTED_PATH_TEXT = Field.new :nested_path_text, :searchable
77
79
  OBJECT_PROFILE = Field.new :object_profile, :displayable
78
80
  OBJECT_STATE = Field.new :object_state, :stored_sortable
79
81
  OBJECT_CREATE_DATE = Field.new :system_create, :stored_sortable, type: :date
data/lib/ddr/models.rb CHANGED
@@ -37,6 +37,7 @@ module Ddr
37
37
  autoload :AdminSet
38
38
  autoload :Base
39
39
  autoload :Cache
40
+ autoload :Captionable
40
41
  autoload :ChecksumInvalid, 'ddr/models/error'
41
42
  autoload :Contact
42
43
  autoload :ContentModelError, 'ddr/models/error'
@@ -134,15 +135,36 @@ module Ddr
134
135
  # Maps file extensions to preferred media types
135
136
  mattr_accessor :preferred_media_types do
136
137
  {
137
- '.mp4' => 'video/mp4',
138
- '.flv' => 'video/flv',
139
- '.webm' => 'video/webm',
140
138
  '.aac' => 'audio/mp4',
141
- '.m4a' => 'audio/mp4',
142
139
  '.f4a' => 'audio/mp4',
140
+ '.flv' => 'video/flv',
141
+ '.m4a' => 'audio/mp4',
142
+ '.mov' => 'video/quicktime',
143
143
  '.mp3' => 'audio/mpeg',
144
- '.ogg' => 'audio/ogg',
144
+ '.mp4' => 'video/mp4',
145
145
  '.oga' => 'audio/ogg',
146
+ '.ogg' => 'audio/ogg',
147
+ '.srt' => 'text/plain',
148
+ '.vtt' => 'text/vtt',
149
+ '.wav' => 'audio/wav',
150
+ '.webm' => 'video/webm',
151
+ '.zip' => 'application/zip'
152
+ }
153
+ end
154
+
155
+ # Maps media types to preferred file extensions
156
+ mattr_accessor :preferred_file_extensions do
157
+ {
158
+ 'application/zip' => 'zip',
159
+ 'audio/mp4' => 'm4a',
160
+ 'audio/mpeg' => 'mp3',
161
+ 'audio/ogg' => 'ogg',
162
+ 'audio/wav' => 'wav',
163
+ 'text/vtt' => 'vtt',
164
+ 'video/flv' => 'flv',
165
+ 'video/mp4' => 'mp4',
166
+ 'video/quicktime' => 'mov',
167
+ 'video/webm' => 'webm'
146
168
  }
147
169
  end
148
170
 
@@ -31,8 +31,8 @@ module Ddr
31
31
  before_create :set_ingested_by, if: :performed_by, unless: :ingested_by
32
32
  before_create :grant_default_roles
33
33
 
34
- after_create :notify_ingest
35
34
  after_create :assign_permanent_id!, if: :assign_permanent_id?
35
+ after_create :notify_ingest
36
36
 
37
37
  around_save :notify_update, unless: :new_record?
38
38
 
@@ -95,6 +95,10 @@ module Ddr
95
95
  datastreams.select { |dsid, ds| ds.changed? }
96
96
  end
97
97
 
98
+ def new_datastreams_having_content
99
+ datastreams.select { |dsid, ds| ds.new? && ds.has_content? }
100
+ end
101
+
98
102
  def datastreams_having_content
99
103
  datastreams.select { |dsid, ds| ds.has_content? }
100
104
  end
@@ -108,6 +112,12 @@ module Ddr
108
112
  end
109
113
  end
110
114
 
115
+ def parent_id
116
+ parent.id
117
+ rescue NoMethodError
118
+ nil
119
+ end
120
+
111
121
  private
112
122
 
113
123
  def grant_default_roles
@@ -141,7 +151,9 @@ module Ddr
141
151
  .merge(pid: pid,
142
152
  user_key: performed_by,
143
153
  permanent_id: permanent_id,
144
- model: self.class.to_s)
154
+ model: self.class.to_s,
155
+ parent: parent_id,
156
+ skip_structure_updates: cache.fetch(:skip_structure_updates, false))
145
157
  end
146
158
 
147
159
  def notify_ingest
@@ -156,6 +168,7 @@ module Ddr
156
168
  event_params = default_notification_payload.merge(
157
169
  attributes_changed: changes,
158
170
  datastreams_changed: datastreams_changed.keys,
171
+ new_datastreams: new_datastreams_having_content.keys,
159
172
  skip_update_derivatives: cache.fetch(:skip_update_derivatives, false)
160
173
  )
161
174
  ActiveSupport::Notifications.instrument(UPDATE, event_params) do |payload|
@@ -0,0 +1,37 @@
1
+ module Ddr::Models
2
+ module Captionable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_file_datastream name: Ddr::Datastreams::CAPTION,
7
+ type: Ddr::Datastreams::CaptionDatastream,
8
+ versionable: true,
9
+ label: "Caption file for this object",
10
+ control_group: "E"
11
+ end
12
+
13
+ def caption_type
14
+ datastreams[Ddr::Datastreams::CAPTION].mimeType
15
+ end
16
+
17
+ def caption_extension
18
+ extensions = Ddr::Models.preferred_file_extensions
19
+ if extensions.include? caption_type
20
+ extensions[caption_type]
21
+ else
22
+ caption_extension_default
23
+ end
24
+ end
25
+
26
+ def caption_path
27
+ datastreams[Ddr::Datastreams::CAPTION].file_path
28
+ end
29
+
30
+ private
31
+
32
+ def caption_extension_default
33
+ datastreams[Ddr::Datastreams::CAPTION].default_file_extension
34
+ end
35
+
36
+ end
37
+ end
@@ -8,38 +8,10 @@ module Ddr
8
8
  ActiveFedora::SolrService.lazy_reify_solr_results(sorted_children).first
9
9
  end
10
10
 
11
- def default_structure
12
- if children.present?
13
- build_default_structure
14
- end
15
- end
16
-
17
11
  def sorted_children
18
12
  ActiveFedora::SolrService.query(association_query(:children), sort: DEFAULT_SORT, rows: 999999)
19
13
  end
20
14
 
21
- private
22
-
23
- def build_default_structure
24
- document = Ddr::Models::Structure.xml_template
25
- structure = Ddr::Models::Structure.new(document)
26
- metshdr = structure.add_metshdr
27
- structure.add_agent(parent: metshdr, role: Ddr::Models::Structures::Agent::ROLE_CREATOR,
28
- name: Ddr::Models::Structures::Agent::NAME_REPOSITORY_DEFAULT)
29
- structmap = structure.add_structmap(type: Ddr::Models::Structure::TYPE_DEFAULT)
30
- add_children(structure, structmap, sorted_children)
31
- structure
32
- end
33
-
34
- def add_children(structure, structmap, children)
35
- count = 0
36
- children.each do |child|
37
- count += 1
38
- div = structure.add_div(parent: structmap, order: count)
39
- structure.add_mptr(parent: div, href: child[Ddr::Index::Fields::PERMANENT_ID])
40
- end
41
- end
42
-
43
15
  end
44
16
  end
45
17
  end
@@ -13,6 +13,29 @@ module Ddr
13
13
  include FileManagement
14
14
  end
15
15
 
16
+ def intermediate_type
17
+ datastreams[Ddr::Datastreams::INTERMEDIATE_FILE].mimeType
18
+ end
19
+
20
+ def intermediate_extension
21
+ extensions = Ddr::Models.preferred_file_extensions
22
+ if extensions.include? intermediate_type
23
+ extensions[intermediate_type]
24
+ else
25
+ intermediate_extension_default
26
+ end
27
+ end
28
+
29
+ def intermediate_path
30
+ datastreams[Ddr::Datastreams::INTERMEDIATE_FILE].file_path
31
+ end
32
+
33
+ private
34
+
35
+ def intermediate_extension_default
36
+ datastreams[Ddr::Datastreams::INTERMEDIATE_FILE].default_file_extension
37
+ end
38
+
16
39
  end
17
40
  end
18
41
  end