epb_view_models 1.0.10 → 1.0.14
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/epb_view_models.rb +1 -1
- data/lib/presenter/export/statistics.rb +29 -0
- data/lib/presenter/rd_sap/export_configuration.rb +1 -0
- data/lib/presenter/to_warehouse/base_configuration.rb +23 -0
- data/lib/presenter/xml/parser.rb +220 -0
- data/lib/presenter/xsd.rb +26 -8
- data/lib/view_model_domain/xsd_arguments.rb +3 -2
- data/lib/view_model_gateway/xsd_files_gateway.rb +21 -14
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee84c9018a99e7ecc114cd9e16da64303f337d6d53ecd4f243510fdcdeeace59
|
4
|
+
data.tar.gz: f2a5ecdb96d373dfc64317ab94a626b9fab1c91b9957de9d765927fdca73f5b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf9fc7e313914c1b34ba94c7ea3dd9f83c6a1ae47b80669e53f01b75b1721f57fb57b356e52eeac54d58d24ba3d03e561ff6e5725f4980a42b02b74d5e971345
|
7
|
+
data.tar.gz: cc89d10482409d65e7fadc02fb7db449e2d54bab4f2d7fa8bf45dcc293883201e81d618fbfa36f24eed6c980bd1e65651f89cdda616aa3bc3a75c2d81d40b602
|
data/lib/epb_view_models.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Presenter::Export
|
2
|
+
class Statistics
|
3
|
+
def initialize(wrapper)
|
4
|
+
@wrapper = wrapper
|
5
|
+
@view_model = wrapper.view_model
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
{
|
10
|
+
current_energy_rating: current_energy_rating,
|
11
|
+
transaction_type: @view_model.transaction_type,
|
12
|
+
}
|
13
|
+
rescue NoMethodError
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def current_energy_rating
|
20
|
+
view_model_type = @view_model.class.to_s.split("::")[1].downcase
|
21
|
+
|
22
|
+
if view_model_type.include?("sapschema")
|
23
|
+
@view_model.current_energy_rating
|
24
|
+
elsif view_model_type.include?("cepc")
|
25
|
+
@view_model.energy_efficiency_rating
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Presenter
|
2
|
+
module ToWarehouse
|
3
|
+
class BaseConfiguration
|
4
|
+
def to_args
|
5
|
+
self.class.args
|
6
|
+
end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
KEYS = %i[excludes includes bases preferred_keys list_nodes rootless_list_nodes].freeze
|
10
|
+
|
11
|
+
KEYS.each do |key|
|
12
|
+
define_method key do |arg|
|
13
|
+
args[key] = arg
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def args
|
18
|
+
@args ||= {}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
module Presenter
|
2
|
+
module Xml
|
3
|
+
class Parser
|
4
|
+
def initialize(excludes: [], includes: [], bases: [], preferred_keys: {}, list_nodes: [], rootless_list_nodes: {})
|
5
|
+
@excludes = excludes
|
6
|
+
@includes = includes
|
7
|
+
@bases = bases
|
8
|
+
@preferred_keys = preferred_keys
|
9
|
+
@list_nodes = list_nodes
|
10
|
+
@rootless_list_nodes = rootless_list_nodes
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse(xml)
|
14
|
+
sax_parser.parse xml
|
15
|
+
last_output
|
16
|
+
end
|
17
|
+
|
18
|
+
def sax_parser
|
19
|
+
@assessment_document ||= AssessmentDocument.new excludes: @excludes,
|
20
|
+
includes: @includes,
|
21
|
+
bases: @bases,
|
22
|
+
preferred_keys: @preferred_keys,
|
23
|
+
list_nodes: @list_nodes,
|
24
|
+
rootless_list_nodes: @rootless_list_nodes
|
25
|
+
@sax_parser ||= Nokogiri::XML::SAX::Parser.new @assessment_document
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def last_output
|
31
|
+
@assessment_document.output
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class AssessmentDocument < Nokogiri::XML::SAX::Document
|
36
|
+
def initialize(excludes: [], includes: [], bases: [], preferred_keys: {}, list_nodes: [], rootless_list_nodes: {})
|
37
|
+
@excludes = excludes
|
38
|
+
@includes = includes
|
39
|
+
@bases = bases
|
40
|
+
@preferred_keys = preferred_keys
|
41
|
+
@list_nodes = list_nodes
|
42
|
+
@rootless_list_nodes = rootless_list_nodes
|
43
|
+
super()
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_document
|
47
|
+
init!
|
48
|
+
@output = {}
|
49
|
+
end
|
50
|
+
|
51
|
+
def end_document
|
52
|
+
init!
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_element_namespace(name, attrs = nil, _prefix = nil, _uri = nil, _namespace = nil)
|
56
|
+
@source_position << name
|
57
|
+
@output_position << root_key_for_list if at_rootless_list_node_item?
|
58
|
+
@output_position << as_key(name) unless is_base?(name)
|
59
|
+
@is_excluding = true if @excludes.include?(name)
|
60
|
+
@is_including = true if @includes.include?(name)
|
61
|
+
super
|
62
|
+
if encountered_position? || at_list_node_item?
|
63
|
+
set_up_list
|
64
|
+
end
|
65
|
+
write_encounter
|
66
|
+
end
|
67
|
+
|
68
|
+
def start_element(_name, attrs = nil)
|
69
|
+
@attrs = attrs
|
70
|
+
end
|
71
|
+
|
72
|
+
def end_element_namespace(name, _prefix = nil, _uri = nil)
|
73
|
+
@output_position.pop unless is_base?(name)
|
74
|
+
@output_position.pop if at_rootless_list_node_item?
|
75
|
+
@source_position.pop
|
76
|
+
@is_excluding = false if @excludes.include?(name)
|
77
|
+
@is_including = false if @includes.include?(name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def characters(string)
|
81
|
+
if @is_excluding && !@is_including
|
82
|
+
return
|
83
|
+
end
|
84
|
+
|
85
|
+
stripped = string.strip
|
86
|
+
if stripped.length.zero?
|
87
|
+
return
|
88
|
+
end
|
89
|
+
|
90
|
+
value = try_as_number stripped
|
91
|
+
|
92
|
+
if @attrs.length.positive?
|
93
|
+
value = @attrs.to_h.merge({ "value" => value })
|
94
|
+
end
|
95
|
+
|
96
|
+
set_value value
|
97
|
+
end
|
98
|
+
|
99
|
+
attr_reader :output
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def init!
|
104
|
+
@source_position = []
|
105
|
+
@output_position = []
|
106
|
+
@is_excluding = false
|
107
|
+
@is_including = false
|
108
|
+
@attrs = []
|
109
|
+
@encountered = []
|
110
|
+
end
|
111
|
+
|
112
|
+
def as_key(name)
|
113
|
+
if @preferred_keys.key?(name)
|
114
|
+
return @preferred_keys[name]
|
115
|
+
end
|
116
|
+
|
117
|
+
name.downcase.gsub("-", "_")
|
118
|
+
end
|
119
|
+
|
120
|
+
def set_value(value)
|
121
|
+
set_value_with_keys(value, @output_position)
|
122
|
+
end
|
123
|
+
|
124
|
+
def set_value_with_keys(value, keys)
|
125
|
+
prepare_hash keys
|
126
|
+
*key, last = keys
|
127
|
+
key.inject(@output, :fetch)[last] = value
|
128
|
+
end
|
129
|
+
|
130
|
+
def value_at(keys)
|
131
|
+
keys.inject(@output, :fetch)
|
132
|
+
rescue IndexError
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
136
|
+
def prepare_hash(keys)
|
137
|
+
cursor = @output
|
138
|
+
keys[..-2].each do |key|
|
139
|
+
cursor[key] = {} unless cursor[key] && cursor[key] != ""
|
140
|
+
cursor = cursor[key]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def is_base?(name)
|
145
|
+
@bases.concat(@excludes).include?(name) || name == @source_position[0]
|
146
|
+
end
|
147
|
+
|
148
|
+
def is_numeric?(string)
|
149
|
+
true if Float(string)
|
150
|
+
rescue StandardError
|
151
|
+
false
|
152
|
+
end
|
153
|
+
|
154
|
+
def try_as_number(string)
|
155
|
+
return string unless is_numeric?(string)
|
156
|
+
|
157
|
+
if string.include?(".")
|
158
|
+
string.to_f
|
159
|
+
else
|
160
|
+
string.to_i
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def write_encounter
|
165
|
+
@encountered << source_position_string
|
166
|
+
end
|
167
|
+
|
168
|
+
def encountered_position?
|
169
|
+
@encountered.include? source_position_string
|
170
|
+
end
|
171
|
+
|
172
|
+
def source_position_string
|
173
|
+
@source_position.join(">")
|
174
|
+
end
|
175
|
+
|
176
|
+
def set_up_list
|
177
|
+
return if @output_position.any? { |x| x.is_a? Integer } && !at_list_node_item?
|
178
|
+
|
179
|
+
candidate_list = value_at @output_position[..-2]
|
180
|
+
|
181
|
+
case candidate_list
|
182
|
+
when Array
|
183
|
+
list_index = candidate_list.length
|
184
|
+
when nil
|
185
|
+
set_value_with_keys([], @output_position[..-2])
|
186
|
+
list_index = 0
|
187
|
+
else
|
188
|
+
set_value_with_keys([candidate_list.values[0]], @output_position[..-2])
|
189
|
+
list_index = 1
|
190
|
+
end
|
191
|
+
|
192
|
+
@output_position[-1] = list_index
|
193
|
+
end
|
194
|
+
|
195
|
+
def at_list_node_item?
|
196
|
+
@list_nodes.include?(@source_position[-2]) || at_rootless_list_node_item?
|
197
|
+
end
|
198
|
+
|
199
|
+
def at_rootless_list_node_item?
|
200
|
+
return unless @rootless_list_nodes.key?(@source_position[-1])
|
201
|
+
|
202
|
+
case value = @rootless_list_nodes[@source_position[-1]]
|
203
|
+
when String
|
204
|
+
true
|
205
|
+
else
|
206
|
+
value[:parents].all? { |val| @source_position.include? val }
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def root_key_for_list
|
211
|
+
case value = @rootless_list_nodes[@source_position[-1]]
|
212
|
+
when String
|
213
|
+
value
|
214
|
+
else
|
215
|
+
value[:key]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
data/lib/presenter/xsd.rb
CHANGED
@@ -10,22 +10,16 @@ module Presenter
|
|
10
10
|
end
|
11
11
|
|
12
12
|
hash = {}
|
13
|
-
xpath = "//xs:simpleType[@name='#{domain_arguments.simple_type}']//xs:enumeration"
|
14
13
|
|
15
14
|
xsd_files.each do |file|
|
16
|
-
|
17
|
-
enums_hash = {}
|
18
|
-
REXML::XPath.each(doc, "#{xpath}/@value") do |node|
|
19
|
-
desc_path = "#{xpath}[@value='#{node.value}']//xs:annotation//xs:documentation"
|
20
|
-
enums_hash.merge!(node.value => REXML::XPath.first(doc, desc_path).children.first)
|
21
|
-
end
|
15
|
+
enums_hash = File.extname(file).downcase == ".xsd" ? read_xsd(file, domain_arguments.simple_type) : read_xml(file, domain_arguments.simple_type, domain_arguments.node_hash)
|
22
16
|
|
23
17
|
next if enums_hash.empty?
|
24
18
|
|
25
19
|
hash[xsd_files_gateway.schema_version(file)] = enums_hash
|
26
20
|
end
|
27
21
|
|
28
|
-
raise ViewModelBoundary::NodeNotFound, "Node #{domain_arguments.simple_type} was not found in any of the
|
22
|
+
raise ViewModelBoundary::NodeNotFound, "Node #{domain_arguments.simple_type} was not found in any of the files in #{domain_arguments.xsd_dir_path} directory" if hash.empty?
|
29
23
|
|
30
24
|
hash
|
31
25
|
end
|
@@ -45,5 +39,29 @@ module Presenter
|
|
45
39
|
def variation_between_schema_versions?(enums_hash)
|
46
40
|
enums_hash.values.flatten.uniq.count != 1
|
47
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def read_xsd(file_name, simple_type)
|
46
|
+
xpath = "//xs:simpleType[@name='#{simple_type}']//xs:enumeration"
|
47
|
+
doc = REXML::Document.new(File.read(file_name))
|
48
|
+
enums_hash = {}
|
49
|
+
REXML::XPath.each(doc, "#{xpath}/@value") do |node|
|
50
|
+
desc_path = "#{xpath}[@value='#{node.value}']//xs:annotation//xs:documentation"
|
51
|
+
enums_hash.merge!(node.value => REXML::XPath.first(doc, desc_path).children.first)
|
52
|
+
end
|
53
|
+
enums_hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_xml(file_name, node_name, node_hash)
|
57
|
+
doc = Nokogiri.XML(File.read(file_name))
|
58
|
+
enums_hash = {}
|
59
|
+
|
60
|
+
doc.xpath(node_name).each do |node|
|
61
|
+
enums_hash.merge!(node.xpath(node_hash.keys[0].to_s).children.text => node.xpath(node_hash.values[0]).children.text)
|
62
|
+
end
|
63
|
+
|
64
|
+
enums_hash
|
65
|
+
end
|
48
66
|
end
|
49
67
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module ViewModelDomain
|
2
2
|
class XsdArguments
|
3
|
-
attr_reader :simple_type, :assessment_type, :xsd_dir_path, :gem_path
|
3
|
+
attr_reader :simple_type, :assessment_type, :xsd_dir_path, :gem_path, :node_hash
|
4
4
|
|
5
|
-
def initialize(simple_type:, assessment_type:, xsd_dir_path: "
|
5
|
+
def initialize(simple_type:, assessment_type:, xsd_dir_path: "", gem_path: "", node_hash: nil)
|
6
6
|
@simple_type = simple_type
|
7
7
|
@assessment_type = assessment_type
|
8
8
|
@xsd_dir_path = xsd_dir_path
|
9
9
|
@gem_path = gem_path
|
10
|
+
@node_hash = node_hash
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -2,6 +2,9 @@ module ViewModelGateway
|
|
2
2
|
class XsdFilesGateway
|
3
3
|
attr_reader :simple_type, :assessment_type, :xsd_dir_path, :glob_path
|
4
4
|
|
5
|
+
API_PATH = "api/schemas/xml/".freeze
|
6
|
+
XSD_DEFAULT_PATH = "/api/schemas/xml/**/".freeze
|
7
|
+
|
5
8
|
def initialize(domain_arguments)
|
6
9
|
@simple_type = domain_arguments.simple_type
|
7
10
|
@assessment_type = domain_arguments.assessment_type
|
@@ -10,20 +13,24 @@ module ViewModelGateway
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def schema_version(file)
|
13
|
-
|
14
|
-
api_path_start = file.index(api_path) + api_path.length
|
16
|
+
api_path_start = file.index(API_PATH) + API_PATH.length
|
15
17
|
schema_version = file[api_path_start..].split("/").first
|
16
|
-
|
18
|
+
sap_defined_in_rdsap_dir?(file) ? "#{schema_version}/SAP" : schema_version
|
17
19
|
end
|
18
20
|
|
19
21
|
def xsd_files
|
20
|
-
files =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
files = if @xsd_dir_path.nil? || @xsd_dir_path.empty?
|
23
|
+
case @assessment_type.downcase
|
24
|
+
when "sap"
|
25
|
+
sap_xsd_files
|
26
|
+
when "rdsap"
|
27
|
+
rdsap_xsd_files
|
28
|
+
when "cepc"
|
29
|
+
cepc_xsd_files
|
30
|
+
end
|
31
|
+
else
|
32
|
+
@glob_path = "#{@dir_path}#{@xsd_dir_path}"
|
33
|
+
Dir.glob(@glob_path)
|
27
34
|
end
|
28
35
|
|
29
36
|
raise ViewModelBoundary::XsdFilesNotFound, "No xsd files were found in #{@glob_path} directory" if files.nil? || files.empty?
|
@@ -33,22 +40,22 @@ module ViewModelGateway
|
|
33
40
|
|
34
41
|
private
|
35
42
|
|
36
|
-
def
|
43
|
+
def sap_defined_in_rdsap_dir?(file)
|
37
44
|
assessment_type == "SAP" && file.end_with?("SAP-Domains.xsd")
|
38
45
|
end
|
39
46
|
|
40
47
|
def sap_xsd_files
|
41
|
-
@glob_path = "#{@dir_path +
|
48
|
+
@glob_path = "#{@dir_path + XSD_DEFAULT_PATH}*-Domains.xsd"
|
42
49
|
Dir.glob(@glob_path)
|
43
50
|
end
|
44
51
|
|
45
52
|
def rdsap_xsd_files
|
46
|
-
@glob_path = "#{@dir_path +
|
53
|
+
@glob_path = "#{@dir_path + XSD_DEFAULT_PATH}*-Domains.xsd"
|
47
54
|
Dir.glob(@glob_path)
|
48
55
|
end
|
49
56
|
|
50
57
|
def cepc_xsd_files
|
51
|
-
@glob_path = "#{@dir_path +
|
58
|
+
@glob_path = "#{@dir_path + XSD_DEFAULT_PATH}Reported-Data.xsd"
|
52
59
|
Dir.glob(@glob_path)
|
53
60
|
end
|
54
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epb_view_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MHCLG Energy Performance of Buildings
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -1655,12 +1655,16 @@ files:
|
|
1655
1655
|
- lib/presenter/export/base.rb
|
1656
1656
|
- lib/presenter/export/commercial.rb
|
1657
1657
|
- lib/presenter/export/domestic.rb
|
1658
|
+
- lib/presenter/export/statistics.rb
|
1659
|
+
- lib/presenter/rd_sap/export_configuration.rb
|
1658
1660
|
- lib/presenter/rd_sap/recommendation_report.rb
|
1659
1661
|
- lib/presenter/rd_sap/report.rb
|
1660
1662
|
- lib/presenter/rd_sap/summary.rb
|
1661
1663
|
- lib/presenter/sap/recommendation_report.rb
|
1662
1664
|
- lib/presenter/sap/report.rb
|
1663
1665
|
- lib/presenter/sap/summary.rb
|
1666
|
+
- lib/presenter/to_warehouse/base_configuration.rb
|
1667
|
+
- lib/presenter/xml/parser.rb
|
1664
1668
|
- lib/presenter/xsd.rb
|
1665
1669
|
- lib/view_model/ac_cert_wrapper.rb
|
1666
1670
|
- lib/view_model/ac_report_wrapper.rb
|