glossarist 2.8.2 → 2.8.5
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/.rubocop_todo.yml +78 -64
- data/glossarist.gemspec +1 -1
- data/lib/glossarist/bibliography_data.rb +41 -0
- data/lib/glossarist/bibliography_entry.rb +13 -0
- data/lib/glossarist/citation.rb +8 -2
- data/lib/glossarist/cli/export_command.rb +10 -5
- data/lib/glossarist/cli/validate_command.rb +21 -5
- data/lib/glossarist/collection.rb +2 -2
- data/lib/glossarist/collections/bibliography_collection.rb +2 -1
- data/lib/glossarist/collections/collection.rb +2 -2
- data/lib/glossarist/collections/localization_collection.rb +4 -4
- data/lib/glossarist/concept_collector.rb +6 -6
- data/lib/glossarist/concept_document.rb +2 -1
- data/lib/glossarist/concept_manager.rb +6 -7
- data/lib/glossarist/concept_reference.rb +4 -0
- data/lib/glossarist/concept_set.rb +4 -4
- data/lib/glossarist/concept_store.rb +38 -50
- data/lib/glossarist/dataset_register.rb +72 -0
- data/lib/glossarist/dataset_validator.rb +2 -1
- data/lib/glossarist/gcr_metadata.rb +8 -5
- data/lib/glossarist/gcr_package_definition.rb +35 -0
- data/lib/glossarist/gcr_statistics.rb +2 -2
- data/lib/glossarist/glossary_definition.rb +1 -1
- data/lib/glossarist/glossary_store.rb +198 -0
- data/lib/glossarist/managed_concept_collection.rb +2 -2
- data/lib/glossarist/rdf/gloss_citation.rb +8 -4
- data/lib/glossarist/rdf/gloss_concept.rb +6 -3
- data/lib/glossarist/rdf/gloss_concept_date.rb +4 -2
- data/lib/glossarist/rdf/gloss_concept_reference.rb +6 -3
- data/lib/glossarist/rdf/gloss_concept_source.rb +6 -3
- data/lib/glossarist/rdf/gloss_designation.rb +56 -25
- data/lib/glossarist/rdf/gloss_grammar_info.rb +19 -9
- data/lib/glossarist/rdf/gloss_locality.rb +6 -3
- data/lib/glossarist/rdf/gloss_localized_concept.rb +14 -7
- data/lib/glossarist/rdf/gloss_non_verbal_rep.rb +9 -4
- data/lib/glossarist/rdf/gloss_pronunciation.rb +13 -6
- data/lib/glossarist/rdf/gloss_reference.rb +8 -4
- data/lib/glossarist/rdf/namespaces.rb +3 -2
- data/lib/glossarist/rdf/relationship_predicates.rb +14 -7
- data/lib/glossarist/rdf.rb +2 -1
- data/lib/glossarist/register_data.rb +72 -18
- data/lib/glossarist/schema_migration.rb +8 -5
- data/lib/glossarist/section.rb +39 -0
- data/lib/glossarist/transforms/concept_to_gloss_transform.rb +24 -11
- data/lib/glossarist/v2/concept_data.rb +2 -1
- data/lib/glossarist/v2/concept_document.rb +1 -1
- data/lib/glossarist/v3/concept_data.rb +2 -1
- data/lib/glossarist/v3/concept_document.rb +1 -1
- data/lib/glossarist/validation/asset_index.rb +2 -2
- data/lib/glossarist/validation/bibliography_index.rb +2 -1
- data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +2 -1
- data/lib/glossarist/validation/rules/authoritative_source_rule.rb +1 -1
- data/lib/glossarist/validation/rules/bibliography_yaml_rule.rb +1 -1
- data/lib/glossarist/validation/rules/citation_completeness_rule.rb +1 -1
- data/lib/glossarist/validation/rules/concept_count_rule.rb +2 -3
- data/lib/glossarist/validation/rules/concept_id_rule.rb +0 -1
- data/lib/glossarist/validation/rules/concept_id_uniqueness_rule.rb +0 -1
- data/lib/glossarist/validation/rules/concept_mention_rule.rb +1 -2
- data/lib/glossarist/validation/rules/concept_status_rule.rb +1 -2
- data/lib/glossarist/validation/rules/concept_uri_rule.rb +1 -1
- data/lib/glossarist/validation/rules/date_type_rule.rb +5 -3
- data/lib/glossarist/validation/rules/date_validity_rule.rb +1 -1
- data/lib/glossarist/validation/rules/definition_content_rule.rb +1 -2
- data/lib/glossarist/validation/rules/domain_target_rule.rb +1 -1
- data/lib/glossarist/validation/rules/duplicate_term_rule.rb +1 -2
- data/lib/glossarist/validation/rules/entry_status_rule.rb +1 -2
- data/lib/glossarist/validation/rules/filename_id_rule.rb +2 -3
- data/lib/glossarist/validation/rules/image_reference_rule.rb +3 -2
- data/lib/glossarist/validation/rules/l10n_uuid_integrity_rule.rb +1 -2
- data/lib/glossarist/validation/rules/language_coverage_rule.rb +1 -2
- data/lib/glossarist/validation/rules/language_list_rule.rb +2 -3
- data/lib/glossarist/validation/rules/locality_completeness_rule.rb +3 -1
- data/lib/glossarist/validation/rules/localization_consistency_rule.rb +1 -1
- data/lib/glossarist/validation/rules/localization_presence_rule.rb +0 -1
- data/lib/glossarist/validation/rules/model_validity_rule.rb +1 -1
- data/lib/glossarist/validation/rules/orphaned_bibliography_rule.rb +2 -1
- data/lib/glossarist/validation/rules/orphaned_images_rule.rb +6 -4
- data/lib/glossarist/validation/rules/orphaned_l10n_files_rule.rb +1 -2
- data/lib/glossarist/validation/rules/preferred_term_rule.rb +1 -2
- data/lib/glossarist/validation/rules/related_concept_cycle_rule.rb +2 -2
- data/lib/glossarist/validation/rules/related_concept_rule.rb +1 -2
- data/lib/glossarist/validation/rules/related_concept_symmetry_rule.rb +1 -1
- data/lib/glossarist/validation/rules/related_concept_target_rule.rb +1 -1
- data/lib/glossarist/validation/rules/source_type_rule.rb +2 -2
- data/lib/glossarist/validation/rules/source_urn_format_rule.rb +2 -2
- data/lib/glossarist/validation/rules/terms_presence_rule.rb +1 -1
- data/lib/glossarist/validation/rules/uuid_format_rule.rb +1 -1
- data/lib/glossarist/version.rb +1 -1
- data/lib/glossarist.rb +7 -0
- data/scripts/migrate_dataset.rb +14 -8
- data/scripts/migrate_isotc204_to_v3.rb +3 -1
- data/scripts/migrate_isotc211_to_v3.rb +5 -3
- data/scripts/migrate_osgeo_to_v3.rb +4 -2
- data/scripts/upgrade_dataset_to_v3.rb +0 -0
- metadata +15 -5
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "lutaml/store"
|
|
4
|
-
|
|
5
3
|
module Glossarist
|
|
6
4
|
class ConceptStore
|
|
7
|
-
#
|
|
8
|
-
# YAML string
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# model exactly, and explicit metadata fields let the store index and
|
|
12
|
-
# query by uuid/identifier without deserializing.
|
|
13
|
-
class Serializer
|
|
14
|
-
def serialize(model)
|
|
5
|
+
# Serializes ConceptDocument for storage in lutaml-store.
|
|
6
|
+
# Stores the YAML stream string to preserve the full concept + localizations.
|
|
7
|
+
class ConceptDocumentSerializer
|
|
8
|
+
def serialize(concept_document)
|
|
15
9
|
{
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"_identifier" => model.identifier,
|
|
10
|
+
"_yamls" => concept_document.to_yamls,
|
|
11
|
+
"_id" => concept_document.id,
|
|
19
12
|
}
|
|
20
13
|
end
|
|
21
14
|
|
|
22
15
|
def deserialize(data, model_class)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
doc = model_class.from_yamls(data["_yamls"])
|
|
17
|
+
doc.id = data["_id"]
|
|
18
|
+
concept = doc.concept
|
|
19
|
+
concept.uuid = doc.id if doc.id && concept
|
|
20
|
+
doc.localizations.each { |l10n| concept&.add_localization(l10n) }
|
|
21
|
+
doc
|
|
27
22
|
end
|
|
28
23
|
end
|
|
29
24
|
|
|
@@ -32,62 +27,55 @@ module Glossarist
|
|
|
32
27
|
def initialize(adapter: :memory)
|
|
33
28
|
@db = Lutaml::Store::DatabaseStore.new(
|
|
34
29
|
adapter: adapter,
|
|
35
|
-
models: [
|
|
30
|
+
models: [concept_document_registration],
|
|
36
31
|
)
|
|
37
32
|
end
|
|
38
33
|
|
|
39
|
-
def
|
|
40
|
-
db.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def fetch(uuid)
|
|
44
|
-
db.fetch(model: ManagedConcept, uuid: uuid)
|
|
45
|
-
end
|
|
34
|
+
def load_glossary(path)
|
|
35
|
+
documents = db.load_all(
|
|
36
|
+
V3::ConceptDocument, path: path, format: :yamls, layout: :grouped
|
|
37
|
+
)
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
documents.each do |doc|
|
|
40
|
+
concept = doc.concept
|
|
41
|
+
concept.uuid = doc.id
|
|
42
|
+
db.save(doc)
|
|
43
|
+
end
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
db.update(model: ManagedConcept, uuid: uuid, attributes: attributes)
|
|
45
|
+
documents
|
|
53
46
|
end
|
|
54
47
|
|
|
55
|
-
def
|
|
56
|
-
db.
|
|
48
|
+
def fetch(uuid)
|
|
49
|
+
doc = db.fetch(model: V3::ConceptDocument, id: uuid)
|
|
50
|
+
doc&.concept
|
|
57
51
|
end
|
|
58
52
|
|
|
59
|
-
def
|
|
60
|
-
db.all(model:
|
|
53
|
+
def concepts
|
|
54
|
+
db.all(model: V3::ConceptDocument).map(&:concept)
|
|
61
55
|
end
|
|
62
56
|
|
|
63
57
|
def count
|
|
64
|
-
db.count(model:
|
|
58
|
+
db.count(model: V3::ConceptDocument)
|
|
65
59
|
end
|
|
66
60
|
|
|
67
61
|
def exists?(uuid)
|
|
68
|
-
db.exists?(model:
|
|
62
|
+
db.exists?(model: V3::ConceptDocument, id: uuid)
|
|
69
63
|
end
|
|
70
64
|
|
|
71
65
|
def clear
|
|
72
|
-
all.each
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def load_from_directory(path, format: :yaml, layout: :separate)
|
|
76
|
-
db.import_all(ManagedConcept, path: path, format: format, layout: layout)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def save_to_directory(path, format: :yaml, layout: :separate)
|
|
80
|
-
db.save_all(all, path: path, format: format, layout: layout)
|
|
66
|
+
db.all(model: V3::ConceptDocument).each do |doc|
|
|
67
|
+
db.destroy(model: V3::ConceptDocument, id: doc.id)
|
|
68
|
+
end
|
|
81
69
|
end
|
|
82
70
|
|
|
83
71
|
private
|
|
84
72
|
|
|
85
|
-
def
|
|
73
|
+
def concept_document_registration
|
|
86
74
|
{
|
|
87
|
-
model:
|
|
88
|
-
key: :
|
|
89
|
-
dir: "
|
|
90
|
-
serializer:
|
|
75
|
+
model: V3::ConceptDocument,
|
|
76
|
+
key: :id,
|
|
77
|
+
dir: "concepts",
|
|
78
|
+
serializer: ConceptDocumentSerializer.new,
|
|
91
79
|
}
|
|
92
80
|
end
|
|
93
81
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Glossarist
|
|
4
|
+
class DatasetRegister < Lutaml::Model::Serializable
|
|
5
|
+
attribute :schema_type, :string, default: -> { "glossarist" }
|
|
6
|
+
attribute :schema_version, :string, default: -> { "3" }
|
|
7
|
+
attribute :id, :string
|
|
8
|
+
attribute :ref, :string
|
|
9
|
+
attribute :year, :integer
|
|
10
|
+
attribute :urn, :string
|
|
11
|
+
attribute :urn_aliases, :string, collection: true
|
|
12
|
+
attribute :ref_aliases, :string, collection: true
|
|
13
|
+
attribute :status, :string
|
|
14
|
+
attribute :supersedes, :string
|
|
15
|
+
attribute :owner, :string
|
|
16
|
+
attribute :source_repo, :string
|
|
17
|
+
attribute :tags, :string, collection: true
|
|
18
|
+
attribute :languages, :string, collection: true
|
|
19
|
+
attribute :language_order, :string, collection: true
|
|
20
|
+
attribute :ordering, :string
|
|
21
|
+
attribute :sections, Section, collection: true
|
|
22
|
+
attribute :description, :hash
|
|
23
|
+
attribute :about, :hash
|
|
24
|
+
attribute :logo, :string
|
|
25
|
+
|
|
26
|
+
key_value do
|
|
27
|
+
map "schema_type", to: :schema_type
|
|
28
|
+
map "schema_version", to: :schema_version
|
|
29
|
+
map "id", to: :id
|
|
30
|
+
map "ref", to: :ref
|
|
31
|
+
map "year", to: :year
|
|
32
|
+
map "urn", to: :urn
|
|
33
|
+
map "urnAliases", to: :urn_aliases
|
|
34
|
+
map "refAliases", to: :ref_aliases
|
|
35
|
+
map "status", to: :status
|
|
36
|
+
map "supersedes", to: :supersedes
|
|
37
|
+
map "owner", to: :owner
|
|
38
|
+
map "sourceRepo", to: :source_repo
|
|
39
|
+
map "tags", to: :tags
|
|
40
|
+
map "languages", to: :languages
|
|
41
|
+
map "languageOrder", to: :language_order
|
|
42
|
+
map "ordering", to: :ordering
|
|
43
|
+
map "sections", to: :sections
|
|
44
|
+
map "description", to: :description
|
|
45
|
+
map "about", to: :about
|
|
46
|
+
map "logo", to: :logo
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def section_by_id(target_id)
|
|
50
|
+
sections&.each do |section|
|
|
51
|
+
return section if section.id == target_id
|
|
52
|
+
|
|
53
|
+
found = section.descendant_by_id(target_id)
|
|
54
|
+
return found if found
|
|
55
|
+
end
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.from_file(path)
|
|
60
|
+
return nil unless File.exist?(path)
|
|
61
|
+
|
|
62
|
+
from_yaml(File.read(path, encoding: "utf-8"))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.from_directory(dir)
|
|
66
|
+
register_path = File.join(dir, "register.yaml")
|
|
67
|
+
return nil unless File.exist?(register_path)
|
|
68
|
+
|
|
69
|
+
from_file(register_path)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -28,7 +28,8 @@ module Glossarist
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def validate_directory(path, reference_path: nil)
|
|
31
|
-
result = ConceptValidator.new(path,
|
|
31
|
+
result = ConceptValidator.new(path,
|
|
32
|
+
on_progress: @on_progress).validate_all
|
|
32
33
|
|
|
33
34
|
if reference_path
|
|
34
35
|
ref_result = validate_directory_cross_references(path, reference_path)
|
|
@@ -21,6 +21,7 @@ module Glossarist
|
|
|
21
21
|
attribute :concept_uri_template, :string
|
|
22
22
|
attribute :compiled_formats, :string, collection: true
|
|
23
23
|
attribute :external_references, :hash, collection: true
|
|
24
|
+
attribute :translations, :hash, default: -> { {} }
|
|
24
25
|
|
|
25
26
|
key_value do
|
|
26
27
|
map :shortname, to: :shortname
|
|
@@ -42,28 +43,30 @@ module Glossarist
|
|
|
42
43
|
map :concept_uri_template, to: :concept_uri_template
|
|
43
44
|
map :compiled_formats, to: :compiled_formats
|
|
44
45
|
map :external_references, to: :external_references
|
|
46
|
+
map :translations, to: :translations
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def self.from_concepts(concepts, register_data: nil, options: {})
|
|
48
50
|
stats = GcrStatistics.from_concepts(concepts)
|
|
49
51
|
rd = register_data
|
|
50
52
|
new(
|
|
51
|
-
shortname: options[:shortname] || rd&.
|
|
52
|
-
version: options[:version] || rd&.
|
|
53
|
-
title: options[:title] || rd&.
|
|
54
|
-
description: options[:description] || rd&.
|
|
53
|
+
shortname: options[:shortname] || rd&.shortname,
|
|
54
|
+
version: options[:version] || rd&.version,
|
|
55
|
+
title: options[:title] || rd&.name,
|
|
56
|
+
description: options[:description] || rd&.description,
|
|
55
57
|
owner: options[:owner],
|
|
56
58
|
tags: options[:tags] || [],
|
|
57
59
|
concept_count: concepts.length,
|
|
58
60
|
languages: stats.languages,
|
|
59
61
|
created_at: Time.now.utc.iso8601,
|
|
60
62
|
glossarist_version: Glossarist::VERSION,
|
|
61
|
-
schema_version: rd&.
|
|
63
|
+
schema_version: rd&.schema_version || SchemaMigration::CURRENT_SCHEMA_VERSION,
|
|
62
64
|
statistics: stats,
|
|
63
65
|
uri_prefix: options[:uri_prefix],
|
|
64
66
|
concept_uri_template: options[:concept_uri_template],
|
|
65
67
|
compiled_formats: options[:compiled_formats] || [],
|
|
66
68
|
external_references: derive_external_references(concepts),
|
|
69
|
+
translations: rd&.translations || {},
|
|
67
70
|
)
|
|
68
71
|
end
|
|
69
72
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Glossarist
|
|
4
|
+
module GcrPackageDefinition
|
|
5
|
+
def self.definition(concept_document_class: V3::ConceptDocument)
|
|
6
|
+
Lutaml::Store::PackageDefinition.new(
|
|
7
|
+
name: :gcr,
|
|
8
|
+
metadata_model: GcrMetadata,
|
|
9
|
+
metadata_file: "metadata.yaml",
|
|
10
|
+
) do |pkg|
|
|
11
|
+
pkg.model(
|
|
12
|
+
model: concept_document_class,
|
|
13
|
+
dir: "concepts",
|
|
14
|
+
layout: :grouped,
|
|
15
|
+
key: :id,
|
|
16
|
+
default_format: :yamls,
|
|
17
|
+
serializer: ConceptStore::ConceptDocumentSerializer.new,
|
|
18
|
+
)
|
|
19
|
+
pkg.model(
|
|
20
|
+
model: RegisterData,
|
|
21
|
+
file: "register.yaml",
|
|
22
|
+
key: :key,
|
|
23
|
+
default_format: :yaml,
|
|
24
|
+
)
|
|
25
|
+
pkg.model(
|
|
26
|
+
model: BibliographyData,
|
|
27
|
+
file: "bibliography.yaml",
|
|
28
|
+
key: :shortname,
|
|
29
|
+
default_format: :yaml,
|
|
30
|
+
)
|
|
31
|
+
pkg.asset("images", type: :directory)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -21,8 +21,8 @@ module Glossarist
|
|
|
21
21
|
|
|
22
22
|
new(
|
|
23
23
|
total_concepts: concepts.length,
|
|
24
|
-
languages: l10ns.
|
|
25
|
-
concepts_by_status: l10ns.
|
|
24
|
+
languages: l10ns.filter_map(&:language_code).sort.uniq,
|
|
25
|
+
concepts_by_status: l10ns.filter_map(&:entry_status).tally,
|
|
26
26
|
concepts_with_definitions: count_with(l10ns, :definition),
|
|
27
27
|
concepts_with_sources: count_with(l10ns, :sources),
|
|
28
28
|
)
|
|
@@ -30,7 +30,7 @@ module Glossarist
|
|
|
30
30
|
CONCEPT_STATUSES = config.dig("concept", "status").freeze
|
|
31
31
|
|
|
32
32
|
DESIGNATION_RELATIONSHIP_TYPES = config.dig("designation",
|
|
33
|
-
|
|
33
|
+
"relationship_type")&.freeze
|
|
34
34
|
|
|
35
35
|
ISO12620_TERM_TYPES = config.dig("iso12620", "term_type").freeze
|
|
36
36
|
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Glossarist
|
|
4
|
+
class GlossaryStore
|
|
5
|
+
attr_reader :package
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@package = nil
|
|
9
|
+
@concept_document_class = V3::ConceptDocument
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# ── Load ──
|
|
13
|
+
|
|
14
|
+
def load_directory(path, format: nil)
|
|
15
|
+
metadata = load_metadata_from_directory(path)
|
|
16
|
+
@concept_document_class = resolve_concept_document_class(metadata)
|
|
17
|
+
|
|
18
|
+
definition = GcrPackageDefinition.definition(
|
|
19
|
+
concept_document_class: @concept_document_class,
|
|
20
|
+
)
|
|
21
|
+
@package = Lutaml::Store::PackageStore.load(
|
|
22
|
+
definition, path, transport: :directory, format: format
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
apply_metadata(metadata)
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def load_zip(path, format: nil)
|
|
30
|
+
metadata = load_metadata_from_zip(path)
|
|
31
|
+
@concept_document_class = resolve_concept_document_class(metadata)
|
|
32
|
+
|
|
33
|
+
definition = GcrPackageDefinition.definition(
|
|
34
|
+
concept_document_class: @concept_document_class,
|
|
35
|
+
)
|
|
36
|
+
@package = Lutaml::Store::PackageStore.load(
|
|
37
|
+
definition, path, transport: :zip, format: format
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
apply_metadata(metadata)
|
|
41
|
+
self
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def load(path, format: nil)
|
|
45
|
+
ext = File.extname(path).downcase
|
|
46
|
+
if [".gcr", ".zip"].include?(ext)
|
|
47
|
+
load_zip(path, format: format)
|
|
48
|
+
else
|
|
49
|
+
load_directory(path, format: format)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# ── Save ──
|
|
54
|
+
|
|
55
|
+
def save_directory(path, format: nil, formats: {})
|
|
56
|
+
@package.save(path, transport: :directory, format: format,
|
|
57
|
+
formats: formats)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def save_zip(path, format: nil, formats: {})
|
|
61
|
+
@package.save(path, transport: :zip, format: format, formats: formats)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# ── Concepts ──
|
|
65
|
+
|
|
66
|
+
def concepts
|
|
67
|
+
@package.models_for(@concept_document_class).map(&:to_managed_concept)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def concept(uuid)
|
|
71
|
+
doc = @package.fetch_model(@concept_document_class, uuid)
|
|
72
|
+
doc&.to_managed_concept
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def add_concept(managed_concept)
|
|
76
|
+
ensure_package
|
|
77
|
+
doc = @concept_document_class.from_managed_concept(managed_concept)
|
|
78
|
+
doc.id = managed_concept.uuid
|
|
79
|
+
@package.add_model(doc)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def remove_concept(uuid)
|
|
83
|
+
@package.remove_model(@concept_document_class, uuid)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def concept_count
|
|
87
|
+
@package.model_count(@concept_document_class)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def concept_exists?(uuid)
|
|
91
|
+
@package.model_exists?(@concept_document_class, uuid)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ── Metadata ──
|
|
95
|
+
|
|
96
|
+
def metadata
|
|
97
|
+
@package&.metadata
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def metadata=(value)
|
|
101
|
+
ensure_package
|
|
102
|
+
@package.metadata = value
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# ── Register Data ──
|
|
106
|
+
|
|
107
|
+
def register_data
|
|
108
|
+
@package.models_for(RegisterData).first
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def register_data=(value)
|
|
112
|
+
ensure_package
|
|
113
|
+
existing = register_data
|
|
114
|
+
@package.remove_model(RegisterData, existing.key) if existing
|
|
115
|
+
@package.add_model(value)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# ── Bibliography ──
|
|
119
|
+
|
|
120
|
+
def bibliography
|
|
121
|
+
@package.models_for(BibliographyData).first
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def bibliography=(value)
|
|
125
|
+
ensure_package
|
|
126
|
+
existing = bibliography
|
|
127
|
+
@package.remove_model(BibliographyData, existing.shortname) if existing
|
|
128
|
+
@package.add_model(value)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# ── Images ──
|
|
132
|
+
|
|
133
|
+
def image(path)
|
|
134
|
+
@package.asset(path)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def add_image(path, content)
|
|
138
|
+
ensure_package
|
|
139
|
+
@package.add_asset(path, content)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def image_paths
|
|
143
|
+
@package.asset_paths.select { |p| p.start_with?("images/") }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# ── Stats ──
|
|
147
|
+
|
|
148
|
+
def stats
|
|
149
|
+
@package&.stats
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# ── Convenience ──
|
|
153
|
+
|
|
154
|
+
def build_metadata(shortname:, version:, **opts)
|
|
155
|
+
GcrMetadata.from_concepts(concepts, register_data: register_data, options: {
|
|
156
|
+
shortname: shortname,
|
|
157
|
+
version: version,
|
|
158
|
+
**opts,
|
|
159
|
+
})
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
def ensure_package
|
|
165
|
+
return if @package
|
|
166
|
+
|
|
167
|
+
definition = GcrPackageDefinition.definition(
|
|
168
|
+
concept_document_class: @concept_document_class,
|
|
169
|
+
)
|
|
170
|
+
@package = Lutaml::Store::PackageStore.new(definition)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def resolve_concept_document_class(metadata)
|
|
174
|
+
version = metadata&.schema_version.to_s
|
|
175
|
+
ConceptDocument.for_version(version)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def load_metadata_from_directory(path)
|
|
179
|
+
file_path = File.join(path, "metadata.yaml")
|
|
180
|
+
return nil unless File.exist?(file_path)
|
|
181
|
+
|
|
182
|
+
GcrMetadata.from_yaml(File.read(file_path, encoding: "utf-8"))
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def load_metadata_from_zip(path)
|
|
186
|
+
Zip::File.open(path) do |zf|
|
|
187
|
+
entry = zf.find_entry("metadata.yaml")
|
|
188
|
+
return nil unless entry
|
|
189
|
+
|
|
190
|
+
GcrMetadata.from_yaml(entry.get_input_stream.read)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def apply_metadata(metadata)
|
|
195
|
+
@package.metadata = metadata if metadata && @package
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -18,10 +18,14 @@ module Glossarist
|
|
|
18
18
|
|
|
19
19
|
types "gloss:Citation"
|
|
20
20
|
|
|
21
|
-
predicate :citationSource, namespace: Namespaces::GlossaristNamespace,
|
|
22
|
-
|
|
23
|
-
predicate :
|
|
24
|
-
|
|
21
|
+
predicate :citationSource, namespace: Namespaces::GlossaristNamespace,
|
|
22
|
+
to: :source
|
|
23
|
+
predicate :citationId, namespace: Namespaces::GlossaristNamespace,
|
|
24
|
+
to: :id
|
|
25
|
+
predicate :citationVersion, namespace: Namespaces::GlossaristNamespace,
|
|
26
|
+
to: :version
|
|
27
|
+
predicate :citationLink, namespace: Namespaces::GlossaristNamespace,
|
|
28
|
+
to: :link
|
|
25
29
|
|
|
26
30
|
members :locality, link: "gloss:hasLocality"
|
|
27
31
|
end
|
|
@@ -28,8 +28,10 @@ module Glossarist
|
|
|
28
28
|
|
|
29
29
|
types "gloss:Concept", "skos:Concept"
|
|
30
30
|
|
|
31
|
-
predicate :identifier, namespace: Namespaces::GlossaristNamespace,
|
|
32
|
-
|
|
31
|
+
predicate :identifier, namespace: Namespaces::GlossaristNamespace,
|
|
32
|
+
to: :identifier
|
|
33
|
+
predicate :hasStatus, namespace: Namespaces::GlossaristNamespace,
|
|
34
|
+
to: :status, uri_reference: true
|
|
33
35
|
|
|
34
36
|
members :localizations,
|
|
35
37
|
link: "gloss:hasLocalization"
|
|
@@ -41,7 +43,8 @@ module Glossarist
|
|
|
41
43
|
link: "gloss:hasDate"
|
|
42
44
|
|
|
43
45
|
RelationshipPredicates::CONCEPT_REL_PREDICATES.each do |type, (ns, name)|
|
|
44
|
-
predicate name, namespace: ns, to: :"#{type}_targets",
|
|
46
|
+
predicate name, namespace: ns, to: :"#{type}_targets",
|
|
47
|
+
uri_reference: true
|
|
45
48
|
end
|
|
46
49
|
end
|
|
47
50
|
end
|
|
@@ -16,8 +16,10 @@ module Glossarist
|
|
|
16
16
|
|
|
17
17
|
types "gloss:ConceptDate"
|
|
18
18
|
|
|
19
|
-
predicate :dateValue, namespace: Namespaces::GlossaristNamespace,
|
|
20
|
-
|
|
19
|
+
predicate :dateValue, namespace: Namespaces::GlossaristNamespace,
|
|
20
|
+
to: :date_value
|
|
21
|
+
predicate :dateType, namespace: Namespaces::GlossaristNamespace,
|
|
22
|
+
to: :date_type, uri_reference: true
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
@@ -19,9 +19,12 @@ module Glossarist
|
|
|
19
19
|
|
|
20
20
|
types "gloss:ConceptReference"
|
|
21
21
|
|
|
22
|
-
predicate :refType, namespace: Namespaces::GlossaristNamespace,
|
|
23
|
-
|
|
24
|
-
predicate :
|
|
22
|
+
predicate :refType, namespace: Namespaces::GlossaristNamespace,
|
|
23
|
+
to: :ref_type
|
|
24
|
+
predicate :conceptId, namespace: Namespaces::GlossaristNamespace,
|
|
25
|
+
to: :concept_id
|
|
26
|
+
predicate :sourceUri, namespace: Namespaces::GlossaristNamespace,
|
|
27
|
+
to: :source
|
|
25
28
|
predicate :urn, namespace: Namespaces::GlossaristNamespace, to: :urn
|
|
26
29
|
end
|
|
27
30
|
end
|
|
@@ -17,9 +17,12 @@ module Glossarist
|
|
|
17
17
|
|
|
18
18
|
types "gloss:ConceptSource"
|
|
19
19
|
|
|
20
|
-
predicate :sourceStatus, namespace: Namespaces::GlossaristNamespace,
|
|
21
|
-
|
|
22
|
-
predicate :
|
|
20
|
+
predicate :sourceStatus, namespace: Namespaces::GlossaristNamespace,
|
|
21
|
+
to: :status, uri_reference: true
|
|
22
|
+
predicate :sourceType, namespace: Namespaces::GlossaristNamespace,
|
|
23
|
+
to: :type, uri_reference: true
|
|
24
|
+
predicate :modification, namespace: Namespaces::GlossaristNamespace,
|
|
25
|
+
to: :modification
|
|
23
26
|
|
|
24
27
|
members :origin, link: "gloss:sourceOrigin"
|
|
25
28
|
end
|