aio_elin 0.0.1

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.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +675 -0
  3. data/README.md +9 -0
  4. data/config.rb +39 -0
  5. data/lib/aio/base/debug.rb +30 -0
  6. data/lib/aio/base/toolkit/array.rb +24 -0
  7. data/lib/aio/base/toolkit/date.rb +46 -0
  8. data/lib/aio/base/toolkit/deep_clone.rb +10 -0
  9. data/lib/aio/base/toolkit/diff.rb +104 -0
  10. data/lib/aio/base/toolkit/excel_office.rb +421 -0
  11. data/lib/aio/base/toolkit/excel_wps.rb +437 -0
  12. data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
  13. data/lib/aio/base/toolkit/ipaddr.rb +28 -0
  14. data/lib/aio/base/toolkit/os.rb +26 -0
  15. data/lib/aio/base/toolkit/regexp.rb +32 -0
  16. data/lib/aio/base/toolkit/string.rb +28 -0
  17. data/lib/aio/base/toolkit/table.rb +441 -0
  18. data/lib/aio/base/toolkit/test_diff.rb +9 -0
  19. data/lib/aio/base/toolkit/test_excel.rb +118 -0
  20. data/lib/aio/base/toolkit/test_word.rb +58 -0
  21. data/lib/aio/base/toolkit/word_wps.rb +492 -0
  22. data/lib/aio/base/toolkit.rb +18 -0
  23. data/lib/aio/base.rb +10 -0
  24. data/lib/aio/core/device/cisco.rb +13 -0
  25. data/lib/aio/core/device/cmd_switch.rb +113 -0
  26. data/lib/aio/core/device/h3c.rb +12 -0
  27. data/lib/aio/core/device/huawei.rb +10 -0
  28. data/lib/aio/core/device/juniper.rb +10 -0
  29. data/lib/aio/core/device/maipu.rb +11 -0
  30. data/lib/aio/core/device/methods.rb +233 -0
  31. data/lib/aio/core/device/methods.rb.bak +199 -0
  32. data/lib/aio/core/device/parent_device.rb +275 -0
  33. data/lib/aio/core/device.rb +15 -0
  34. data/lib/aio/core/device_manager.rb +207 -0
  35. data/lib/aio/core/module/cmd.rb +160 -0
  36. data/lib/aio/core/module/description.rb +67 -0
  37. data/lib/aio/core/module/input_style.rb +98 -0
  38. data/lib/aio/core/module/output_style.rb +80 -0
  39. data/lib/aio/core/module/platform.rb +30 -0
  40. data/lib/aio/core/module/ranking.rb +24 -0
  41. data/lib/aio/core/module/special_style.rb +30 -0
  42. data/lib/aio/core/module/template.rb +13 -0
  43. data/lib/aio/core/module.rb +15 -0
  44. data/lib/aio/core/module_loader.rb +161 -0
  45. data/lib/aio/core/module_loader.rb.bak +148 -0
  46. data/lib/aio/core/module_manager.rb +112 -0
  47. data/lib/aio/core/module_manager.rb.bak +78 -0
  48. data/lib/aio/core/parse/file.rb +19 -0
  49. data/lib/aio/core/parse/parser.rb +91 -0
  50. data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
  51. data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
  52. data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
  53. data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
  54. data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
  55. data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
  56. data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
  57. data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
  58. data/lib/aio/core/parse/parser_machine.rb +47 -0
  59. data/lib/aio/core/parse.rb +6 -0
  60. data/lib/aio/core/text/context.rb +211 -0
  61. data/lib/aio/core/text/line_string.rb +74 -0
  62. data/lib/aio/core/text/warning.rb +179 -0
  63. data/lib/aio/core/text.rb +7 -0
  64. data/lib/aio/core/warning/description.rb +47 -0
  65. data/lib/aio/core/warning/warning_summarize.rb +232 -0
  66. data/lib/aio/core/warning.rb +6 -0
  67. data/lib/aio/core.rb +32 -0
  68. data/lib/aio/license.rb +687 -0
  69. data/lib/aio/resource/cover_picture.png +0 -0
  70. data/lib/aio/resource/line.png +0 -0
  71. data/lib/aio/resource/logo.png +0 -0
  72. data/lib/aio/ui/banner.rb +85 -0
  73. data/lib/aio/ui/readable_text.rb +75 -0
  74. data/lib/aio/ui/verbose.rb +29 -0
  75. data/lib/aio/ui/version.rb +9 -0
  76. data/lib/aio/ui.rb +138 -0
  77. data/lib/aio.rb +13 -0
  78. data/lib/modules/cmd/cisco/show_clock.rb +32 -0
  79. data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
  80. data/lib/modules/cmd/cisco/show_env.rb +71 -0
  81. data/lib/modules/cmd/cisco/show_failover.rb +39 -0
  82. data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
  83. data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
  84. data/lib/modules/cmd/cisco/show_inv.rb +43 -0
  85. data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
  86. data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
  87. data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
  88. data/lib/modules/cmd/cisco/show_memory.rb +27 -0
  89. data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
  90. data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
  91. data/lib/modules/cmd/cisco/show_version.rb +97 -0
  92. data/lib/modules/cmd/h3c/display_clock.rb +32 -0
  93. data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
  94. data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
  95. data/lib/modules/cmd/h3c/display_fan.rb +91 -0
  96. data/lib/modules/cmd/h3c/display_interface.rb +203 -0
  97. data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
  98. data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
  99. data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
  100. data/lib/modules/cmd/h3c/display_memory.rb +35 -0
  101. data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
  102. data/lib/modules/cmd/h3c/display_power.rb +90 -0
  103. data/lib/modules/cmd/h3c/display_version.rb +54 -0
  104. data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
  105. data/lib/modules/cmd/maipu/show_env.rb +34 -0
  106. data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
  107. data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
  108. data/lib/modules/cmd/maipu/show_memory.rb +31 -0
  109. data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
  110. data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
  111. data/lib/modules/cmd/maipu/show_version.rb +50 -0
  112. data/lib/modules/description/style/crc.rb +22 -0
  113. data/lib/modules/description/style/input_errors.rb +22 -0
  114. data/lib/modules/description/style/overrun.rb +22 -0
  115. data/lib/modules/description/style/proc_ratio.rb +22 -0
  116. data/lib/modules/description/style/protocol.rb +22 -0
  117. data/lib/modules/description/style/register.rb +22 -0
  118. data/lib/modules/description/style/runts.rb +22 -0
  119. data/lib/modules/description/style/template.rb +22 -0
  120. data/lib/modules/description/style/total_output_drops.rb +22 -0
  121. data/lib/modules/input/style/compare_xml.rb +89 -0
  122. data/lib/modules/input/style/console.rb +222 -0
  123. data/lib/modules/input/style/console.rb.bak +114 -0
  124. data/lib/modules/input/style/xinhua_nat.rb +70 -0
  125. data/lib/modules/output/style/boc_day.rb +223 -0
  126. data/lib/modules/output/style/cmds.rb +77 -0
  127. data/lib/modules/output/style/compare_json.rb +26 -0
  128. data/lib/modules/output/style/compare_report.rb +31 -0
  129. data/lib/modules/output/style/compare_xml.rb +86 -0
  130. data/lib/modules/output/style/excel_table_office.rb +407 -0
  131. data/lib/modules/output/style/excel_table_wps.rb +400 -0
  132. data/lib/modules/output/style/summary_report.rb +563 -0
  133. data/lib/modules/special/style/compare.rb +110 -0
  134. metadata +176 -0
@@ -0,0 +1,563 @@
1
+ #coding=utf-8
2
+
3
+ require "aio/core"
4
+
5
+ class Aio::Module::OutputStyle::SummaryReport < Aio::Module::OutputStyle
6
+ include Aio::Module
7
+ include Aio::Device
8
+ include Aio::Base::Toolkit::WordWps
9
+ include Aio::Base::Toolkit::ExcelWps
10
+ include Aio::Ui::Verbose
11
+
12
+ PlaceHolder = "###"
13
+
14
+ def initialize
15
+ super({
16
+ :author => "Elin",
17
+ :description => "输出巡检简要报告, 以WPS运行",
18
+ :file_suffix => "doc",
19
+ })
20
+ end
21
+
22
+ def generate
23
+
24
+ word = Word.new
25
+ #word.show
26
+ word.display_alerts = false
27
+ @doc = word.init_document
28
+ @text = @doc.add_text
29
+
30
+ # 创建风格
31
+ create_style
32
+
33
+ device_manager.devices.each_pair do |device_name, klass|
34
+ #puts "summary_report"
35
+ #pp device_name
36
+ #pp klass.warning_klass
37
+ end
38
+
39
+ # 附带信息
40
+ info = {
41
+ :resource_file => File.join(::BaseFile, "aio", "resource"),
42
+ :client => "中国银行湖北省分行",
43
+ :time => ::Time.now.to_s.split(' ')[0],
44
+
45
+ }
46
+
47
+ # 标号
48
+ @mark = [0, 0, 0]
49
+
50
+ # 按流程算法运行
51
+ process(info)
52
+
53
+ # 保存
54
+ word.display_alerts = true
55
+
56
+ begin
57
+ word.save(output_file.to_s)
58
+ rescue Exception => e
59
+ e.message
60
+ ensure
61
+ #word.close
62
+ end
63
+ end
64
+
65
+ # 创建风格
66
+ def create_style
67
+
68
+ # 用于目录的标题
69
+ @doc.create_style_self("Contents") do |sty|
70
+ sty.font.size = 20
71
+ sty.font.NameFarEast = "黑体"
72
+ sty.font.NameAscii = "Book Antiqua"
73
+ sty.font.NameOther = "Book Antiqua"
74
+ sty.font.bold = true
75
+ # 段落间距
76
+ sty.ParagraphFormat.Alignment = 2 # 文本右对齐
77
+ sty.ParagraphFormat.LineUnitBefore = 3 #
78
+ sty.ParagraphFormat.LineUnitAfter = 2
79
+ sty.NextParagraphStyle = "正文"
80
+ # 段落控制
81
+ sty.ParagraphFormat.WidowControl = true
82
+ sty.ParagraphFormat.KeepWithNext = true
83
+ sty.ParagraphFormat.PageBreakBefore = true
84
+ # 边框
85
+ sty.ParagraphFormat.Borders(-1).LineStyle = 0
86
+ sty.ParagraphFormat.Borders(-2).LineStyle = 0
87
+ sty.ParagraphFormat.Borders(-4).LineStyle = 0
88
+ bottom = sty.ParagraphFormat.Borders(-3)
89
+ bottom.LineStyle = 1
90
+ bottom.LineWidth = 12
91
+ bottom.Color = 0
92
+ end
93
+
94
+ # 一级标题
95
+ @doc.create_style_self("font_chapter_name1") do |sty|
96
+ sty.BaseStyle = "Contents"
97
+ sty.ParagraphFormat.OutlineLevel = 1
98
+ sty.NextParagraphStyle = "正文"
99
+ end
100
+
101
+ # 一级标题标号
102
+ @doc.create_style_self("font_chapter_num1") do |sty|
103
+ sty.BaseStyle = "Contents"
104
+ sty.font.size = 72
105
+ sty.ParagraphFormat.LineUnitBefore = 0.5
106
+ sty.ParagraphFormat.LineUnitAfter = 0.5
107
+ sty.ParagraphFormat.OutlineLevel = 1
108
+ sty.NextParagraphStyle = "font_chapter_name1"
109
+ end
110
+
111
+ # 二级标题
112
+ @doc.create_style_self("font_section_name1") do |sty|
113
+ sty.BaseStyle = "正文"
114
+ sty.font.bold = true
115
+ sty.font.size = 18
116
+ sty.ParagraphFormat.LineUnitBefore = 1
117
+ sty.ParagraphFormat.LineUnitAfter = 1
118
+ sty.ParagraphFormat.OutlineLevel = 2
119
+ sty.NextParagraphStyle = "正文"
120
+ end
121
+
122
+ # 二级标题标号
123
+ @doc.create_style_self("font_section_num1") do |sty|
124
+ sty.BaseStyle = "font_section_name1"
125
+ sty.NextParagraphStyle = "font_section_name1"
126
+ end
127
+
128
+ @doc.create_style_self("font_level3_name1") do |sty|
129
+ sty.BaseStyle = "正文"
130
+ sty.font.bold = true
131
+ sty.font.size = 18
132
+ sty.ParagraphFormat.LineUnitBefore = 1
133
+ sty.ParagraphFormat.LineUnitAfter = 1
134
+ sty.ParagraphFormat.OutlineLevel = 3
135
+ sty.NextParagraphStyle = "正文"
136
+ end
137
+
138
+ @doc.create_style_self("font_level3_num1") do |sty|
139
+ sty.BaseStyle = "font_level3_name1"
140
+ sty.NextParagraphStyle = "font_level3_name1"
141
+ end
142
+
143
+ # 要点
144
+ @doc.create_style_self("importance") do |sty|
145
+ sty.BaseStyle = "正文"
146
+ sty.font.bold = true
147
+ sty.font.size = 18
148
+ sty.ParagraphFormat.LineUnitBefore = 1
149
+ sty.ParagraphFormat.LineUnitAfter = 1
150
+ sty.NextParagraphStyle = "正文"
151
+ end
152
+ end
153
+
154
+ # 主体流程控制
155
+ def process(info)
156
+ generate_cover(info)
157
+ generate_catalog(info)
158
+ generate_introduction(info)
159
+
160
+ generate_summary(info)
161
+ generate_summarize(info)
162
+ update_catalog
163
+ end
164
+
165
+ # 创建封面
166
+ def generate_cover(info)
167
+ @text.add_head_image(File.join(info[:resource_file], "cover_picture.png"))
168
+ @text.style = "正文"
169
+ @text.entry
170
+ @text.entry
171
+ @text.entry
172
+
173
+ @text.font.size = 16
174
+ @text.center
175
+ @text.section { "数据通信网络高级巡检报告" }
176
+ @text.entry
177
+ @text.entry
178
+
179
+ client = info[:client]
180
+ time = info[:time]
181
+ @text.font.Size = 15
182
+ @text.section { "客户名称:#{client}" }
183
+ @text.section { "巡检时间:#{time}" }
184
+
185
+ @text.add_table(1,1) { |tbl| }
186
+ =begin
187
+ @text.entry
188
+ @text.entry
189
+ @text.entry
190
+
191
+ @text.left
192
+ @text.font.bold = true
193
+ @text.add_image(File.join(info[:resource_file], "logo.png"))
194
+ =end
195
+ end
196
+
197
+ # 生成目录
198
+ def generate_catalog(info)
199
+ @text.section("Contents") { "目 录" }
200
+ @doc.create_catalog
201
+ @text.page_break
202
+ end
203
+
204
+ # 生成前言
205
+ def generate_introduction(info)
206
+ @text.section("font_chapter_name1") { "前言" }
207
+ @text.section("font_section_name1") { "概述" }
208
+ @text.puts "根据#{info[:client]}的运行维护需要,公司对其网络设备进行了巡检。本文档提供了本次巡检所有设备的检查明细信息及汇总信息,针对检查中发现的设备在运行过程中存在的故障隐患和风险提出了相关建议,并对网络整体的健康程度进行了评估。"
209
+ @text.entry
210
+ @text.puts "通过本文档,您可以及时了解网络设备的健康状况,清除设备故障隐患,指导技术人员完成对网络的改造优化,提高网络的可用性,保障业务可靠运行。"
211
+
212
+ @text.section("font_section_name1") { "读者对象" }
213
+ @text.puts "本项目相关的网络运行维护主管、技术工程师、系统集成商工程师等。"
214
+
215
+ @text.page_break
216
+ @text.entry
217
+ @text.section("importance") { "尊敬的_______________________ :" }
218
+ @text.puts "感谢您选择我们的产品和服务!为了提高网络的可用性,保障网络的稳定运行,我们于#{info[:time]}对贵单位网络设备进行了巡检服务。现将本次服务的情况向您汇报如下,并请您对我们的工作给予评价。"
219
+ @text.entry
220
+ @text.puts "感谢您和您的团队在本次服务过程中给我们的配合和支持!"
221
+ @text.entry
222
+ @text.entry
223
+ @text.entry
224
+ @text.entry
225
+ @text.entry
226
+ @text.entry
227
+ @text.entry
228
+ @text.puts "本次巡检负责人:"
229
+ @text.puts "联系电话:"
230
+ @text.puts "联系邮箱:"
231
+ end
232
+
233
+ ###
234
+ #
235
+ # 巡检概要报告
236
+ #
237
+ ###
238
+ # 流程控制
239
+ def generate_summary(info)
240
+ add_title_1("巡检概要报告")
241
+ generate_summary_overview(info)
242
+ generate_summary_device_type(info)
243
+ generate_summary_warning_device_top10(info)
244
+ generate_summary_level(info)
245
+ generate_summary_problem(info)
246
+ generate_summary_major_problem(info)
247
+ end
248
+
249
+ # 概述
250
+ def generate_summary_overview(info)
251
+ add_title_2("概述")
252
+ tmp = "本次巡检共巡检设备#{device_manager.devices_number}台," +
253
+ "发现问题#{warning_summarize.total_number}个。" +
254
+ "其中严重问题#{warning_summarize.serious_number}个," +
255
+ "一般问题#{warning_summarize.ordinary_number}个。"
256
+ @text.puts tmp
257
+ end
258
+
259
+ # 巡检设备类型
260
+ def generate_summary_device_type(info)
261
+ add_title_2("巡检设备类型")
262
+ @text.puts "下图表示本次巡检各类型设备所占的比例: "
263
+
264
+ # 生成table数据目录
265
+ type_info = device_manager.device_type_classify.to_a
266
+ tbl = []
267
+ type_info.size.times do |i|
268
+ # 将Hash 变成数组后,按照indent输出
269
+ tbl << [ type_info[i][0], type_info[i][1].size.to_s ]
270
+ end
271
+
272
+ # 生成图表
273
+ @text.chart(tbl) do |chart|
274
+ chart.type = chart.class::Pie
275
+ chart.style = 251
276
+ end
277
+ end
278
+
279
+ # 发现问题数TOP20的设备
280
+ def generate_summary_warning_device_top10(info)
281
+ add_title_2("发现问题数TOP10的设备")
282
+ @text.puts "本次巡检发现问题数排名前10的设备,如下图所示: "
283
+
284
+ tbl = [["", "serious", "ordinary", "compare"]]
285
+
286
+ type_warning_info = warning_summarize.device_warning_sort
287
+ n = 0
288
+ type_warning_info.each do |dev|
289
+ n += 1
290
+ next unless dev[1].total_number > 0
291
+ break if n > 10
292
+ tbl << [ dev[0],
293
+ dev[1].serious_number,
294
+ dev[1].ordinary_number,
295
+ dev[1].compare_number ]
296
+ end
297
+
298
+ @text.chart(tbl) do |chart|
299
+ chart.type = chart.class::ColumnStacked
300
+ chart.style = 251
301
+ chart.series_name = false
302
+ chart.category_name = false
303
+ chart.value = false
304
+ chart.axes_unit(1)
305
+ end
306
+ end
307
+
308
+ # 按问题级别展现
309
+ def generate_summary_level(info)
310
+ add_title_2("按问题级别展现")
311
+ @text.puts "本次巡检发现的问题级别分布情况,如下图所示: "
312
+ tbl = []
313
+ if warning_summarize.has_serious?
314
+ tbl << ["serious", warning_summarize.serious_number]
315
+ end
316
+
317
+ if warning_summarize.has_ordinary?
318
+ tbl << ["ordinary", warning_summarize.ordinary_number]
319
+ end
320
+
321
+ if warning_summarize.has_compare?
322
+ tbl << ["compare", warning_summarize.compare_number]
323
+ end
324
+
325
+ @text.chart(tbl) do |chart|
326
+ chart.type = chart.class::Pie
327
+ chart.style = 251
328
+ end
329
+
330
+ #------
331
+ @text.entry
332
+ @text.puts "1、本次巡检发现的严重问题数最多的5台设备,如下图所示:"
333
+ tbl = warning_summarize.device_serious_sort
334
+ # 只保留5个
335
+ n = 0
336
+ tbl.delete_if { |x| n += 1 ;n > 5 }
337
+ tbl.insert(0, ["", "数量"])
338
+ @text.chart(tbl) do |chart|
339
+ chart.type = chart.class::ColumnClustered
340
+ chart.style = 251
341
+ chart.series_name = false
342
+ chart.category_name = false
343
+ chart.value = false
344
+ chart.axes_unit(1)
345
+ end
346
+
347
+ #------
348
+ @text.entry
349
+ @text.puts "2、本次巡检发现的一般问题数最多的5台设备,如下图所示:"
350
+ tbl = warning_summarize.device_ordinary_sort
351
+ # 只保留5个
352
+ n = 0
353
+ tbl.delete_if { |x| n += 1 ;n > 5 }
354
+ tbl.insert(0, ["", "数量"])
355
+ @text.chart(tbl) do |chart|
356
+ chart.type = chart.class::ColumnClustered
357
+ chart.style = 251
358
+ chart.series_name = false
359
+ chart.category_name = false
360
+ chart.value = false
361
+ chart.axes_unit(1)
362
+ end
363
+ end
364
+
365
+ # 按问题发生频率展现
366
+ def generate_summary_problem(info)
367
+ add_title_2("按问题发生频率展现")
368
+ @text.puts "本次巡检发现的发生频率最多的5类问题,如下图所示:"
369
+ tbl = warning_summarize.problem_frequency
370
+ n = 0
371
+ tbl.delete_if { |x| n += 1 ;n > 5 }
372
+ tbl.insert(0, ["", "数量"])
373
+ @text.chart(tbl) do |chart|
374
+ chart.type = chart.class::BarClustered
375
+ chart.style = 251
376
+ chart.series_name = false
377
+ chart.category_name = false
378
+ chart.value = false
379
+ chart.axes_unit(1)
380
+ end
381
+ end
382
+
383
+ # 主要问题分析及说明
384
+ def generate_summary_major_problem(info)
385
+ add_title_2("主要问题分析及说明")
386
+ @text.puts "本章节将详细介绍巡检过程中发生的所有严重问题,及发生频率最高的3类一般和提示问题。"
387
+
388
+ #------
389
+ warning_summarize.summary[:serious].each_pair do |cs, dev_info|
390
+ desc_klass = warning_summarize.get_desc(cs)
391
+ add_title_3(desc_klass.title)
392
+ level(:serious)
393
+ @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台,明细如下:"
394
+ add_device_table(dev_info)
395
+ end
396
+
397
+ #------
398
+ warning_summarize.summary[:ordinary].each_pair do |cs, dev_info|
399
+ desc_klass = warning_summarize.get_desc(cs)
400
+ add_title_3(desc_klass.title)
401
+ level(:ordinary)
402
+ @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台,明细如下:"
403
+ add_device_table(dev_info)
404
+ end
405
+
406
+ end
407
+
408
+ # 打印级别
409
+ def level(sym)
410
+ res = ""
411
+ case sym
412
+ when :serious
413
+ res = "级别: 严重"
414
+ when :ordinary
415
+ res = "级别: 一般"
416
+ end
417
+
418
+ @text.style = "importance"
419
+ @text.size = 12
420
+ @text.puts res
421
+ end
422
+
423
+ # 添加按照设备标明的表格
424
+ def add_device_table(dev_info)
425
+ tbl = [ ["序号", "名称", "型号", "IP"] ]
426
+ n = 1
427
+ dev_info.each_pair do |name, klass_info|
428
+ klass = klass_info[:klass]
429
+ tbl << [n, name,
430
+ klass.device_info[:device_model],
431
+ klass.get_manager_ip ]
432
+ n += 1
433
+ end
434
+ @text.size = 10
435
+ @text.add_table_by_value(tbl) do |table|
436
+ table.center
437
+ table.border_line
438
+ table.set_columns_width(1, 44)
439
+ table.set_columns_width(2, 143)
440
+ table.set_columns_width(3, 143)
441
+ end
442
+ end
443
+
444
+
445
+ # 总结流程控制
446
+ def generate_summarize(info)
447
+ @text.page_break
448
+ generate_machine_room(info)
449
+ generate_inspection(info)
450
+ generate_offer(info)
451
+ generate_appraise(info)
452
+ end
453
+
454
+ # 机房环境检查结果
455
+ def generate_machine_room(info)
456
+ add_title_2("机房环境检查结果")
457
+ @text.add_table(1,1) do |tbl|
458
+ tbl.height = 100
459
+ tbl.border_line
460
+ end
461
+
462
+ end
463
+
464
+ # 巡检结论
465
+ def generate_inspection(info)
466
+ add_title_2("巡检结论")
467
+ @text.add_table(1,1) do |tbl|
468
+ tbl.height = 100
469
+ tbl.border_line
470
+ end
471
+ end
472
+
473
+ # 运行维护建议
474
+ def generate_offer(info)
475
+ add_title_2("运行维护建议")
476
+ @text.add_table(1,1) do |tbl|
477
+ tbl.height = 100
478
+ tbl.border_line
479
+ end
480
+ end
481
+
482
+ # 您对本次巡检情况的评价
483
+ def generate_appraise(info)
484
+ add_title_2("您对本次巡检情况的评价")
485
+ @text.add_table(1,1) do |tbl|
486
+ tbl.height = 100
487
+ tbl.border_line
488
+ end
489
+ end
490
+
491
+ private
492
+ ###
493
+ #
494
+ # 本地方法
495
+ #
496
+ ###
497
+ # 更新目录
498
+ def update_catalog
499
+ @doc.update_catalog
500
+ end
501
+
502
+ # 1级标题
503
+ def add_title_1(str)
504
+ @mark[0] += 1
505
+ @mark[1] = 0
506
+ @mark[2] = 0
507
+ mk = @mark[0].to_s
508
+ @text.style = "font_chapter_name1"
509
+ @text.print join(mk, str)
510
+ modify_num(mk, "font_chapter_num1")
511
+ @text.entry
512
+ end
513
+
514
+ # 2级标题
515
+ def add_title_2(str)
516
+ @mark[1] += 1
517
+ @mark[2] = 0
518
+ mk = [@mark[0], @mark[1]].join(".")
519
+ @text.style = "font_section_name1"
520
+ @text.print join(mk, str)
521
+ modify_num(mk, "font_section_num1")
522
+ @text.entry
523
+ end
524
+
525
+ # 3级标题
526
+ def add_title_3(str)
527
+ @mark[2] += 1
528
+ mk = [@mark[0], @mark[1], @mark[2]].join(".")
529
+ @text.style = "font_level3_name1"
530
+ @text.print join(mk, str)
531
+ modify_num(mk, "font_level3_num1")
532
+ @text.entry
533
+ end
534
+
535
+ # 合并,以空格分开
536
+ def join(*arg)
537
+ arg.join(" ")
538
+ end
539
+
540
+ # 修改标题数字
541
+ def modify_num(num, sty)
542
+ @doc.home_key
543
+ @doc.move_right(num.size, 1)
544
+ @text.now.Style = @doc.doc_work.Styles(sty)
545
+ #@text.now.ParagraphFormat.LineUnitBefore = 0.1
546
+ @doc.end_key
547
+ end
548
+
549
+ # 添加占位符
550
+ def add_holder(str)
551
+ PlaceHolder + " " + str
552
+ end
553
+
554
+ def replace_holder(str, style)
555
+ @text.replace(PlaceHolder, str.to_s, style)
556
+ end
557
+
558
+ # 警告信息汇总类
559
+ def warning_summarize
560
+ device_manager.warning_summarize
561
+ end
562
+
563
+ end
@@ -0,0 +1,110 @@
1
+ #coding=utf-8
2
+
3
+ require "aio/core"
4
+
5
+ class Aio::Module::SpecialStyle::Compare < Aio::Module::SpecialStyle
6
+ include Aio::Module
7
+
8
+ include Aio::Ui::Verbose
9
+
10
+ # 用于传递已经分析好的现有的device
11
+ attr_accessor :device_manager
12
+
13
+ # 用于传递由XML,Json生成并已经解析的Hash值
14
+ attr_accessor :input_benchmark
15
+
16
+ def initialize
17
+ super({
18
+ :author => "Elin",
19
+ :description => "此模块用于解析两个Hash值的不同点,并发出警告",
20
+ })
21
+ end
22
+
23
+ def parse
24
+ # 将device_manager 中的按照{device_name => useful} 形式重新编排
25
+ # cmds_useful为深度克隆信息,对本体无影响
26
+ device_warning = {}
27
+ total = device_manager.devices_number
28
+ print_good "总共 #{total} 台设备进行比较"
29
+
30
+ device_manager.each_devices_with_index do |device_name, device_klass, i|
31
+
32
+ device_warning[device_name] = Aio::Base::Toolkit::DeepClone.clone(device_klass.cmds_useful)
33
+ # 进度条
34
+ progress_bar(total, i+1, device_name)
35
+
36
+ end
37
+
38
+ clear_line
39
+ clear_other_info(device_warning, input_benchmark)
40
+ delete(device_warning, input_benchmark)
41
+ end
42
+
43
+ # 只留下要比较的两个数据有共同命令的交集,其他的命令就丢弃
44
+ # 因为即使是保留了,产生的也是大量的垃圾信息
45
+ def clear_other_info(device_warning, input_benchmark)
46
+ device_arr = {}
47
+ input_arr = {}
48
+
49
+ # 获得命令信息
50
+ device_warning.each_pair { |k, v| device_arr[k] = v.keys }
51
+ input_benchmark.each_pair { |k, v| input_arr[k] = v.keys }
52
+
53
+ # 删除 device_warning 中多余的命令信息
54
+ device_warning.each_pair do |name, hash|
55
+ hash.delete_if do |k, v|
56
+ next true unless input_arr.has_key?(name)
57
+ input_arr[name].include?(k) ? false : true
58
+ end
59
+ end
60
+
61
+ # 删除 input_benchmark 中多余的命令信息
62
+ input_benchmark.each_pair do |name, hash|
63
+ hash.delete_if do |k, v|
64
+ next true unless device_arr.has_key?(name)
65
+ device_arr[name].include?(k) ? false : true
66
+ end
67
+ end
68
+ end
69
+
70
+ def delete(cm1, cm2)
71
+ cm1.delete_if do |key, val|
72
+
73
+ # 当末端是Hash时,迭代循环
74
+ if val.class == Hash
75
+ # 保证无论是Symbol 还是 String 都能互换
76
+ unless cm2.has_key?(key)
77
+ cm2_val = cm2[key.to_sym] if key.kind_of? String
78
+ cm2_val = cm2[key.to_s] if key.kind_of? Symbol
79
+ next if cm2_val.nil?
80
+ else
81
+ cm2_val = cm2[key]
82
+ end
83
+ res = delete(cm1[key], cm2_val)
84
+ # 当有内容时,说明存在差异,则保留
85
+ res.empty? ? true : false
86
+ else
87
+
88
+ # 当末端不是Hash时,判断是否相等
89
+ unless cm2.has_key?(key)
90
+ cm2_val = cm2[key.to_sym] if key.kind_of? String
91
+ cm2_val = cm2[key.to_s] if key.kind_of? Symbol
92
+ next if cm2_val.nil?
93
+ else
94
+ cm2_val = cm2[key]
95
+ end
96
+ #cm1[key].eql?(cm2_val)
97
+ # 当配置中有信息时,那么只有当大于配置中的区间波动才会被记录
98
+ # 当有Pass值的时候,直接Pass
99
+ # 只有是数值才可以
100
+ compare = Aio::Config::Warning::Compare
101
+ if compare.has_key?(key)
102
+ compare[key] == "pass" ? true : (cm1[key].to_i < cm2_val.to_i + compare[key])
103
+ else
104
+ cm1[key].eql?(cm2_val)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ end