epb_view_models 1.0.10 → 1.0.14

Sign up to get free protection for your applications and to get access to all the features.
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