adiwg-mdtranslator 2.19.0.pre.beta.19 → 2.20.0.pre.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +1 -1
- data/DCAT-US.md +67 -0
- data/Gemfile.lock +41 -31
- data/README.md +21 -0
- data/Rakefile +1 -0
- data/adiwg-mdtranslator.gemspec +2 -2
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_dataQuality.rb +3 -3
- data/lib/adiwg/mdtranslator/readers/mdJson/modules/module_conformanceResult.rb +0 -5
- data/lib/adiwg/mdtranslator/readers/mdJson/modules/module_coverageResult.rb +0 -4
- data/lib/adiwg/mdtranslator/readers/mdJson/modules/module_descriptiveResult.rb +0 -4
- data/lib/adiwg/mdtranslator/readers/mdJson/modules/module_quantitativeResult.rb +0 -4
- data/lib/adiwg/mdtranslator/version.rb +1 -1
- data/lib/adiwg/mdtranslator/writers/dcat_us/dcat_us_writer.rb +98 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/readme.md +10 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_access_level.rb +55 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_access_url.rb +17 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_accrualPeriodicity.rb +45 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_bureau_code.rb +33 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_contact_point.rb +29 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_dcat_us.rb +104 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_described_by.rb +29 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_described_by_type.rb +33 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_description.rb +19 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_distribution.rb +59 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_download_url.rb +17 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_identifier.rb +29 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_is_part_of.rb +27 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_issued.rb +19 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_keyword.rb +19 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_landing_page.rb +27 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_language.rb +23 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_license.rb +18 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_media_type.rb +17 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_modified.rb +29 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_primaryITInvestmentUII.rb +19 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_program_code.rb +33 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_publisher.rb +74 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_references.rb +50 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_rights.rb +32 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_spatial.rb +32 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_system_of_records.rb +28 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_temporal.rb +40 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/sections/dcat_us_theme.rb +28 -0
- data/lib/adiwg/mdtranslator/writers/dcat_us/version.rb +14 -0
- data/lib/adiwg/mdtranslator/writers/fgdc/classes/class_dataQuality.rb +3 -3
- data/lib/adiwg/mdtranslator/writers/html/sections/html_dataQuality.rb +1 -1
- data/lib/adiwg/mdtranslator/writers/html/sections/html_dataQualityReport.rb +0 -28
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_conformanceResult.rb +5 -6
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_coverageResult.rb +0 -1
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_descriptiveResult.rb +0 -1
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_onlineResource.rb +1 -1
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_quantitativeResult.rb +5 -6
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_resourceInfo.rb +1 -1
- data/lib/adiwg/mdtranslator/writers/simple_html/sections/html_dataQuality.rb +1 -1
- data/lib/adiwg/mdtranslator_cli.rb +1 -1
- metadata +39 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec23318ef18dc9729c5aaa6c608b55c856234d8e31a893b6c011f02494f75718
|
4
|
+
data.tar.gz: d28e618a12660f940c9fbc4d3ea380c1109cdc2c7756a32872c2f2e84b4e2c64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c81ced313a48931ef23b337d408f512932836b81368c535eb197dc0950795b8510deea40f5a130b4372b3110f1d9020fb943d7537de8e80184dc88b25fe8994
|
7
|
+
data.tar.gz: 0566ba79a6004232a532bd7eda527bb60a90191ea0a0ba47baf38764efa014341074a31418cdc798f82a2fe5a5860f13d9f8a3e9dce8d170389edea39392a47d
|
data/.github/workflows/test.yml
CHANGED
data/DCAT-US.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# DCAT-US - mdTranslator proposed mappings
|
2
|
+
## Quick references
|
3
|
+
- DCAT-US [element definitions](https://resources.data.gov/resources/dcat-us/)
|
4
|
+
- DCAT-US v1.1 [catalog.json schema](https://resources.data.gov/schemas/dcat-us/v1.1/schema/catalog.json)
|
5
|
+
- DCAT-US v1.1 [dataset.json schema](https://resources.data.gov/schemas/dcat-us/v1.1/schema/dataset.json)
|
6
|
+
- DCAT-US v1.1 [JSON-LD catalog.json schema](https://resources.data.gov/schemas/dcat-us/v1.1/schema/catalog.jsonld)
|
7
|
+
- [Element crosswalks](https://resources.data.gov/resources/podm-field-mapping/#field-mappings) to other standards
|
8
|
+
|
9
|
+
## DCAT-US - mdTranslator
|
10
|
+
|
11
|
+
### Always (always required)
|
12
|
+
|
13
|
+
| Field Name | DCAT Name | Condition | mdJson Source |
|
14
|
+
| --- | --- | --- | --- |
|
15
|
+
| Title | title | exists | citation.title |
|
16
|
+
| Description | description | exists | resourceInfo.abstract |
|
17
|
+
| Tags | keyword | exists | [resourceInfo.keyword.keyword[0, n] *flatten*] |
|
18
|
+
| Last Update | modified | if resourceInfo.citation.date[any].dateType = "lastUpdated" or "lastRevised" or "revision" | resourceInfo.citation.date[most recent] |
|
19
|
+
| Publisher | publisher{name} | if citation.responsibleParty.[any].role = "publisher" | contactId -> contact.name where isOrganization IS TRUE |
|
20
|
+
| | | if exists resourceDistribution.distributor.contact | [first contact] contactId -> contact.name where isOrganization IS TRUE |
|
21
|
+
| Publisher Parent Organization | publisher{subOrganizationOf} | if citation.responsibleParty[any].role = "publisher" and exists contactId -> memberOfOrganization[0] and isOrganization is true | contactId -> contact.name |
|
22
|
+
| | | if exists resourceDistribution.distributor.contact and exists contactId -> memberOfOrganization[0] and isOrganization IS TRUE | contactId -> contact.name |
|
23
|
+
| Contact Name | contactPoint{fn} | exists | resourceInfo.pointOfContact.parties[0].contactId -> contact.name |
|
24
|
+
| Contact Email | contactPoint{email} | exists | resourceInfo.pointOfContact.parties[0].contactId -> contact.eMailList[0] |
|
25
|
+
| Unique Identifier | identifier | if resourceInfo.citation.identifier.namespace = "DOI" | resourceInfo.citation.onlineResource.uri |
|
26
|
+
| | | if "DOI" within resourceInfo.citation.onlineResource.uri | resourceInfo.citation.onlineResource.uri |
|
27
|
+
| Public Access Level | accessLevel | [*extend codelist MD_RestrictionCode to include "public", "restricted public", "non-public"*] <br> if resourceInfo.constraints.legal[any] one of {"public", "restricted public", "non-public"} | resourceInfo.constraints.legal[first]. Also resourceInfo.constraint.security.classification [[MD_ClassificationCode](https://mdtools.adiwg.org/#codes-page?c=iso_classification)] |
|
28
|
+
| Bureau Code | bureauCode | | [*extend role codelist to include "bureau", extend namespace codelist to include "bureauCode"*] <br> for each resourceInfo.citation.responsibleParty[any] role = "bureau" <br>contactId -> contact.identifier [*identifier must conform to https://resources.data.gov/schemas/dcat-us/v1.1/omb_bureau_codes.csv*] |
|
29
|
+
| Program Code | programCode | | [*add new element of program resourceInfo.programCode, add new codelist of programCode*] <br> resourceInfo.program[0,n] |
|
30
|
+
|
31
|
+
### If-Applicable (required if it exists)
|
32
|
+
|
33
|
+
| Field Name | DCAT Name | Condition | mdJson Source |
|
34
|
+
| --- | --- | --- | --- |
|
35
|
+
| Distribution | distribution | if exists resourceDistribution[any] and if exists resourceDistribution.distributor[any].transferOption[any].onlineOption[any].uri <br> for each resourceDistribution[0, n] where exists resourceDistribution.distributor.transferOption.onlineOption.uri then <br> {description, accessURL, downloadURL, mediaType, title} |
|
36
|
+
| - Description | distribution.description | exists | resourceDistribution.description |
|
37
|
+
| - AccessURL | distribution.accessURL | if citation.onlineResources[first occurence].uri [path ends in ".html"] [*required if applicable*] | resourceDistribution.distributor.transferOption.onlineOption.uri |
|
38
|
+
| - DownloadURL | dcat.distribution.downloadURL | if citation.onlineResources[first occurence].uri [path does not end in ".html"] [*required if applicable*] |resourceDistribution.distributor.transferOption.onlineOption.uri |
|
39
|
+
| - MediaType | distribution.mediaType | [*add codelist of "dataFormat"*] <br> transferOption.distributionFormat.formatSpecification.title [dataFormat] [*dataFormat should conform to: https://www.iana.org/assignments/media-types/media-types.xhtml*] |
|
40
|
+
| - Title | distribution.title | exists | resourceDistribution.distributor.transferOption.onlineOption.name |
|
41
|
+
| License | license | [*add resourceInfo.constraint.reference to mdEditor*] <br> if exists resourceInfo.constraint.reference[0] | resourceInfo.constraint.reference[0] <br> |
|
42
|
+
| | | else | https://creativecommons.org/publicdomain/zero/1.0/ <br> [*allows author to identify a license to use, or default to CC0 if none provided, CC0 would cover international usage as opposed to publicdomain*] <br> [*others: http://www.usa.gov/publicdomain/label/1.0/, http://opendatacommons.org/licenses/pddl/1.0*] |
|
43
|
+
| Rights | rights | if constraint.accessLevel in {"restricted public", "non-public"} | resourceInfo.constraint.releasibility.statement + " " + each constraint.releasibility.dessiminationConstraint[0, n] |
|
44
|
+
| Endpoint | *removed* | *ignored* | *ignored* |
|
45
|
+
| Spatial | spatial | if exists resourceInfo.extents[0].geographicExtents[0].boundingBox | boundingBox.eastLongitude + "," + boundingBox.southLatitude + "," + boundingBox.westLongitude + "," + boundingBox.northLatitude [*decimal degrees*] |
|
46
|
+
| | | else | if exists resourceInfo.extents[0].geographicExtents[0].geographicElement[0].type = "point" then <br> geographicElement[0].coordinate[1] + "," + geographicElement[0].coordinate[0] [*lat, long decimal degrees*] |
|
47
|
+
| Temporal | temporal | if exists resourceInfo.extent[0].temporalExtent[0] then <br> if exists tempororalExtent[0].timePeriod.startDate and exists temporaralExtent[0].timePeriod.endDate | timePeriod[0].startDate + "/" + timePeriod.endDate |
|
48
|
+
| | | if exists tempororalExtent[0].timePeriod.startDate and not exists temporaralExtent[0].timePeriod.endDate | tempororalExtent[0].timePeriod.startDate |
|
49
|
+
| | | if not exists temporalExtent[0].timePeriod.startDate and exists temporaralExtent[0].timePeriod.endDate | tempororalExtent[0].timePeriod.endDate <br> [*may need revisiting relative to decision on date only formatting*] |
|
50
|
+
|
51
|
+
### No (not required)
|
52
|
+
|
53
|
+
| Field Name | DCAT Name | Condition | mdJson Source |
|
54
|
+
| --- | --- | --- | --- |
|
55
|
+
| Release Date | issued | if resourceInfo.citation.date[any].dateType = "publication" or "distributed" | resourceInfo.citation.date[earliest] |
|
56
|
+
| Frequency | accrualPeriodicity | | [*ISO codelist MD_maintenanceFrequency can be used and several codes intersect with accrualPeriod codelist they are partially corresponding. A column of ISO8601 code equivalents could be added to MD_maintenanceFrequency to provide the coding expected https://resources.data.gov/schemas/dcat-us/v1.1/iso8601_guidance/#accrualperiodicity, community valuation should be determined*] |
|
57
|
+
| Language | language | | [*language codelist could be used but needs to be bound with country corresponding to the RFC 5646 format https://datatracker.ietf.org/doc/html/rfc5646, such as "en-US", community valuation should be determined* |
|
58
|
+
| Data Quality | dataQuality | | [*this is a boolean to indicate whether data "conforms" to agency standards, value seems negligble*] |
|
59
|
+
| Category | theme | where resourceInfo.keyword[any].thesaurus.title = "ISO Topic Category" | [resourceInfo.keyword.keyword[0, n] *flatten*] |
|
60
|
+
| Related Documents | references | | associatedResource[all].resourceCitation.onlineResource[all].uri + additionalDocumentation[all].citation[all].onlineResource[all].uri [*comma separated*]|
|
61
|
+
| Homepage URL | landingPage | [*Add code "landingPage" to CI_OnlineFunctionCode*] <br> if resourceInfo.citation.onlineResource[any].function = "landingPage" | resourceInfo.citation.onlineResource.uri |
|
62
|
+
| Collection | isPartOf | for each associatedResource[0, n].initiativeType = "collection" and associatedResource.associationType = "collectiveTitle" | associatedResource.resourceCitation[0].uri |
|
63
|
+
| System of Records | systemOfRecords | [*Add code "sorn" to DS_InitiativeTypeCode*] <br> for each associatedResource[0, n].initiativeType = "sorn" | associatedResource.resourceCitation[0].uri |
|
64
|
+
| Primary IT Investment | primaryITInvestmentUII | | [*Links data to an IT investment identifier relative to Exhibit 53 docs, community valuation should be determined*] |
|
65
|
+
| Data Dictionary | describedBy | if dataDictionary.dictionaryIncludedWithResource IS NOT TRUE and citation.onlineResource[0].uri exists | dataDictionary.citation.onlineResource[0].uri |
|
66
|
+
| Data Dictionary Type | describedByType | | [*For simplicity, leave blank implying html page, community decision needed whether to support other format types using mime type and in the form of "application/pdf"*]|
|
67
|
+
| Data Standard | conformsTo | | [*Currently not able to identify the schema standard the data conforms to, though this has been proposed. Should this be built and there is community decision to support it, then it can be mapped*] |
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
adiwg-mdtranslator (2.
|
5
|
-
adiwg-mdcodes (= 2.9.4.pre.beta.
|
6
|
-
adiwg-mdjson_schemas (= 2.9.3.pre.beta.
|
4
|
+
adiwg-mdtranslator (2.20.0.pre.beta.3)
|
5
|
+
adiwg-mdcodes (= 2.9.4.pre.beta.0)
|
6
|
+
adiwg-mdjson_schemas (= 2.9.3.pre.beta.0)
|
7
7
|
builder (~> 3.2)
|
8
8
|
coderay (~> 1.1)
|
9
9
|
jbuilder (~> 2.5)
|
@@ -17,59 +17,69 @@ PATH
|
|
17
17
|
GEM
|
18
18
|
remote: https://rubygems.org/
|
19
19
|
specs:
|
20
|
-
actionview (
|
21
|
-
activesupport (=
|
20
|
+
actionview (7.1.3.2)
|
21
|
+
activesupport (= 7.1.3.2)
|
22
22
|
builder (~> 3.1)
|
23
|
-
erubi (~> 1.
|
24
|
-
rails-dom-testing (~> 2.
|
25
|
-
rails-html-sanitizer (~> 1.
|
26
|
-
activesupport (
|
23
|
+
erubi (~> 1.11)
|
24
|
+
rails-dom-testing (~> 2.2)
|
25
|
+
rails-html-sanitizer (~> 1.6)
|
26
|
+
activesupport (7.1.3.2)
|
27
|
+
base64
|
28
|
+
bigdecimal
|
27
29
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
connection_pool (>= 2.2.5)
|
31
|
+
drb
|
32
|
+
i18n (>= 1.6, < 2)
|
33
|
+
minitest (>= 5.1)
|
34
|
+
mutex_m
|
35
|
+
tzinfo (~> 2.0)
|
36
|
+
addressable (2.8.6)
|
32
37
|
public_suffix (>= 2.0.2, < 6.0)
|
33
|
-
adiwg-mdcodes (2.9.4.pre.beta.
|
38
|
+
adiwg-mdcodes (2.9.4.pre.beta.0)
|
34
39
|
json (~> 2.0)
|
35
|
-
adiwg-mdjson_schemas (2.9.3.pre.beta.
|
40
|
+
adiwg-mdjson_schemas (2.9.3.pre.beta.0)
|
41
|
+
base64 (0.2.0)
|
42
|
+
bigdecimal (3.1.8)
|
36
43
|
builder (3.2.4)
|
37
44
|
coderay (1.1.3)
|
38
|
-
concurrent-ruby (1.2.
|
45
|
+
concurrent-ruby (1.2.3)
|
46
|
+
connection_pool (2.4.1)
|
39
47
|
crass (1.0.6)
|
48
|
+
drb (2.2.1)
|
40
49
|
erubi (1.12.0)
|
41
|
-
i18n (1.14.
|
50
|
+
i18n (1.14.5)
|
42
51
|
concurrent-ruby (~> 1.0)
|
43
|
-
jbuilder (2.
|
52
|
+
jbuilder (2.12.0)
|
44
53
|
actionview (>= 5.0.0)
|
45
54
|
activesupport (>= 5.0.0)
|
46
|
-
json (2.
|
55
|
+
json (2.7.2)
|
47
56
|
json-schema (2.8.1)
|
48
57
|
addressable (>= 2.4)
|
49
58
|
kramdown (2.4.0)
|
50
59
|
rexml
|
51
|
-
loofah (2.
|
60
|
+
loofah (2.22.0)
|
52
61
|
crass (~> 1.0.2)
|
53
|
-
nokogiri (>= 1.
|
62
|
+
nokogiri (>= 1.12.0)
|
54
63
|
minitest (5.20.0)
|
55
|
-
|
64
|
+
mutex_m (0.2.0)
|
65
|
+
nokogiri (1.15.6-arm64-darwin)
|
56
66
|
racc (~> 1.4)
|
57
|
-
nokogiri (1.15.
|
67
|
+
nokogiri (1.15.6-x86_64-linux)
|
58
68
|
racc (~> 1.4)
|
59
|
-
public_suffix (
|
69
|
+
public_suffix (5.0.5)
|
60
70
|
racc (1.7.3)
|
61
|
-
rails-dom-testing (2.
|
71
|
+
rails-dom-testing (2.2.0)
|
62
72
|
activesupport (>= 5.0.0)
|
63
73
|
minitest
|
64
74
|
nokogiri (>= 1.6)
|
65
|
-
rails-html-sanitizer (1.
|
66
|
-
loofah (~> 2.
|
75
|
+
rails-html-sanitizer (1.6.0)
|
76
|
+
loofah (~> 2.21)
|
77
|
+
nokogiri (~> 1.14)
|
67
78
|
rake (13.1.0)
|
68
|
-
rexml (3.2.
|
79
|
+
rexml (3.2.6)
|
69
80
|
thor (0.20.3)
|
70
|
-
|
71
|
-
|
72
|
-
thread_safe (~> 0.1)
|
81
|
+
tzinfo (2.0.6)
|
82
|
+
concurrent-ruby (~> 1.0)
|
73
83
|
uuidtools (2.2.0)
|
74
84
|
|
75
85
|
PLATFORMS
|
data/README.md
CHANGED
@@ -23,6 +23,27 @@ Or install it yourself as:
|
|
23
23
|
|
24
24
|
$ mdtranslator help translate
|
25
25
|
|
26
|
+
## Development
|
27
|
+
|
28
|
+
### Requirements
|
29
|
+
|
30
|
+
Requires
|
31
|
+
- [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
|
32
|
+
- bundler (`gem install bundler`)
|
33
|
+
- rake (`gem install rake`)
|
34
|
+
|
35
|
+
### Tests
|
36
|
+
|
37
|
+
In order to run the tests, first install the dependencies
|
38
|
+
|
39
|
+
$ bundle install
|
40
|
+
|
41
|
+
Then, run the rake command
|
42
|
+
|
43
|
+
$ bundle exec rake
|
44
|
+
|
45
|
+
_TODO: There are currently 4 tests that are not passing, related to mdJSON readers and writers_
|
46
|
+
|
26
47
|
## Contributing
|
27
48
|
|
28
49
|
1. Fork it ( https://github.com/[my-github-username]/mdTranslator/fork )
|
data/Rakefile
CHANGED
data/adiwg-mdtranslator.gemspec
CHANGED
@@ -34,8 +34,8 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_runtime_dependency "thor", "~> 0.19"
|
35
35
|
spec.add_runtime_dependency "uuidtools", "~> 2.1"
|
36
36
|
spec.add_runtime_dependency "json-schema", "~> 2.7"
|
37
|
-
spec.add_runtime_dependency "adiwg-mdjson_schemas", "2.9.3.pre.beta.
|
38
|
-
spec.add_runtime_dependency "adiwg-mdcodes", "2.9.4.pre.beta.
|
37
|
+
spec.add_runtime_dependency "adiwg-mdjson_schemas", "2.9.3.pre.beta.0"
|
38
|
+
spec.add_runtime_dependency "adiwg-mdcodes", "2.9.4.pre.beta.0"
|
39
39
|
spec.add_runtime_dependency "jbuilder", "~> 2.5"
|
40
40
|
spec.add_runtime_dependency "kramdown", ">= 1.13", "< 3.0"
|
41
41
|
spec.add_runtime_dependency "coderay", "~> 1.1"
|
@@ -68,7 +68,7 @@ module ADIWG
|
|
68
68
|
else
|
69
69
|
complete = xComplete.text
|
70
70
|
report = intMetadataClass.newDataQualityReport
|
71
|
-
report[:type] = '
|
71
|
+
report[:type] = 'Omission'
|
72
72
|
descriptiveResult = intMetadataClass.newDescriptiveResult
|
73
73
|
descriptiveResult[:statement] = complete
|
74
74
|
report[:descriptiveResult] << descriptiveResult
|
@@ -82,7 +82,7 @@ module ADIWG
|
|
82
82
|
xHorizontal = xPositionalAccuracy.xpath('./horizpa')
|
83
83
|
unless xHorizontal.empty?
|
84
84
|
report = intMetadataClass.newDataQualityReport
|
85
|
-
report[:type] = '
|
85
|
+
report[:type] = 'AbsoluteExternalPositionalAccuracy'
|
86
86
|
unless xHorizontal.xpath('qhorizpa/horizpae').empty?
|
87
87
|
report[:qualityMeasure] = intMetadataClass.newQualityMeasure
|
88
88
|
report[:qualityMeasure][:description] = xHorizontal.xpath('qhorizpa/horizpae').text
|
@@ -105,7 +105,7 @@ module ADIWG
|
|
105
105
|
xVertical = xPositionalAccuracy.xpath('./vertacc')
|
106
106
|
unless xVertical.empty?
|
107
107
|
report = intMetadataClass.newDataQualityReport
|
108
|
-
report[:type] = '
|
108
|
+
report[:type] = 'AbsoluteExternalPositionalAccuracy'
|
109
109
|
unless xVertical.xpath('qvertpa/vertacce').empty?
|
110
110
|
report[:qualityMeasure] = intMetadataClass.newQualityMeasure
|
111
111
|
report[:qualityMeasure][:description] = xVertical.xpath('qvertpa/vertacce').text
|
@@ -23,11 +23,6 @@ module ADIWG
|
|
23
23
|
intConformanceResult[:scope] = Scope.unpack(hConformanceResult['scope'], responseObj)
|
24
24
|
end
|
25
25
|
|
26
|
-
# name
|
27
|
-
if hConformanceResult.has_key?('name')
|
28
|
-
intConformanceResult[:name] = hConformanceResult['name']
|
29
|
-
end
|
30
|
-
|
31
26
|
#specification
|
32
27
|
if hConformanceResult.has_key?('specification')
|
33
28
|
intConformanceResult[:specification] = Citation.unpack(hConformanceResult['specification'], responseObj)
|
@@ -26,10 +26,6 @@ module ADIWG
|
|
26
26
|
intResult[:scope] = Scope.unpack(hResult['scope'], responseObj)
|
27
27
|
end
|
28
28
|
|
29
|
-
# name
|
30
|
-
if hResult.has_key?('name')
|
31
|
-
intResult[:name] = hResult['name']
|
32
|
-
end
|
33
29
|
|
34
30
|
# spatialRepresentationType
|
35
31
|
if hResult.has_key?('spatialRepresentationType')
|
@@ -25,10 +25,6 @@ module ADIWG
|
|
25
25
|
intResult[:scope] = Scope.unpack(hResult['scope'], responseObj)
|
26
26
|
end
|
27
27
|
|
28
|
-
if hResult.has_key?('name')
|
29
|
-
intResult[:name] = hResult['name']
|
30
|
-
end
|
31
|
-
|
32
28
|
if hResult.has_key?('statement')
|
33
29
|
intResult[:statement] = hResult['statement']
|
34
30
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
require_relative 'version'
|
3
|
+
require_relative 'sections/dcat_us_dcat_us'
|
4
|
+
|
5
|
+
module ADIWG
|
6
|
+
module Mdtranslator
|
7
|
+
module Writers
|
8
|
+
module Dcat_us
|
9
|
+
|
10
|
+
def self.startWriter(intObj, responseObj)
|
11
|
+
# set the contact array for use by the writer
|
12
|
+
@contacts = intObj[:contacts]
|
13
|
+
|
14
|
+
# set output flag for null properties
|
15
|
+
Jbuilder.ignore_nil(!responseObj[:writerShowTags])
|
16
|
+
|
17
|
+
# set the format of the output file based on the writer specified
|
18
|
+
responseObj[:writerOutputFormat] = 'json'
|
19
|
+
responseObj[:writerVersion] = ADIWG::Mdtranslator::Writers::Dcat_us::VERSION
|
20
|
+
|
21
|
+
# write the dcat_us metadata record
|
22
|
+
metadata = Dcat_us.build(intObj, responseObj)
|
23
|
+
|
24
|
+
# set writer pass to true if no messages
|
25
|
+
# false or warning state will be set by writer code
|
26
|
+
responseObj[:writerPass] = true if responseObj[:writerMessages].empty?
|
27
|
+
|
28
|
+
# encode the metadata target as JSON
|
29
|
+
metadata.target!
|
30
|
+
end
|
31
|
+
|
32
|
+
# find contact in contact array and return the contact hash
|
33
|
+
def self.get_contact_by_index(contactIndex)
|
34
|
+
if @contacts[contactIndex]
|
35
|
+
return @contacts[contactIndex]
|
36
|
+
end
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
|
40
|
+
# find contact in contact array and return the contact hash
|
41
|
+
def self.get_contact_by_id(contactId)
|
42
|
+
@contacts.each do |hContact|
|
43
|
+
if hContact[:contactId] == contactId
|
44
|
+
return hContact
|
45
|
+
end
|
46
|
+
end
|
47
|
+
{}
|
48
|
+
end
|
49
|
+
|
50
|
+
# find contact in contact array and return the contact index
|
51
|
+
def self.get_contact_index_by_id(contactId)
|
52
|
+
@contacts.each_with_index do |hContact, index|
|
53
|
+
if hContact[:contactId] == contactId
|
54
|
+
return index
|
55
|
+
end
|
56
|
+
end
|
57
|
+
{}
|
58
|
+
end
|
59
|
+
|
60
|
+
# ignore jBuilder object mapping when array is empty
|
61
|
+
def self.json_map(collection = [], _class)
|
62
|
+
if collection.nil? || collection.empty?
|
63
|
+
return nil
|
64
|
+
else
|
65
|
+
collection.map { |item| _class.build(item).attributes! }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# find all nested objects in 'obj' that contain the element 'ele'
|
70
|
+
def self.nested_objs_by_element(obj, ele, excludeList = [])
|
71
|
+
aCollected = []
|
72
|
+
obj.each do |key, value|
|
73
|
+
skipThisOne = false
|
74
|
+
excludeList.each do |exclude|
|
75
|
+
if key == exclude.to_sym
|
76
|
+
skipThisOne = true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
next if skipThisOne
|
80
|
+
if key == ele.to_sym
|
81
|
+
aCollected << obj
|
82
|
+
elsif obj.is_a?(Array)
|
83
|
+
if key.respond_to?(:each)
|
84
|
+
aReturn = nested_objs_by_element(key, ele, excludeList)
|
85
|
+
aCollected = aCollected.concat(aReturn) unless aReturn.empty?
|
86
|
+
end
|
87
|
+
elsif obj[key].respond_to?(:each)
|
88
|
+
aReturn = nested_objs_by_element(value, ele, excludeList)
|
89
|
+
aCollected = aCollected.concat(aReturn) unless aReturn.empty?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
aCollected
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
|
3
|
+
module ADIWG
|
4
|
+
module Mdtranslator
|
5
|
+
module Writers
|
6
|
+
module Dcat_us
|
7
|
+
module AccessLevel
|
8
|
+
|
9
|
+
def self.build(intObj)
|
10
|
+
|
11
|
+
publicArray = ['unclassified', 'unrestricted', 'licenseUnrestricted', 'licenseEndUser']
|
12
|
+
nonPublicArray = ['restricted','confidential','secret','topSecret','forOfficialUseOnly','protected','intellectualPropertyRights','restricted','otherRestrictions','private','statutory','confidential','traditionalKnowledge','personallyIdentifiableInformation']
|
13
|
+
restrictedPublicArray = ['sensitiveButUnclassified','limitedDistribution','copyright','patent','patentPending','trademark','license','licenseDistributor','in-confidence','threatenedOrEndangered']
|
14
|
+
|
15
|
+
resourceInfo = intObj[:metadata][:resourceInfo]
|
16
|
+
legalConstraints = resourceInfo[:constraints]&.select { |constraint| constraint[:type] == 'legal' }
|
17
|
+
securityConstraints = resourceInfo[:constraints]&.select { |constraint| constraint[:type] == 'security' }
|
18
|
+
|
19
|
+
accessLevelCodes = []
|
20
|
+
|
21
|
+
# Gather codes from security constraints and legal constraints
|
22
|
+
unless securityConstraints.empty?
|
23
|
+
securityConstraints.each do |securityConstraint|
|
24
|
+
code = securityConstraint[:securityConstraint][:classCode]
|
25
|
+
accessLevelCodes << code
|
26
|
+
end
|
27
|
+
end
|
28
|
+
unless legalConstraints.empty?
|
29
|
+
legalConstraints.each do |legalConstraint|
|
30
|
+
codes = legalConstraint.dig(:legalConstraint, :accessCodes)
|
31
|
+
accessLevelCodes.push(*codes)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# return access level that is most restrictive
|
36
|
+
accessLevelCodes.uniq.each do |code|
|
37
|
+
if nonPublicArray.include? code
|
38
|
+
return 'non-public'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
accessLevelCodes.uniq.each do |code|
|
42
|
+
if restrictedPublicArray.include? code
|
43
|
+
return 'restricted public'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
return 'public'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
|
3
|
+
module ADIWG
|
4
|
+
module Mdtranslator
|
5
|
+
module Writers
|
6
|
+
module Dcat_us
|
7
|
+
module AccrualPeriodicity
|
8
|
+
|
9
|
+
def self.build(intObj)
|
10
|
+
|
11
|
+
frequency_mapping = {
|
12
|
+
'decennial' => 'R/P10Y',
|
13
|
+
'quadrennial' => 'R/P4Y',
|
14
|
+
'annual' => 'R/P1Y',
|
15
|
+
'bimonthly' => 'R/P2M or R/P0.5M',
|
16
|
+
'semiweekly' => 'R/P3.5D',
|
17
|
+
'daily' => 'R/P1D',
|
18
|
+
'biweekly' => 'R/P2W or R/P0.5W',
|
19
|
+
'semiannual' => 'R/P6M',
|
20
|
+
'biennial' => 'R/P2Y',
|
21
|
+
'triennial' => 'R/P3Y',
|
22
|
+
'three times a week' => 'R/P0.33W',
|
23
|
+
'three times a month' => 'R/P0.33M',
|
24
|
+
'continuously updated' => 'R/PT1S',
|
25
|
+
'monthly' => 'R/P1M',
|
26
|
+
'quarterly' => 'R/P3M',
|
27
|
+
'semimonthly' => 'R/P0.5M',
|
28
|
+
'three times a year' => 'R/P4M',
|
29
|
+
'weekly' => 'R/P1W',
|
30
|
+
'hourly' => 'R/PT1H'
|
31
|
+
}
|
32
|
+
|
33
|
+
frequency = intObj[:metadata][:metadataInfo][:metadataMaintenance][:frequency]
|
34
|
+
|
35
|
+
unless frequency.nil?
|
36
|
+
frequency_code = frequency_mapping[frequency.downcase]
|
37
|
+
end
|
38
|
+
return frequency_code
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
|
3
|
+
module ADIWG
|
4
|
+
module Mdtranslator
|
5
|
+
module Writers
|
6
|
+
module Dcat_us
|
7
|
+
module BureauCode
|
8
|
+
|
9
|
+
def self.build(intObj)
|
10
|
+
|
11
|
+
responsibleParties = intObj[:metadata][:resourceInfo][:citation][:responsibleParties]
|
12
|
+
contacts = []
|
13
|
+
responsibleParties.each do |party|
|
14
|
+
contactId = party[:parties][0][:contactId]
|
15
|
+
contacts << Dcat_us.get_contact_by_id(contactId)
|
16
|
+
end
|
17
|
+
|
18
|
+
bureauContacts = contacts&.select { |contact| contact[:externalIdentifier].any? { |id| id[:namespace] == 'bureauCode'} }
|
19
|
+
|
20
|
+
bureauCodes = []
|
21
|
+
bureauContacts.each do |contact|
|
22
|
+
bureauCode = contact[:externalIdentifier].find { |id| id[:namespace] == 'bureauCode' }
|
23
|
+
bureauCodes << bureauCode[:identifier]
|
24
|
+
end
|
25
|
+
|
26
|
+
return bureauCodes
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
|
3
|
+
module ADIWG
|
4
|
+
module Mdtranslator
|
5
|
+
module Writers
|
6
|
+
module Dcat_us
|
7
|
+
module ContactPoint
|
8
|
+
|
9
|
+
def self.build(intObj)
|
10
|
+
resourceInfo = intObj[:metadata][:resourceInfo]
|
11
|
+
pointOfContact = resourceInfo[:pointOfContacts][0]
|
12
|
+
contactId = pointOfContact[:parties][0][:contactId]
|
13
|
+
|
14
|
+
contact = Dcat_us.get_contact_by_id(contactId)
|
15
|
+
fn = contact[:name]
|
16
|
+
hasEmail = contact[:eMailList][0]
|
17
|
+
|
18
|
+
Jbuilder.new do |json|
|
19
|
+
json.set!('@type', 'vcard:Contact')
|
20
|
+
json.set!('fn', fn)
|
21
|
+
json.set!('hasEmail', hasEmail)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|