cocina_display 1.1.3 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.standard.yml +1 -1
- data/README.md +21 -2
- data/config/i18n-tasks.yml +0 -0
- data/config/licenses.yml +59 -0
- data/config/locales/en.yml +109 -0
- data/config/marc_countries.yml +385 -0
- data/config/marc_relators.yml +310 -0
- data/config/searchworks_languages.yml +520 -0
- data/lib/cocina_display/cocina_record.rb +29 -64
- data/lib/cocina_display/concerns/accesses.rb +78 -0
- data/lib/cocina_display/concerns/contributors.rb +32 -11
- data/lib/cocina_display/concerns/events.rb +19 -6
- data/lib/cocina_display/concerns/forms.rb +98 -11
- data/lib/cocina_display/concerns/geospatial.rb +9 -5
- data/lib/cocina_display/concerns/identifiers.rb +25 -5
- data/lib/cocina_display/concerns/languages.rb +6 -2
- data/lib/cocina_display/concerns/notes.rb +36 -0
- data/lib/cocina_display/concerns/related_resources.rb +20 -0
- data/lib/cocina_display/concerns/subjects.rb +25 -8
- data/lib/cocina_display/concerns/titles.rb +67 -25
- data/lib/cocina_display/concerns/{access.rb → url_helpers.rb} +3 -3
- data/lib/cocina_display/concerns.rb +6 -0
- data/lib/cocina_display/contributors/contributor.rb +47 -26
- data/lib/cocina_display/contributors/name.rb +18 -14
- data/lib/cocina_display/contributors/role.rb +31 -13
- data/lib/cocina_display/dates/date.rb +55 -14
- data/lib/cocina_display/dates/date_range.rb +0 -2
- data/lib/cocina_display/description/access.rb +41 -0
- data/lib/cocina_display/description/access_contact.rb +11 -0
- data/lib/cocina_display/description/url.rb +17 -0
- data/lib/cocina_display/display_data.rb +104 -0
- data/lib/cocina_display/events/event.rb +8 -4
- data/lib/cocina_display/events/imprint.rb +0 -10
- data/lib/cocina_display/events/location.rb +9 -3
- data/lib/cocina_display/events/note.rb +33 -0
- data/lib/cocina_display/forms/form.rb +71 -0
- data/lib/cocina_display/forms/genre.rb +12 -0
- data/lib/cocina_display/forms/resource_type.rb +38 -0
- data/lib/cocina_display/geospatial.rb +1 -1
- data/lib/cocina_display/identifier.rb +101 -0
- data/lib/cocina_display/json_backed_record.rb +27 -0
- data/lib/cocina_display/language.rb +18 -12
- data/lib/cocina_display/license.rb +32 -0
- data/lib/cocina_display/note.rb +103 -0
- data/lib/cocina_display/related_resource.rb +74 -0
- data/lib/cocina_display/subjects/subject.rb +32 -9
- data/lib/cocina_display/subjects/subject_value.rb +34 -16
- data/lib/cocina_display/title.rb +221 -0
- data/lib/cocina_display/utils.rb +4 -4
- data/lib/cocina_display/version.rb +1 -1
- data/lib/cocina_display.rb +32 -2
- metadata +46 -12
- data/lib/cocina_display/title_builder.rb +0 -397
- data/lib/cocina_display/vocabularies/marc_country_codes.rb +0 -393
- data/lib/cocina_display/vocabularies/marc_relator_codes.rb +0 -318
- data/lib/cocina_display/vocabularies/searchworks_languages.rb +0 -526
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Concerns
|
|
3
|
+
# Methods for extracting access/location information from a Cocina object.
|
|
4
|
+
module Accesses
|
|
5
|
+
# Display data for all access metadata except contact emails
|
|
6
|
+
# @return [Array<DisplayData>]
|
|
7
|
+
def access_display_data
|
|
8
|
+
CocinaDisplay::DisplayData.from_objects(accesses +
|
|
9
|
+
access_contacts.reject(&:contact_email?) +
|
|
10
|
+
purls +
|
|
11
|
+
urls)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Display data for all access contact email metadata
|
|
15
|
+
# @return [Array<DisplayData>]
|
|
16
|
+
def contact_email_display_data
|
|
17
|
+
CocinaDisplay::DisplayData.from_objects(access_contacts.select(&:contact_email?))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Display data for the use and reproduction statement.
|
|
21
|
+
# Exhibits and EarthWorks handle useAndReproductionStatement like descriptive metadata.
|
|
22
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
23
|
+
def use_and_reproduction_display_data
|
|
24
|
+
CocinaDisplay::DisplayData.from_strings([use_and_reproduction],
|
|
25
|
+
label: I18n.t("cocina_display.field_label.use_and_reproduction"))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Display data for the copyright statement.
|
|
29
|
+
# Exhibits and EarthWorks handle copyright like descriptive metadata.
|
|
30
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
31
|
+
def copyright_display_data
|
|
32
|
+
CocinaDisplay::DisplayData.from_strings([copyright],
|
|
33
|
+
label: I18n.t("cocina_display.field_label.copyright"))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def license_display_data
|
|
37
|
+
CocinaDisplay::DisplayData.from_strings([license_description],
|
|
38
|
+
label: I18n.t("cocina_display.field_label.license"))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# All access metadata except contact emails and URLs
|
|
42
|
+
# @return [Array<Description::Access>]
|
|
43
|
+
def accesses
|
|
44
|
+
@accesses ||= Enumerator::Chain.new(
|
|
45
|
+
path("$.description.access.physicalLocation.*"),
|
|
46
|
+
path("$.description.access.digitalLocation.*"),
|
|
47
|
+
path("$.description.access.digitalRepository.*")
|
|
48
|
+
).map { |a| CocinaDisplay::Description::Access.new(a) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# All access contact metadata
|
|
52
|
+
# @return [Array<Description::AccessContact>]
|
|
53
|
+
def access_contacts
|
|
54
|
+
path("$.description.access.accessContact.*").map do |contact|
|
|
55
|
+
CocinaDisplay::Description::AccessContact.new(contact)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# All access URL metadata
|
|
60
|
+
# @return [Array<Description::Url>]
|
|
61
|
+
def urls
|
|
62
|
+
path("$.description.access.url.*").map do |url|
|
|
63
|
+
CocinaDisplay::Description::Url.new(url)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# The Purl URL to combine with other access metadata
|
|
70
|
+
# @return [Array<DescriptiveValue>]
|
|
71
|
+
def purls
|
|
72
|
+
return [] unless purl_url.present?
|
|
73
|
+
|
|
74
|
+
CocinaDisplay::DisplayData.descriptive_values_from_strings([purl_url], label: I18n.t("cocina_display.field_label.purl"))
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require_relative "../contributors/contributor"
|
|
2
|
-
|
|
3
1
|
module CocinaDisplay
|
|
4
2
|
module Concerns
|
|
5
3
|
# Methods for finding and formatting names for contributors
|
|
@@ -20,20 +18,20 @@ module CocinaDisplay
|
|
|
20
18
|
# @param with_date [Boolean] Include life dates, if present
|
|
21
19
|
# @return [Array<String>]
|
|
22
20
|
def additional_contributor_names(with_date: false)
|
|
23
|
-
additional_contributors.
|
|
21
|
+
additional_contributors.flat_map { |c| c.display_names(with_date: with_date) }.compact
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
# All names of publishers, formatted for display.
|
|
27
25
|
# @return [Array<String>]
|
|
28
26
|
def publisher_names
|
|
29
|
-
publisher_contributors.
|
|
27
|
+
publisher_contributors.flat_map(&:display_names).compact
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
# All names of contributors who are people, formatted for display.
|
|
33
31
|
# @param with_date [Boolean] Include life dates, if present
|
|
34
32
|
# @return [Array<String>]
|
|
35
33
|
def person_contributor_names(with_date: false)
|
|
36
|
-
contributors.filter(&:person?).
|
|
34
|
+
contributors.filter(&:person?).flat_map { |c| c.display_names(with_date: with_date) }.compact
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
# All names of non-person contributors, formatted for display.
|
|
@@ -41,35 +39,58 @@ module CocinaDisplay
|
|
|
41
39
|
# @return [Array<String>]
|
|
42
40
|
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#contributor-types
|
|
43
41
|
def impersonal_contributor_names
|
|
44
|
-
contributors.reject(&:person?).
|
|
42
|
+
contributors.reject(&:person?).flat_map(&:display_names).compact
|
|
45
43
|
end
|
|
46
44
|
|
|
47
45
|
# All names of contributors that are organizations, formatted for display.
|
|
48
46
|
# @return [Array<String>]
|
|
49
47
|
def organization_contributor_names
|
|
50
|
-
contributors.filter(&:organization?).
|
|
48
|
+
contributors.filter(&:organization?).flat_map(&:display_names).compact
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
# All names of contributors that are conferences, formatted for display.
|
|
54
52
|
# @return [Array<String>]
|
|
55
53
|
def conference_contributor_names
|
|
56
|
-
contributors.filter(&:conference?).
|
|
54
|
+
contributors.filter(&:conference?).flat_map(&:display_names).compact
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
# A hash mapping role names to the names of contributors with that role.
|
|
60
58
|
# @param with_date [Boolean] Include life dates, if present
|
|
61
59
|
# @return [Hash<String, Array<String>>]
|
|
62
60
|
def contributor_names_by_role(with_date: false)
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
contributors_by_role(with_date: with_date)
|
|
62
|
+
.transform_values { |contributor_list| contributor_list.flat_map { |contributor| contributor.display_names(with_date: with_date) }.compact_blank }
|
|
63
|
+
.compact_blank
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# A hash mapping role names to the names of contributors with that role.
|
|
67
|
+
# @param with_date [Boolean] Include life dates, if present
|
|
68
|
+
# @return [Hash<[String,NilClass], Array<Contributor>>]
|
|
69
|
+
def contributors_by_role(with_date: false)
|
|
70
|
+
@contributors_by_role ||= contributors.each_with_object({}) do |contributor, hash|
|
|
71
|
+
if contributor.roles.empty?
|
|
72
|
+
hash[nil] ||= []
|
|
73
|
+
hash[nil] << contributor
|
|
74
|
+
else
|
|
65
75
|
contributor.roles.each do |role|
|
|
66
76
|
hash[role.to_s] ||= []
|
|
67
|
-
hash[role.to_s] <<
|
|
77
|
+
hash[role.to_s] << contributor
|
|
68
78
|
end
|
|
69
79
|
end
|
|
70
80
|
end
|
|
71
81
|
end
|
|
72
82
|
|
|
83
|
+
# DisplayData for Contributors, one per role.
|
|
84
|
+
# Contributors with no role are grouped under a default heading.
|
|
85
|
+
# @return [Array<DisplayData>]
|
|
86
|
+
def contributor_display_data
|
|
87
|
+
contributors_by_role.map do |role, contributors|
|
|
88
|
+
label = I18n.t(role, scope: "cocina_display.contributor.role",
|
|
89
|
+
default: role&.capitalize || I18n.t("default", scope: "cocina_display.contributor.role"))
|
|
90
|
+
DisplayData.new(label: label, objects: contributors)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
73
94
|
# A string value for sorting by contributor that sorts missing values last.
|
|
74
95
|
# Appends the sort title to break ties between contributor names.
|
|
75
96
|
# Ignores punctuation and leading/trailing spaces.
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
require_relative "../dates/date"
|
|
2
|
-
require_relative "../dates/date_range"
|
|
3
|
-
require_relative "../events/event"
|
|
4
|
-
require_relative "../events/imprint"
|
|
5
|
-
|
|
6
1
|
module CocinaDisplay
|
|
7
2
|
module Concerns
|
|
8
3
|
module Events
|
|
@@ -86,12 +81,18 @@ module CocinaDisplay
|
|
|
86
81
|
publication_events.flat_map { |event| event.locations.map(&:to_s) }
|
|
87
82
|
end
|
|
88
83
|
|
|
89
|
-
# All events associated with the object.
|
|
84
|
+
# All root level events associated with the object.
|
|
90
85
|
# @return [Array<CocinaDisplay::Events::Event>]
|
|
91
86
|
def events
|
|
92
87
|
@events ||= path("$.description.event.*").map { |event| CocinaDisplay::Events::Event.new(event) }
|
|
93
88
|
end
|
|
94
89
|
|
|
90
|
+
# The adminMetadata creation event (When was it was deposited?)
|
|
91
|
+
# @return <CocinaDisplay::Events::Event>
|
|
92
|
+
def admin_creation_event
|
|
93
|
+
@admin_events ||= path("$.description.adminMetadata.event[?(@.type==\"creation\")]").map { |event| CocinaDisplay::Events::Event.new(event) }.first
|
|
94
|
+
end
|
|
95
|
+
|
|
95
96
|
# All events that could be used to select a publication date.
|
|
96
97
|
# Includes publication, creation, and capture events.
|
|
97
98
|
# Considers event types as well as date types if the event is untyped.
|
|
@@ -121,6 +122,18 @@ module CocinaDisplay
|
|
|
121
122
|
@event_dates ||= events.flat_map(&:dates)
|
|
122
123
|
end
|
|
123
124
|
|
|
125
|
+
# DisplayData for all notes associated with events.
|
|
126
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
127
|
+
def event_note_display_data
|
|
128
|
+
CocinaDisplay::DisplayData.from_objects(events.flat_map(&:notes))
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# DisplayData for all dates associated with events.
|
|
132
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
133
|
+
def event_date_display_data
|
|
134
|
+
CocinaDisplay::DisplayData.from_objects(event_dates)
|
|
135
|
+
end
|
|
136
|
+
|
|
124
137
|
# The earliest preferred publication date as a CocinaDisplay::Dates::Date object.
|
|
125
138
|
# Considers publication, creation, and capture dates in that order.
|
|
126
139
|
# Prefers dates marked as primary and those with a declared encoding.
|
|
@@ -6,18 +6,24 @@ module CocinaDisplay
|
|
|
6
6
|
module Forms
|
|
7
7
|
# Resource types of the object, expressed in SearchWorks controlled vocabulary.
|
|
8
8
|
# @return [Array<String>]
|
|
9
|
-
def
|
|
9
|
+
def searchworks_resource_types
|
|
10
10
|
mapped_values = resource_type_values.flat_map { |resource_type| searchworks_resource_type(resource_type) }
|
|
11
11
|
mapped_values << "Dataset" if dataset?
|
|
12
12
|
mapped_values.uniq
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Resource types of the object, expressed in SearchWorks controlled vocabulary.
|
|
16
|
+
# @return [Array<String>]
|
|
17
|
+
def mods_resource_types
|
|
18
|
+
all_resource_types.select { |type| type.mods? }.map(&:to_s)
|
|
19
|
+
end
|
|
20
|
+
|
|
15
21
|
# Physical or digital forms of the object.
|
|
16
22
|
# @return [Array<String>]
|
|
17
23
|
# @example GIS dataset (nz187ct8959)
|
|
18
24
|
# record.forms #=> ["map", "optical disc", "electronic resource"]
|
|
19
25
|
def forms
|
|
20
|
-
|
|
26
|
+
form_forms.map(&:to_s).compact_blank.uniq
|
|
21
27
|
end
|
|
22
28
|
|
|
23
29
|
# Extent of the object, such as "1 audiotape" or "1 map".
|
|
@@ -25,7 +31,7 @@ module CocinaDisplay
|
|
|
25
31
|
# @example Oral history interview (sw705fr7011)
|
|
26
32
|
# record.extents #=> ["1 audiotape", "1 transcript"]
|
|
27
33
|
def extents
|
|
28
|
-
|
|
34
|
+
extent_forms.map(&:to_s).compact_blank.uniq
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
# Genres of the object, capitalized for display.
|
|
@@ -33,7 +39,7 @@ module CocinaDisplay
|
|
|
33
39
|
# @example GIS dataset (nz187ct8959)
|
|
34
40
|
# record.genres #=> ["Cartographic dataset", "Geospatial data", "Geographic information systems data"]
|
|
35
41
|
def genres
|
|
36
|
-
|
|
42
|
+
genre_forms.map(&:to_s).compact_blank.uniq
|
|
37
43
|
end
|
|
38
44
|
|
|
39
45
|
# Genres of the object, with additional values added for search/faceting.
|
|
@@ -47,6 +53,34 @@ module CocinaDisplay
|
|
|
47
53
|
end.uniq
|
|
48
54
|
end
|
|
49
55
|
|
|
56
|
+
# All form-related data to be rendered for display.
|
|
57
|
+
# Includes form, extent, resource type, etc. (but not self-deposit resource types).
|
|
58
|
+
# @return [Array<DisplayData>]
|
|
59
|
+
def form_display_data
|
|
60
|
+
CocinaDisplay::DisplayData.from_objects(all_forms - genre_forms - map_forms - media_forms - self_deposit_resource_types)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# All genre-related data to be rendered for display.
|
|
64
|
+
# Includes both form genres, subject genres, and self-deposit resource types.
|
|
65
|
+
# @return [Array<DisplayData>]
|
|
66
|
+
def genre_display_data
|
|
67
|
+
CocinaDisplay::DisplayData.from_objects(genre_forms + genre_subjects + self_deposit_resource_types)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# All map-related data to be rendered for display.
|
|
71
|
+
# Includes map scale, projection info, and geographic coordinate subjects.
|
|
72
|
+
# @return [Array<DisplayData>]
|
|
73
|
+
def map_display_data
|
|
74
|
+
CocinaDisplay::DisplayData.from_objects(map_forms + coordinate_subjects)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# All form notes to be rendered for display.
|
|
78
|
+
# @return [Array<DisplayData>]
|
|
79
|
+
def form_note_display_data
|
|
80
|
+
CocinaDisplay::DisplayData.from_cocina(path("$.description.form[*].note[*]"),
|
|
81
|
+
label: I18n.t("cocina_display.field_label.form.note"))
|
|
82
|
+
end
|
|
83
|
+
|
|
50
84
|
# Is the object a periodical or serial?
|
|
51
85
|
# @return [Boolean]
|
|
52
86
|
def periodical?
|
|
@@ -73,6 +107,46 @@ module CocinaDisplay
|
|
|
73
107
|
|
|
74
108
|
private
|
|
75
109
|
|
|
110
|
+
# Collapses all nested form values into an array of {Form} objects.
|
|
111
|
+
# Preserves resource type without flattening, since it can be structured.
|
|
112
|
+
# @return [Array<Form>]
|
|
113
|
+
def all_forms
|
|
114
|
+
@all_forms ||= path("$.description.form.*")
|
|
115
|
+
.flat_map { |form| Utils.flatten_nested_values(form, atomic_types: ["resource type"]) }
|
|
116
|
+
.map { |form| CocinaDisplay::Forms::Form.from_cocina(form) }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# {Form} objects with type "form".
|
|
120
|
+
# @return [Array<Form>]
|
|
121
|
+
def form_forms
|
|
122
|
+
all_forms.filter { |form| form.type == "form" }
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# {Form} objects with type "genre".
|
|
126
|
+
# @return [Array<Form>]
|
|
127
|
+
def genre_forms
|
|
128
|
+
all_forms.filter { |form| form.type == "genre" }
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# {Form} objects with type "extent".
|
|
132
|
+
# @return [Array<Form>]
|
|
133
|
+
def extent_forms
|
|
134
|
+
all_forms.filter { |form| form.type == "extent" }
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# {Form} objects with types related to map data.
|
|
138
|
+
# @return [Array<Form>]
|
|
139
|
+
def map_forms
|
|
140
|
+
all_forms.filter { |form| ["map scale", "map projection"].include?(form.type) }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# {Form} objects with types that are media-related.
|
|
144
|
+
# @note These are excluded from the general form display data.
|
|
145
|
+
# @return [Array<Form>]
|
|
146
|
+
def media_forms
|
|
147
|
+
all_forms.filter { |form| ["reformatting quality", "media type"].include?(form.type) }
|
|
148
|
+
end
|
|
149
|
+
|
|
76
150
|
# Map a resource type to SearchWorks format value(s).
|
|
77
151
|
# @param resource_type [String] The resource type to map.
|
|
78
152
|
# @return [Array<String>]
|
|
@@ -113,21 +187,34 @@ module CocinaDisplay
|
|
|
113
187
|
values.compact_blank
|
|
114
188
|
end
|
|
115
189
|
|
|
190
|
+
# All resource types forms, as {ResourceType}s.
|
|
191
|
+
# @return [Array<ResourceType>]
|
|
192
|
+
def all_resource_types
|
|
193
|
+
all_forms.filter { |form| form.is_a?(CocinaDisplay::Forms::ResourceType) }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# {ResourceType} objects that are Stanford self-deposit resource types.
|
|
197
|
+
# @return [Array<ResourceType>]
|
|
198
|
+
def self_deposit_resource_types
|
|
199
|
+
all_resource_types.filter { |resource_type| resource_type.stanford_self_deposit? }
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Display values of all resource types.
|
|
203
|
+
# @return [Array<String>]
|
|
204
|
+
def resource_type_values
|
|
205
|
+
all_resource_types.map(&:to_s).uniq
|
|
206
|
+
end
|
|
207
|
+
|
|
116
208
|
# Issuance terms for a work, drawn from the event notes.
|
|
117
209
|
# @return [Array<String>]
|
|
118
210
|
def issuance_terms
|
|
119
|
-
|
|
211
|
+
events.flat_map(&:notes).filter { |note| note.type == "issuance" }.map { |note| note.to_s.downcase }.uniq
|
|
120
212
|
end
|
|
121
213
|
|
|
122
214
|
# Frequency terms for a periodical, drawn from the event notes.
|
|
123
215
|
# @return [Array<String>]
|
|
124
216
|
def frequency
|
|
125
|
-
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Values of the resource type form field prior to mapping.
|
|
129
|
-
def resource_type_values
|
|
130
|
-
path("$.description.form..[?@.type == 'resource type'].value").uniq
|
|
217
|
+
events.flat_map(&:notes).filter { |note| note.type == "frequency" }.map { |note| note.to_s.downcase }.uniq
|
|
131
218
|
end
|
|
132
219
|
end
|
|
133
220
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../subjects/subject_value"
|
|
4
|
-
|
|
5
3
|
module CocinaDisplay
|
|
6
4
|
module Concerns
|
|
7
5
|
# Methods for extracting geospatial metadata, such as coordinates.
|
|
@@ -10,7 +8,7 @@ module CocinaDisplay
|
|
|
10
8
|
# @return [Array<String>]
|
|
11
9
|
# @example ["34°03′08″N 118°14′37″W"]
|
|
12
10
|
def coordinates
|
|
13
|
-
|
|
11
|
+
coordinate_subject_values.map(&:to_s).compact.uniq
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
# All valid coordinate data formatted for indexing into a Solr RPT field.
|
|
@@ -49,15 +47,21 @@ module CocinaDisplay
|
|
|
49
47
|
|
|
50
48
|
private
|
|
51
49
|
|
|
50
|
+
# {Subject} objects with types that could contain coordinate information.
|
|
51
|
+
# @return [Array<Subject>]
|
|
52
|
+
def coordinate_subjects
|
|
53
|
+
all_subjects.filter { |subject| subject.type&.include? "coordinates" }
|
|
54
|
+
end
|
|
55
|
+
|
|
52
56
|
# Parsed coordinate values from the coordinate subject values.
|
|
53
57
|
# @return [Array<Geospatial::Coordinates>]
|
|
54
58
|
def coordinate_objects
|
|
55
|
-
|
|
59
|
+
coordinate_subject_values.filter_map(&:coordinates)
|
|
56
60
|
end
|
|
57
61
|
|
|
58
62
|
# All subject values that could contain parsed coordinates.
|
|
59
63
|
# @return [Array<Subjects::CoordinatesSubjectValue>]
|
|
60
|
-
def
|
|
64
|
+
def coordinate_subject_values
|
|
61
65
|
subject_values.filter { |s| s.is_a? CocinaDisplay::Subjects::CoordinatesSubjectValue }
|
|
62
66
|
end
|
|
63
67
|
end
|
|
@@ -26,11 +26,7 @@ module CocinaDisplay
|
|
|
26
26
|
# @example
|
|
27
27
|
# record.doi #=> "10.25740/ppax-bf07"
|
|
28
28
|
def doi
|
|
29
|
-
|
|
30
|
-
path("$.description.identifier[?match(@.type, 'doi|DOI')].value").first ||
|
|
31
|
-
path("$.description.identifier[?search(@.uri, 'doi.org')].uri").first
|
|
32
|
-
|
|
33
|
-
URI(doi_id).path.delete_prefix("/") if doi_id.present?
|
|
29
|
+
identifiers.find(&:doi?)&.identifier
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
# The DOI as a URL, if there is one. Any valid DOI should resolve via doi.org.
|
|
@@ -66,6 +62,30 @@ module CocinaDisplay
|
|
|
66
62
|
def searchworks_id
|
|
67
63
|
folio_hrid || bare_druid
|
|
68
64
|
end
|
|
65
|
+
|
|
66
|
+
# Identifier objects extracted from the Cocina metadata.
|
|
67
|
+
# @return [Array<Identifier>]
|
|
68
|
+
def identifiers
|
|
69
|
+
@identifiers ||= path("$.description.identifier[*]").map { |id| Identifier.new(id) } + Array(doi_from_identification)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Labelled display data for identifiers.
|
|
73
|
+
# @return [Array<DisplayData>]
|
|
74
|
+
def identifier_display_data
|
|
75
|
+
CocinaDisplay::DisplayData.from_objects(identifiers)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# Synthetic Identifier object for a DOI in the identification block.
|
|
81
|
+
# @return [Array<Identifier>]
|
|
82
|
+
def doi_from_identification
|
|
83
|
+
id = path("$.identification.doi").first
|
|
84
|
+
return if id.blank?
|
|
85
|
+
|
|
86
|
+
value_key = id.start_with?("http") ? "uri" : "value"
|
|
87
|
+
Identifier.new({value_key => id, "type" => "doi"})
|
|
88
|
+
end
|
|
69
89
|
end
|
|
70
90
|
end
|
|
71
91
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require_relative "../language"
|
|
2
|
-
|
|
3
1
|
module CocinaDisplay
|
|
4
2
|
module Concerns
|
|
5
3
|
# Methods for extracting language information from a Cocina object.
|
|
@@ -15,6 +13,12 @@ module CocinaDisplay
|
|
|
15
13
|
def searchworks_language_names
|
|
16
14
|
languages.filter_map { |lang| lang.to_s if lang.searchworks_language? }.compact_blank.uniq
|
|
17
15
|
end
|
|
16
|
+
|
|
17
|
+
# Language information for display.
|
|
18
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
19
|
+
def language_display_data
|
|
20
|
+
CocinaDisplay::DisplayData.from_objects(languages)
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Concerns
|
|
3
|
+
# Methods for extracting note information from Cocina.
|
|
4
|
+
module Notes
|
|
5
|
+
# Note objects associated with the cocina record.
|
|
6
|
+
# @return [Array<CocinaDisplay::Note>]
|
|
7
|
+
def notes
|
|
8
|
+
@notes ||= path("$.description.note.*").map { |note| CocinaDisplay::Note.new(note) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Abstract metadata for display.
|
|
12
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
13
|
+
def abstract_display_data
|
|
14
|
+
CocinaDisplay::DisplayData.from_objects(notes.select(&:abstract?))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# General note metadata for display.
|
|
18
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
19
|
+
def general_note_display_data
|
|
20
|
+
CocinaDisplay::DisplayData.from_objects(notes.select(&:general_note?))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Preferred citation metadata for display.
|
|
24
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
25
|
+
def preferred_citation_display_data
|
|
26
|
+
CocinaDisplay::DisplayData.from_objects(notes.select(&:preferred_citation?))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Table of contents metadata for display.
|
|
30
|
+
# @return [Array<CocinaDisplay::DisplayData>]
|
|
31
|
+
def table_of_contents_display_data
|
|
32
|
+
CocinaDisplay::DisplayData.from_objects(notes.select(&:table_of_contents?))
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module CocinaDisplay
|
|
2
|
+
module Concerns
|
|
3
|
+
# Methods for extracting and formatting related resources from Cocina records.
|
|
4
|
+
module RelatedResources
|
|
5
|
+
# Resources related to the object.
|
|
6
|
+
# @return [Array<CocinaDisplay::RelatedResource>]
|
|
7
|
+
def related_resources
|
|
8
|
+
@related_resources ||= path("$.description.relatedResource[*]").map { |res| RelatedResource.new(res) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Display data for related resources.
|
|
12
|
+
# @note Related resources also have their own nested display data.
|
|
13
|
+
# @see CocinaDisplay::RelatedResource#display_data
|
|
14
|
+
# @return [Array<DisplayData>]
|
|
15
|
+
def related_resource_display_data
|
|
16
|
+
DisplayData.from_objects(related_resources)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
require_relative "../subjects/subject"
|
|
2
|
-
require_relative "../subjects/subject_value"
|
|
3
|
-
|
|
4
1
|
module CocinaDisplay
|
|
5
2
|
module Concerns
|
|
6
3
|
# Methods for extracting and formatting subject information.
|
|
@@ -87,25 +84,45 @@ module CocinaDisplay
|
|
|
87
84
|
# @see Subject#to_s
|
|
88
85
|
# @return [Array<String>]
|
|
89
86
|
def subject_all_display
|
|
90
|
-
|
|
87
|
+
all_subjects.map(&:to_s).uniq
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Subject data to be rendered for display.
|
|
91
|
+
# Uses the concatenated form for structured subject values.
|
|
92
|
+
# @see Subject#to_s
|
|
93
|
+
# @return [Array<DisplayData>]
|
|
94
|
+
def subject_display_data
|
|
95
|
+
CocinaDisplay::DisplayData.from_objects(all_subjects - classification_subjects - genre_subjects - coordinate_subjects)
|
|
91
96
|
end
|
|
92
97
|
|
|
93
98
|
private
|
|
94
99
|
|
|
95
|
-
# All subjects, accessible as Subject objects.
|
|
100
|
+
# All subjects, accessible as {Subject} objects.
|
|
96
101
|
# Checks both description.subject and description.geographic.subject.
|
|
97
102
|
# @return [Array<Subject>]
|
|
98
|
-
def
|
|
99
|
-
@
|
|
103
|
+
def all_subjects
|
|
104
|
+
@all_subjects ||= Enumerator::Chain.new(
|
|
100
105
|
path("$.description.subject[*]"),
|
|
101
106
|
path("$.description.geographic.*.subject[*]")
|
|
102
107
|
).map { |s| CocinaDisplay::Subjects::Subject.new(s) }
|
|
103
108
|
end
|
|
104
109
|
|
|
110
|
+
# {Subject} objects with type "genre".
|
|
111
|
+
# @return [Array<Subject>]
|
|
112
|
+
def genre_subjects
|
|
113
|
+
all_subjects.filter { |subject| subject.type == "genre" }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# {Subject} objects with type "classification".
|
|
117
|
+
# @return [Array<Subject>]
|
|
118
|
+
def classification_subjects
|
|
119
|
+
all_subjects.filter { |subject| subject.type == "classification" }
|
|
120
|
+
end
|
|
121
|
+
|
|
105
122
|
# All subject values, flattened from all subjects.
|
|
106
123
|
# @return [Array<SubjectValue>]
|
|
107
124
|
def subject_values
|
|
108
|
-
@subject_values ||=
|
|
125
|
+
@subject_values ||= all_subjects.flat_map(&:subject_values)
|
|
109
126
|
end
|
|
110
127
|
|
|
111
128
|
# All subject values that are named places.
|