cocina_display 1.1.3 → 1.2.0
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/lib/cocina_display/cocina_record.rb +27 -63
- 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 +15 -4
- 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 +20 -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 +0 -2
- 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 +9 -11
- 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 +194 -0
- data/lib/cocina_display/utils.rb +4 -4
- data/lib/cocina_display/version.rb +1 -1
- data/lib/cocina_display.rb +30 -2
- metadata +45 -11
- data/lib/cocina_display/title_builder.rb +0 -397
- /data/lib/cocina_display/vocabularies/{marc_country_codes.rb → marc_country.rb} +0 -0
- /data/lib/cocina_display/vocabularies/{marc_relator_codes.rb → marc_relator.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0196b844ff2e2914b0216d0881f72d099772c73574cacbb2c2b8427d37910db
|
4
|
+
data.tar.gz: e1d9657e7868bcef2e20468998d118954d7ce3deefb9049a79b32f5cae54d3d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5963e10cfa7d99df707b3c088d0142170fd3a7b45d16a19ea98b5bec7872e24e6299ee18477107e43fbaa92f3eaf7620b25479b04b4cf26e7288c7ded0cf14be
|
7
|
+
data.tar.gz: 0a0cc895e8c1bd18aff64fa437945d9d9ae172be32730f7cbbb863f244ea17e4ce70087ac5cfab5e090f2e138849d3d74cdb1c5e3ce262fc1c85d9dcb920e018
|
data/.rspec
CHANGED
data/.standard.yml
CHANGED
data/README.md
CHANGED
@@ -44,10 +44,10 @@ The `CocinaRecord` class provides some methods to access common fields, as well
|
|
44
44
|
=> "Bugatti Type 51A. Road & Track Salon January 1957"
|
45
45
|
> record.content_type
|
46
46
|
=> "image"
|
47
|
-
> record.iiif_manifest_url
|
47
|
+
> record.iiif_manifest_url
|
48
48
|
=> "https://purl.stanford.edu/bb112zx3193/iiif3/manifest"
|
49
49
|
# access the hash representation
|
50
|
-
> record.cocina_doc.dig("description", "contributor", 0, "name", 0, "value")
|
50
|
+
> record.cocina_doc.dig("description", "contributor", 0, "name", 0, "value")
|
51
51
|
=> "Hearst Magazines, Inc."
|
52
52
|
```
|
53
53
|
|
@@ -92,6 +92,25 @@ cat spec/fixtures/bb112zx3193.json | janeway "$.description.contributor[?@.role[
|
|
92
92
|
|
93
93
|
Sometimes you need to determine if records exist "in the wild" that exhibit particular characteristics in the Cocina metadata, like the presence or absence of a field, or a specific value in a field. There is a template script in the `scripts/` directory that can be used to crawl all DRUIDs released to a particular target, like Searchworks, and examine each record.
|
94
94
|
|
95
|
+
Another approach is to examine the records in the `/stacks` share using jq. For example:
|
96
|
+
|
97
|
+
```shell
|
98
|
+
find /stacks -name cocina.json | head -10000 |
|
99
|
+
xargs jq '.description.subject[] | select(.source.uri=="http://id.loc.gov/authorities/subjects/") | select(.value != null) | select(.value | contains("--")) | .value'
|
100
|
+
```
|
101
|
+
|
102
|
+
### Logging of errors
|
103
|
+
|
104
|
+
You may create a custom error handler by implementing the `Honeybadger` interface (or just using Honeybadger) and assigning it to the `CocinaRecord.notifier`.
|
105
|
+
|
106
|
+
For example:
|
107
|
+
```ruby
|
108
|
+
Rails.application.config.to_prepare do
|
109
|
+
CocinaDisplay.notifier = Honeybadger
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
|
95
114
|
## Development
|
96
115
|
|
97
116
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. This is a useful place to try out JSONPath expressions with `CocinaRecord#path`.
|
File without changes
|
data/config/licenses.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
https://www.apache.org/licenses/LICENSE-2.0:
|
2
|
+
description: "This work is licensed under an Apache License 2.0."
|
3
|
+
https://opensource.org/licenses/BSD-2-Clause:
|
4
|
+
description: 'This work is licensed under a BSD 2-Clause "Simplified" License.'
|
5
|
+
https://opensource.org/licenses/BSD-3-Clause:
|
6
|
+
description: 'This work is licensed under a BSD 3-Clause "New" or "Revised" License.'
|
7
|
+
https://creativecommons.org/licenses/by/3.0/legalcode:
|
8
|
+
description: "This work is licensed under a Creative Commons Attribution 3.0 Unported license (CC BY)."
|
9
|
+
https://creativecommons.org/licenses/by/4.0/legalcode:
|
10
|
+
description: "This work is licensed under a Creative Commons Attribution 4.0 International license (CC BY)."
|
11
|
+
https://creativecommons.org/licenses/by-nc/3.0/legalcode:
|
12
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial 3.0 Unported license (CC BY-NC)."
|
13
|
+
https://creativecommons.org/licenses/by-nc/4.0/legalcode:
|
14
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial 4.0 International license (CC BY-NC)."
|
15
|
+
https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode:
|
16
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported license (CC BY-NC-ND)."
|
17
|
+
https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode:
|
18
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial No Derivatives 4.0 International license (CC BY-NC-ND)."
|
19
|
+
https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode:
|
20
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial Share Alike 3.0 Unported license (CC BY-NC-SA)."
|
21
|
+
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode:
|
22
|
+
description: "This work is licensed under a Creative Commons Attribution Non Commercial Share Alike 4.0 International license (CC BY-NC-SA)."
|
23
|
+
https://creativecommons.org/licenses/by-nd/4.0/legalcode:
|
24
|
+
description: "This work is licensed under a Creative Commons Attribution No Derivatives 4.0 International license (CC BY-ND)."
|
25
|
+
https://creativecommons.org/licenses/by-sa/3.0/legalcode:
|
26
|
+
description: "This work is licensed under a Creative Commons Attribution Share Alike 3.0 Unported license (CC BY-SA)."
|
27
|
+
https://creativecommons.org/licenses/by-sa/4.0/legalcode:
|
28
|
+
description: "This work is licensed under a Creative Commons Attribution Share Alike 4.0 International license (CC BY-SA)."
|
29
|
+
https://creativecommons.org/licenses/by-nd/3.0/legalcode:
|
30
|
+
description: "This work is licensed under a Creative Commons Attribution No Derivatives 3.0 Unported license (CC BY-ND)."
|
31
|
+
https://creativecommons.org/publicdomain/zero/1.0/legalcode:
|
32
|
+
description: "This work is licensed under a Creative Commons Zero v1.0 Universal license (CC0)."
|
33
|
+
https://opensource.org/licenses/cddl1:
|
34
|
+
description: "This work is licensed under a Common Development and Distribution License 1.0."
|
35
|
+
https://www.eclipse.org/legal/epl-2.0:
|
36
|
+
description: "This work is licensed under an Eclipse Public License 2.0."
|
37
|
+
https://www.gnu.org/licenses/agpl.txt:
|
38
|
+
description: "This work is licensed under a GNU Affero General Public License v3.0 only."
|
39
|
+
https://www.gnu.org/licenses/gpl-3.0-standalone.html:
|
40
|
+
description: "This work is licensed under a GNU General Public License v3.0 only."
|
41
|
+
https://www.gnu.org/licenses/lgpl-3.0-standalone.html:
|
42
|
+
description: "This work is licensed under a GNU Lesser General Public License v3.0 only."
|
43
|
+
https://www.isc.org/downloads/software-support-policy/isc-license/:
|
44
|
+
description: "This work is licensed under an ISC License."
|
45
|
+
https://opensource.org/licenses/MIT:
|
46
|
+
description: "This work is licensed under an MIT License."
|
47
|
+
https://www.mozilla.org/MPL/2.0/:
|
48
|
+
description: "This work is licensed under a Mozilla Public License 2.0."
|
49
|
+
https://opendatacommons.org/licenses/by/1-0/:
|
50
|
+
description: "This work is licensed under an Open Data Commons Attribution License v1.0."
|
51
|
+
http://opendatacommons.org/licenses/odbl/1.0/:
|
52
|
+
# This is a non-canonical url found in some existing data. It redirects to # https://opendatacommons.org/licenses/odbl/1-0/
|
53
|
+
description: "This work is licensed under an Open Data Commons Open Database License v1.0."
|
54
|
+
https://opendatacommons.org/licenses/odbl/1-0/:
|
55
|
+
description: "This work is licensed under an Open Data Commons Open Database License v1.0."
|
56
|
+
https://opendatacommons.org/licenses/pddl/1-0/:
|
57
|
+
description: "This work is licensed under an Open Data Commons Public Domain Dedication & License 1.0."
|
58
|
+
https://creativecommons.org/publicdomain/mark/1.0/:
|
59
|
+
description: "This work has been identified as being free of known restrictions under copyright law, including all related and neighboring rights (Public Domain Mark 1.0)."
|
@@ -0,0 +1,109 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
cocina_display:
|
4
|
+
field_label:
|
5
|
+
access:
|
6
|
+
access: Location
|
7
|
+
email: Contact information
|
8
|
+
repository: Repository
|
9
|
+
url: Location
|
10
|
+
copyright: Copyright
|
11
|
+
event:
|
12
|
+
date:
|
13
|
+
default: "%{type} date"
|
14
|
+
untyped: Date
|
15
|
+
note:
|
16
|
+
default: Imprint note
|
17
|
+
edition: Edition
|
18
|
+
issuance: Issuance
|
19
|
+
form:
|
20
|
+
digital_origin: Digital origin
|
21
|
+
extent: Extent
|
22
|
+
form: Form
|
23
|
+
genre: Genre
|
24
|
+
map_projection: Map data
|
25
|
+
map_scale: Map data
|
26
|
+
note: Note
|
27
|
+
resource_type: Resource Type
|
28
|
+
identifier:
|
29
|
+
doi: DOI
|
30
|
+
handle: Handle
|
31
|
+
identifier: Identifier
|
32
|
+
isbn: ISBN
|
33
|
+
ismn: ISMN
|
34
|
+
isrc: ISRC
|
35
|
+
issn: ISSN
|
36
|
+
issn_l: ISSN
|
37
|
+
issue_number: Issue number
|
38
|
+
language: Language
|
39
|
+
lccn: LCCN
|
40
|
+
matrix_number: Matrix number
|
41
|
+
music_plate: Music plate
|
42
|
+
music_publisher: Music publisher
|
43
|
+
oclc: OCLC
|
44
|
+
orcid: ORCID
|
45
|
+
sici: SICI
|
46
|
+
stock_number: Stock number
|
47
|
+
upc: UPC
|
48
|
+
videorecording_identifier: Videorecording identifier
|
49
|
+
language: Language
|
50
|
+
license: License
|
51
|
+
note:
|
52
|
+
abstract: Abstract
|
53
|
+
bibliography: Bibliography
|
54
|
+
biographical_historical: Biographical/Historical
|
55
|
+
citation_reference: Citation/Reference
|
56
|
+
creation_production_credits: Creation/Production credits
|
57
|
+
date_sequential_designation: Date/Sequential designation
|
58
|
+
note: Note
|
59
|
+
preferred_citation: Preferred citation
|
60
|
+
publications: Publications
|
61
|
+
references: References
|
62
|
+
scope_and_content: Scope and content
|
63
|
+
statement_of_responsibility: Statement of responsibility
|
64
|
+
summary: Summary
|
65
|
+
table_of_contents: Table of contents
|
66
|
+
purl: Location
|
67
|
+
subject:
|
68
|
+
bounding_box_coordinates: Map data
|
69
|
+
coverage: Map data
|
70
|
+
genre: Genre
|
71
|
+
map_coordinates: Map data
|
72
|
+
point_coordinates: Map data
|
73
|
+
subject: Subject
|
74
|
+
topic: Subject
|
75
|
+
use_and_reproduction: Use and reproduction statement
|
76
|
+
related_resource:
|
77
|
+
described_by: Described by
|
78
|
+
describes: Describes
|
79
|
+
derived_from: Derived from
|
80
|
+
has_original_version: Has original version
|
81
|
+
has_other_format: Has other format
|
82
|
+
has_part: Contains
|
83
|
+
has_version: Has version
|
84
|
+
identical_to: Identical to
|
85
|
+
in_series: In series
|
86
|
+
other_relation_type: Related to
|
87
|
+
part_of: Part of
|
88
|
+
preceded_by: Preceded by
|
89
|
+
referenced_by: Referenced by
|
90
|
+
references: References
|
91
|
+
related_to: Related item
|
92
|
+
reviewed_by: Reviewed by
|
93
|
+
source_of: Source of
|
94
|
+
succeeded_by: Succeeded by
|
95
|
+
supplemented_by: Supplemented by
|
96
|
+
supplement_to: Supplement to
|
97
|
+
version_of_record: Version of record
|
98
|
+
title:
|
99
|
+
title: Title
|
100
|
+
abbreviated: Abbreviated title
|
101
|
+
alternative: Alternative title
|
102
|
+
parallel: Parallel title
|
103
|
+
supplied: Supplied title
|
104
|
+
translated: Translated title
|
105
|
+
transliterated: Transliterated title
|
106
|
+
uniform: Uniform title
|
107
|
+
contributor:
|
108
|
+
role:
|
109
|
+
default: Associated with
|
@@ -1,37 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "janeway"
|
4
|
-
require "json"
|
5
|
-
require "net/http"
|
6
|
-
require "active_support"
|
7
|
-
require "active_support/core_ext/object/blank"
|
8
|
-
require "active_support/core_ext/hash/conversions"
|
9
|
-
|
10
|
-
require_relative "concerns/events"
|
11
|
-
require_relative "concerns/contributors"
|
12
|
-
require_relative "concerns/identifiers"
|
13
|
-
require_relative "concerns/titles"
|
14
|
-
require_relative "concerns/access"
|
15
|
-
require_relative "concerns/subjects"
|
16
|
-
require_relative "concerns/forms"
|
17
|
-
require_relative "concerns/languages"
|
18
|
-
require_relative "concerns/geospatial"
|
19
|
-
require_relative "concerns/structural"
|
20
|
-
require_relative "utils"
|
21
|
-
|
22
3
|
module CocinaDisplay
|
23
4
|
# Public Cocina metadata for an SDR object, as fetched from PURL.
|
24
|
-
class CocinaRecord
|
5
|
+
class CocinaRecord < JsonBackedRecord
|
6
|
+
include CocinaDisplay::Concerns::Accesses
|
25
7
|
include CocinaDisplay::Concerns::Events
|
26
8
|
include CocinaDisplay::Concerns::Contributors
|
27
9
|
include CocinaDisplay::Concerns::Identifiers
|
10
|
+
include CocinaDisplay::Concerns::Notes
|
28
11
|
include CocinaDisplay::Concerns::Titles
|
29
|
-
include CocinaDisplay::Concerns::
|
12
|
+
include CocinaDisplay::Concerns::UrlHelpers
|
30
13
|
include CocinaDisplay::Concerns::Subjects
|
31
14
|
include CocinaDisplay::Concerns::Forms
|
32
15
|
include CocinaDisplay::Concerns::Languages
|
33
16
|
include CocinaDisplay::Concerns::Geospatial
|
34
17
|
include CocinaDisplay::Concerns::Structural
|
18
|
+
include CocinaDisplay::Concerns::RelatedResources
|
35
19
|
|
36
20
|
# Fetch a public Cocina document from PURL and create a CocinaRecord.
|
37
21
|
# @note This is intended to be used in development or testing only.
|
@@ -39,7 +23,7 @@ module CocinaDisplay
|
|
39
23
|
# @param deep_compact [Boolean] If true, compact the JSON to remove blank values.
|
40
24
|
# @return [CocinaDisplay::CocinaRecord]
|
41
25
|
# :nocov:
|
42
|
-
def self.fetch(druid, deep_compact:
|
26
|
+
def self.fetch(druid, deep_compact: true)
|
43
27
|
from_json(Net::HTTP.get(URI("https://purl.stanford.edu/#{druid}.json")), deep_compact: deep_compact)
|
44
28
|
end
|
45
29
|
# :nocov:
|
@@ -53,28 +37,6 @@ module CocinaDisplay
|
|
53
37
|
deep_compact ? new(Utils.deep_compact_blank(cocina_doc)) : new(cocina_doc)
|
54
38
|
end
|
55
39
|
|
56
|
-
# The parsed Cocina document.
|
57
|
-
# @return [Hash]
|
58
|
-
attr_reader :cocina_doc
|
59
|
-
|
60
|
-
# Initialize a CocinaRecord with a Cocina document hash.
|
61
|
-
# @param cocina_doc [Hash]
|
62
|
-
def initialize(cocina_doc)
|
63
|
-
@cocina_doc = cocina_doc
|
64
|
-
end
|
65
|
-
|
66
|
-
# Evaluate a JSONPath expression against the Cocina document.
|
67
|
-
# @return [Enumerator] An enumerator that yields results matching the expression.
|
68
|
-
# @param path_expression [String] The JSONPath expression to evaluate.
|
69
|
-
# @see https://www.rubydoc.info/gems/janeway-jsonpath/0.6.0/file/README.md
|
70
|
-
# @example Name values for contributors
|
71
|
-
# record.path("$.description.contributor.*.name.*.value").search #=> ["Smith, John", "ACME Corp."]
|
72
|
-
# @example Filtering nodes using a condition
|
73
|
-
# record.path("$.description.contributor[?(@.type == 'person')].name.*.value").search #=> ["Smith, John"]
|
74
|
-
def path(path_expression)
|
75
|
-
Janeway.enum_for(path_expression, cocina_doc)
|
76
|
-
end
|
77
|
-
|
78
40
|
# Timestamp when the Cocina was created.
|
79
41
|
# @note This is for the metadata itself, not the object.
|
80
42
|
# @return [Time]
|
@@ -96,7 +58,7 @@ module CocinaDisplay
|
|
96
58
|
# @example
|
97
59
|
# record.content_type #=> "image"
|
98
60
|
def content_type
|
99
|
-
cocina_doc["type"]
|
61
|
+
cocina_doc["type"].delete_prefix("https://cocina.sul.stanford.edu/models/")
|
100
62
|
end
|
101
63
|
|
102
64
|
# Primary processing label for the object.
|
@@ -112,27 +74,29 @@ module CocinaDisplay
|
|
112
74
|
content_type == "collection"
|
113
75
|
end
|
114
76
|
|
115
|
-
#
|
116
|
-
# @return [
|
117
|
-
def
|
118
|
-
|
77
|
+
# Copyright statement from Cocina access metadata.
|
78
|
+
# @return [String, nil]
|
79
|
+
def copyright
|
80
|
+
cocina_doc.dig("access", "copyright")
|
119
81
|
end
|
120
|
-
end
|
121
82
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
# @example "is part of"
|
128
|
-
# @see https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md#relatedresource-types
|
129
|
-
attr_reader :type
|
83
|
+
# Use and reproduction statement from Cocina access metadata.
|
84
|
+
# @return [String, nil]
|
85
|
+
def use_and_reproduction
|
86
|
+
cocina_doc.dig("access", "useAndReproductionStatement")
|
87
|
+
end
|
130
88
|
|
131
|
-
#
|
132
|
-
#
|
133
|
-
def
|
134
|
-
@
|
135
|
-
|
89
|
+
# Description of the license
|
90
|
+
# @return [String, nil]
|
91
|
+
def license_description
|
92
|
+
@license_description ||=
|
93
|
+
license ? License.new(url: license).description : nil
|
94
|
+
end
|
95
|
+
|
96
|
+
# License URI
|
97
|
+
# @return [String, nil]
|
98
|
+
def license
|
99
|
+
cocina_doc.dig("access", "license")
|
136
100
|
end
|
137
101
|
end
|
138
102
|
end
|
@@ -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_string(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_string(copyright,
|
33
|
+
label: I18n.t("cocina_display.field_label.copyright"))
|
34
|
+
end
|
35
|
+
|
36
|
+
def license_display_data
|
37
|
+
CocinaDisplay::DisplayData.from_string(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_string(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.
|