opencdd 0.2.1 → 0.2.3
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/lib/opencdd/database.rb +1 -0
- data/lib/opencdd/entity.rb +11 -0
- data/lib/opencdd/exporters/json.rb +9 -0
- data/lib/opencdd/list_unit.rb +6 -0
- data/lib/opencdd/meta_class.rb +10 -0
- data/lib/opencdd/parcel/flat_dir_reader.rb +1 -0
- data/lib/opencdd/parcel/layout_detector.rb +1 -1
- data/lib/opencdd/parcel/sheet_schema.rb +78 -0
- data/lib/opencdd/version.rb +1 -1
- data/lib/opencdd/visitor.rb +9 -0
- data/lib/opencdd.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0782b45aeee8bad692974cd0480dd8430f13c92f405760188a13df3e3b2c77ed'
|
|
4
|
+
data.tar.gz: a4e26b1842e838b8e9464d0ff782ec745d59b96e9f5637e8630de9343218805d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 12267bf271cabfeedb613766a6f679843d3be7fe542a96b097c9804ae7014c2a6fa5d96c2bafeeeefdaf7bbd9878ccde9aeca85423bbc40ad07ef3b7fb1428b7
|
|
7
|
+
data.tar.gz: 23a8abce3684e130d3e7bff46973b579c3a71d9212153aea4f216314e6ab9ff7747b3a0030ecb1a0cd9134a3dab6dc83b782132d83a4feea8c2c36052994bfb0
|
data/lib/opencdd/database.rb
CHANGED
|
@@ -109,6 +109,7 @@ module Opencdd
|
|
|
109
109
|
def value_terms ; @entities_by_type[:value_term] || [] ; end
|
|
110
110
|
def relations ; @entities_by_type[:relation] || [] ; end
|
|
111
111
|
def view_controls ; @entities_by_type[:view_control] || [] ; end
|
|
112
|
+
def list_of_units ; @entities_by_type[:list_of_unit] || [] ; end
|
|
112
113
|
|
|
113
114
|
def entities_of_type(type)
|
|
114
115
|
@entities_by_type[type.to_sym] || []
|
data/lib/opencdd/entity.rb
CHANGED
|
@@ -69,6 +69,17 @@ module Opencdd
|
|
|
69
69
|
def self.from_row(row, schema:, meta_class_irdi:, code_property_id: nil)
|
|
70
70
|
code_property_id ||= default_code_property_id(meta_class_irdi)
|
|
71
71
|
raw_code = code_property_id && row[code_property_id]
|
|
72
|
+
# Fall back to other known code property IDs when the entity-
|
|
73
|
+
# specific one is absent (happens with name-only header sheets
|
|
74
|
+
# where "Code" synthesizes to MDC_P001_5 regardless of type).
|
|
75
|
+
if raw_code.nil? || raw_code.to_s.strip.empty?
|
|
76
|
+
Opencdd::MetaClasses::CODE_PROPERTY_IDS.each_value do |alt_id|
|
|
77
|
+
val = row[alt_id]
|
|
78
|
+
next if val.nil? || val.to_s.strip.empty?
|
|
79
|
+
raw_code = val
|
|
80
|
+
break
|
|
81
|
+
end
|
|
82
|
+
end
|
|
72
83
|
irdi = raw_code && Opencdd::IRDI.parse(raw_code)
|
|
73
84
|
|
|
74
85
|
props = row.each_with_object({}) do |(k, v), h|
|
|
@@ -53,6 +53,10 @@ module Opencdd
|
|
|
53
53
|
@nodes << view_control_node(vc)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def visit_list_of_unit(lou)
|
|
57
|
+
@nodes << list_of_unit_node(lou)
|
|
58
|
+
end
|
|
59
|
+
|
|
56
60
|
# ─────────────────────────────────────────────────────────────
|
|
57
61
|
# Public per-entity payload API
|
|
58
62
|
#
|
|
@@ -73,6 +77,7 @@ module Opencdd
|
|
|
73
77
|
Opencdd::ValueTerm => :value_term_node,
|
|
74
78
|
Opencdd::Relation => :relation_node,
|
|
75
79
|
Opencdd::ViewControl => :view_control_node,
|
|
80
|
+
Opencdd::ListUnit => :list_of_unit_node,
|
|
76
81
|
}.freeze
|
|
77
82
|
|
|
78
83
|
def payload_for(entity, database: nil)
|
|
@@ -125,6 +130,10 @@ module Opencdd
|
|
|
125
130
|
entity_payload(vc).merge(type: "view_control").compact
|
|
126
131
|
end
|
|
127
132
|
|
|
133
|
+
def list_of_unit_node(lou)
|
|
134
|
+
entity_payload(lou).merge(type: "list_of_unit").compact
|
|
135
|
+
end
|
|
136
|
+
|
|
128
137
|
private
|
|
129
138
|
|
|
130
139
|
# Iterates every declared field on the entity's class (walking
|
data/lib/opencdd/meta_class.rb
CHANGED
|
@@ -79,6 +79,7 @@ module Opencdd
|
|
|
79
79
|
"MDC_C011" => "MDC_P001_13",
|
|
80
80
|
"MDC_C009" => "MDC_P001_10",
|
|
81
81
|
"MDC_C010" => "MDC_P001_11",
|
|
82
|
+
"MDC_C0100" => "C0101",
|
|
82
83
|
"EXT_C001" => "EXT_P001",
|
|
83
84
|
}.freeze
|
|
84
85
|
|
|
@@ -89,6 +90,7 @@ module Opencdd
|
|
|
89
90
|
"MDC_C011" => :relation,
|
|
90
91
|
"MDC_C009" => :unit,
|
|
91
92
|
"MDC_C010" => :value_term,
|
|
93
|
+
"MDC_C0100" => :list_of_unit,
|
|
92
94
|
"EXT_C001" => :view_control,
|
|
93
95
|
}.freeze
|
|
94
96
|
|
|
@@ -252,6 +254,13 @@ module Opencdd
|
|
|
252
254
|
type: :view_control,
|
|
253
255
|
allowed_property_ids: common + %w[EXT_P002 EXT_P003],
|
|
254
256
|
)
|
|
257
|
+
list_of_unit = MetaClass.new(
|
|
258
|
+
irdi: "MDC_C0100",
|
|
259
|
+
name: "ListOfUnit",
|
|
260
|
+
entity_class: Opencdd::ListUnit,
|
|
261
|
+
type: :list_of_unit,
|
|
262
|
+
allowed_property_ids: common,
|
|
263
|
+
)
|
|
255
264
|
{
|
|
256
265
|
klass_class.irdi => klass_class,
|
|
257
266
|
property_class.irdi => property_class,
|
|
@@ -260,6 +269,7 @@ module Opencdd
|
|
|
260
269
|
unit.irdi => unit,
|
|
261
270
|
value_term.irdi => value_term,
|
|
262
271
|
view_control.irdi => view_control,
|
|
272
|
+
list_of_unit.irdi => list_of_unit,
|
|
263
273
|
}
|
|
264
274
|
end
|
|
265
275
|
end
|
|
@@ -32,7 +32,7 @@ module Opencdd
|
|
|
32
32
|
|
|
33
33
|
# Per-type export filename produced by cdd.iec.ch's download
|
|
34
34
|
# endpoint.
|
|
35
|
-
FILE_PATTERN = /\Aexport_(CLASS|PROPERTY|RELATION|UNIT|VALUELIST|VALUETERMS)_[^\.]+\.(xls|xlsx)\z/i.freeze
|
|
35
|
+
FILE_PATTERN = /\Aexport_(CLASS|PROPERTY|RELATION|UNIT|VALUELIST|VALUETERMS|LISTOFUNITS)_[^\.]+\.(xls|xlsx)\z/i.freeze
|
|
36
36
|
|
|
37
37
|
module_function
|
|
38
38
|
|
|
@@ -159,6 +159,9 @@ module Opencdd
|
|
|
159
159
|
|
|
160
160
|
def finalize!
|
|
161
161
|
ids = @column_directives["PROPERTY_ID"] || []
|
|
162
|
+
if ids.empty? || ids.all? { |id| id.nil? || id.to_s.strip.empty? }
|
|
163
|
+
ids = synthesize_ids_from_names
|
|
164
|
+
end
|
|
162
165
|
ids.each_with_index do |id, idx|
|
|
163
166
|
next if id.nil? || id.to_s.strip.empty?
|
|
164
167
|
|
|
@@ -194,6 +197,81 @@ module Opencdd
|
|
|
194
197
|
freeze
|
|
195
198
|
end
|
|
196
199
|
|
|
200
|
+
# When a sheet has no #PROPERTY_ID directive row (only
|
|
201
|
+
# #PROPERTY_NAME), synthesize property IDs from the names.
|
|
202
|
+
# This happens with some export formats (notably RELATION
|
|
203
|
+
# exports from cdd.iec.ch) that omit the PROPERTY_ID row.
|
|
204
|
+
NAME_TO_PROPERTY_ID = {
|
|
205
|
+
"Code" => "MDC_P001_5",
|
|
206
|
+
"Version" => "MDC_P002_1",
|
|
207
|
+
"Revision" => "MDC_P002_2",
|
|
208
|
+
"VersionInitiationDate" => "MDC_P003_1",
|
|
209
|
+
"VersionReleaseDate" => "MDC_P003_2",
|
|
210
|
+
"RevisionReleaseDate" => "MDC_P003_3",
|
|
211
|
+
"PreferredName" => "MDC_P004",
|
|
212
|
+
"SynonymousName" => "MDC_P007",
|
|
213
|
+
"ShortName" => "MDC_P005",
|
|
214
|
+
"Definition" => "MDC_P006",
|
|
215
|
+
"DefinitionSource" => "MDC_P006_1",
|
|
216
|
+
"Note" => "MDC_P008",
|
|
217
|
+
"Remark" => "MDC_P009",
|
|
218
|
+
"Drawing" => "MDC_P008_1",
|
|
219
|
+
"GUID" => "MDC_P066",
|
|
220
|
+
"TimeStamp" => "MDC_P067",
|
|
221
|
+
"ClassType" => "MDC_P011",
|
|
222
|
+
"Superclass" => "MDC_P010",
|
|
223
|
+
"IsCaseOf" => "MDC_P013",
|
|
224
|
+
"ApplicableProperties" => "MDC_P014",
|
|
225
|
+
"ImportedProperties" => "MDC_P090",
|
|
226
|
+
"SubClassSelection" => "MDC_P016",
|
|
227
|
+
"DataType" => "MDC_P022",
|
|
228
|
+
"ValueFormat" => "MDC_P024",
|
|
229
|
+
"DefinitionClass" => "MDC_P021",
|
|
230
|
+
"Unit" => "MDC_P041",
|
|
231
|
+
"Condition" => "MDC_P028",
|
|
232
|
+
"ListType" => "MDC_P046",
|
|
233
|
+
"CodeList" => "MDC_P044",
|
|
234
|
+
"TermList" => "MDC_P043",
|
|
235
|
+
"EnumerationCode" => "MDC_P044",
|
|
236
|
+
"RelationType" => "MDC_P200",
|
|
237
|
+
"RelationDomain" => "MDC_P201",
|
|
238
|
+
"FunctionDomain" => "MDC_P202",
|
|
239
|
+
"FunctionCodomain" => "MDC_P203",
|
|
240
|
+
"Formula" => "MDC_P204",
|
|
241
|
+
"FormulaLanguage" => "MDC_P205",
|
|
242
|
+
"FormulaExternalSolver" => "MDC_P206",
|
|
243
|
+
"TriggerEvent" => "MDC_P207",
|
|
244
|
+
"DomainElementType" => "MDC_P208",
|
|
245
|
+
"CodomainElementType" => "MDC_P209",
|
|
246
|
+
"Role" => "MDC_P210",
|
|
247
|
+
"Segment" => "MDC_P211",
|
|
248
|
+
"SuperRelation" => "MDC_P212",
|
|
249
|
+
}.freeze
|
|
250
|
+
|
|
251
|
+
def synthesize_ids_from_names
|
|
252
|
+
names = nil
|
|
253
|
+
@column_directives.each do |key, vals|
|
|
254
|
+
base, = key.split(".", 2)
|
|
255
|
+
next unless base == "PROPERTY_NAME"
|
|
256
|
+
names = vals
|
|
257
|
+
break
|
|
258
|
+
end
|
|
259
|
+
return [] unless names
|
|
260
|
+
Array.new(names.size) do |idx|
|
|
261
|
+
val = names[idx]
|
|
262
|
+
next nil if val.nil? || val.to_s.strip.empty?
|
|
263
|
+
raw = val.to_s.strip
|
|
264
|
+
if raw =~ /\A(.+)\.([A-Za-z]{2})\z/
|
|
265
|
+
base = $1
|
|
266
|
+
lang = $2
|
|
267
|
+
pid = NAME_TO_PROPERTY_ID[base]
|
|
268
|
+
pid ? "#{pid}.#{lang.downcase}" : nil
|
|
269
|
+
else
|
|
270
|
+
NAME_TO_PROPERTY_ID[raw]
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
197
275
|
def [](property_id_or_name)
|
|
198
276
|
find_by_property_id(property_id_or_name) || find_by_name(property_id_or_name)
|
|
199
277
|
end
|
data/lib/opencdd/version.rb
CHANGED
data/lib/opencdd/visitor.rb
CHANGED
|
@@ -18,6 +18,7 @@ module Opencdd
|
|
|
18
18
|
visit_value_terms(database)
|
|
19
19
|
visit_relations(database)
|
|
20
20
|
visit_view_controls(database)
|
|
21
|
+
visit_list_of_units(database)
|
|
21
22
|
self
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -55,6 +56,10 @@ module Opencdd
|
|
|
55
56
|
each_sorted(database.view_controls) { |v| visit_view_control(v) }
|
|
56
57
|
end
|
|
57
58
|
|
|
59
|
+
def visit_list_of_units(database)
|
|
60
|
+
each_sorted(database.list_of_units) { |l| visit_list_of_unit(l) }
|
|
61
|
+
end
|
|
62
|
+
|
|
58
63
|
# Single source of truth for sort-by-code traversal. Was
|
|
59
64
|
# duplicated as `.sort_by { |x| x.code.to_s }` in 7 methods.
|
|
60
65
|
def each_sorted(entities)
|
|
@@ -85,6 +90,10 @@ module Opencdd
|
|
|
85
90
|
@seen << vc.irdi if vc.irdi
|
|
86
91
|
end
|
|
87
92
|
|
|
93
|
+
def visit_list_of_unit(lou)
|
|
94
|
+
@seen << lou.irdi if lou.irdi
|
|
95
|
+
end
|
|
96
|
+
|
|
88
97
|
def reset!
|
|
89
98
|
@seen.clear
|
|
90
99
|
self
|
data/lib/opencdd.rb
CHANGED
|
@@ -28,6 +28,7 @@ module Opencdd
|
|
|
28
28
|
autoload :ValueTerm, "opencdd/value_term"
|
|
29
29
|
autoload :Relation, "opencdd/relation"
|
|
30
30
|
autoload :ViewControl, "opencdd/view_control"
|
|
31
|
+
autoload :ListUnit, "opencdd/list_unit"
|
|
31
32
|
|
|
32
33
|
autoload :Database, "opencdd/database"
|
|
33
34
|
autoload :EffectiveProperties, "opencdd/effective_properties"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opencdd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenCDD contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: roo
|
|
@@ -251,6 +251,7 @@ files:
|
|
|
251
251
|
- lib/opencdd/irdi.rb
|
|
252
252
|
- lib/opencdd/klass.rb
|
|
253
253
|
- lib/opencdd/languages.rb
|
|
254
|
+
- lib/opencdd/list_unit.rb
|
|
254
255
|
- lib/opencdd/meta_class.rb
|
|
255
256
|
- lib/opencdd/model.rb
|
|
256
257
|
- lib/opencdd/model/entity_store.rb
|