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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70fe31a8b4317370e678562b7ce01baa5db0b8e48b8b185197c88285731a476b
4
- data.tar.gz: 73542839d5a7ac83b87698248308e46faa5397f94c8a63758ebdfd4a93f42a22
3
+ metadata.gz: ee84c9018a99e7ecc114cd9e16da64303f337d6d53ecd4f243510fdcdeeace59
4
+ data.tar.gz: f2a5ecdb96d373dfc64317ab94a626b9fab1c91b9957de9d765927fdca73f5b2
5
5
  SHA512:
6
- metadata.gz: 27154cc9e7eb4e48f595042cf2e100093647307e62fd6552f57d9e782d5926232fa67d0cb07c0f8767582fe6e123ec165db33efe62b7ca2fd73e237af87e9107
7
- data.tar.gz: 2d05b80c15f37828f1da3ac56857843e21fc33b138c9bfd8109e7a74f9defb64042155a3a84fc6343e99ffea5353cc157f5d8ef6337ac2be30de29036e1c4b94
6
+ metadata.gz: bf9fc7e313914c1b34ba94c7ea3dd9f83c6a1ae47b80669e53f01b75b1721f57fb57b356e52eeac54d58d24ba3d03e561ff6e5725f4980a42b02b74d5e971345
7
+ data.tar.gz: cc89d10482409d65e7fadc02fb7db449e2d54bab4f2d7fa8bf45dcc293883201e81d618fbfa36f24eed6c980bd1e65651f89cdda616aa3bc3a75c2d81d40b602
@@ -5,7 +5,7 @@ loader = Zeitwerk::Loader.for_gem
5
5
  loader.setup
6
6
 
7
7
  module EpbViewModels
8
- VERSION = "1.0.10"
8
+ VERSION = "1.0.14"
9
9
  end
10
10
 
11
11
  # Monkey patching to avoid using ActiveRecord::Type::Boolean.new.cast
@@ -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,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
- doc = REXML::Document.new(File.read(file))
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 xsd files in #{domain_arguments.xsd_dir_path} directory" if hash.empty?
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: "/api/schemas/xml/**/", gem_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
- api_path = "api/schemas/xml/"
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
- sap_defnied_in_rdsap_dir?(file) ? "#{schema_version}/SAP" : schema_version
18
+ sap_defined_in_rdsap_dir?(file) ? "#{schema_version}/SAP" : schema_version
17
19
  end
18
20
 
19
21
  def xsd_files
20
- files = case @assessment_type.downcase
21
- when "sap"
22
- sap_xsd_files
23
- when "rdsap"
24
- rdsap_xsd_files
25
- when "cepc"
26
- cepc_xsd_files
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 sap_defnied_in_rdsap_dir?(file)
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 + xsd_dir_path}*-Domains.xsd"
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 + xsd_dir_path}*-Domains.xsd"
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 + xsd_dir_path}Reported-Data.xsd"
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.10
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-12 00:00:00.000000000 Z
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