aio_elin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +675 -0
- data/README.md +9 -0
- data/config.rb +39 -0
- data/lib/aio/base/debug.rb +30 -0
- data/lib/aio/base/toolkit/array.rb +24 -0
- data/lib/aio/base/toolkit/date.rb +46 -0
- data/lib/aio/base/toolkit/deep_clone.rb +10 -0
- data/lib/aio/base/toolkit/diff.rb +104 -0
- data/lib/aio/base/toolkit/excel_office.rb +421 -0
- data/lib/aio/base/toolkit/excel_wps.rb +437 -0
- data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
- data/lib/aio/base/toolkit/ipaddr.rb +28 -0
- data/lib/aio/base/toolkit/os.rb +26 -0
- data/lib/aio/base/toolkit/regexp.rb +32 -0
- data/lib/aio/base/toolkit/string.rb +28 -0
- data/lib/aio/base/toolkit/table.rb +441 -0
- data/lib/aio/base/toolkit/test_diff.rb +9 -0
- data/lib/aio/base/toolkit/test_excel.rb +118 -0
- data/lib/aio/base/toolkit/test_word.rb +58 -0
- data/lib/aio/base/toolkit/word_wps.rb +492 -0
- data/lib/aio/base/toolkit.rb +18 -0
- data/lib/aio/base.rb +10 -0
- data/lib/aio/core/device/cisco.rb +13 -0
- data/lib/aio/core/device/cmd_switch.rb +113 -0
- data/lib/aio/core/device/h3c.rb +12 -0
- data/lib/aio/core/device/huawei.rb +10 -0
- data/lib/aio/core/device/juniper.rb +10 -0
- data/lib/aio/core/device/maipu.rb +11 -0
- data/lib/aio/core/device/methods.rb +233 -0
- data/lib/aio/core/device/methods.rb.bak +199 -0
- data/lib/aio/core/device/parent_device.rb +275 -0
- data/lib/aio/core/device.rb +15 -0
- data/lib/aio/core/device_manager.rb +207 -0
- data/lib/aio/core/module/cmd.rb +160 -0
- data/lib/aio/core/module/description.rb +67 -0
- data/lib/aio/core/module/input_style.rb +98 -0
- data/lib/aio/core/module/output_style.rb +80 -0
- data/lib/aio/core/module/platform.rb +30 -0
- data/lib/aio/core/module/ranking.rb +24 -0
- data/lib/aio/core/module/special_style.rb +30 -0
- data/lib/aio/core/module/template.rb +13 -0
- data/lib/aio/core/module.rb +15 -0
- data/lib/aio/core/module_loader.rb +161 -0
- data/lib/aio/core/module_loader.rb.bak +148 -0
- data/lib/aio/core/module_manager.rb +112 -0
- data/lib/aio/core/module_manager.rb.bak +78 -0
- data/lib/aio/core/parse/file.rb +19 -0
- data/lib/aio/core/parse/parser.rb +91 -0
- data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
- data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
- data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
- data/lib/aio/core/parse/parser_machine.rb +47 -0
- data/lib/aio/core/parse.rb +6 -0
- data/lib/aio/core/text/context.rb +211 -0
- data/lib/aio/core/text/line_string.rb +74 -0
- data/lib/aio/core/text/warning.rb +179 -0
- data/lib/aio/core/text.rb +7 -0
- data/lib/aio/core/warning/description.rb +47 -0
- data/lib/aio/core/warning/warning_summarize.rb +232 -0
- data/lib/aio/core/warning.rb +6 -0
- data/lib/aio/core.rb +32 -0
- data/lib/aio/license.rb +687 -0
- data/lib/aio/resource/cover_picture.png +0 -0
- data/lib/aio/resource/line.png +0 -0
- data/lib/aio/resource/logo.png +0 -0
- data/lib/aio/ui/banner.rb +85 -0
- data/lib/aio/ui/readable_text.rb +75 -0
- data/lib/aio/ui/verbose.rb +29 -0
- data/lib/aio/ui/version.rb +9 -0
- data/lib/aio/ui.rb +138 -0
- data/lib/aio.rb +13 -0
- data/lib/modules/cmd/cisco/show_clock.rb +32 -0
- data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
- data/lib/modules/cmd/cisco/show_env.rb +71 -0
- data/lib/modules/cmd/cisco/show_failover.rb +39 -0
- data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
- data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
- data/lib/modules/cmd/cisco/show_inv.rb +43 -0
- data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
- data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
- data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
- data/lib/modules/cmd/cisco/show_memory.rb +27 -0
- data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
- data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
- data/lib/modules/cmd/cisco/show_version.rb +97 -0
- data/lib/modules/cmd/h3c/display_clock.rb +32 -0
- data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
- data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
- data/lib/modules/cmd/h3c/display_fan.rb +91 -0
- data/lib/modules/cmd/h3c/display_interface.rb +203 -0
- data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
- data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
- data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
- data/lib/modules/cmd/h3c/display_memory.rb +35 -0
- data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
- data/lib/modules/cmd/h3c/display_power.rb +90 -0
- data/lib/modules/cmd/h3c/display_version.rb +54 -0
- data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
- data/lib/modules/cmd/maipu/show_env.rb +34 -0
- data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
- data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
- data/lib/modules/cmd/maipu/show_memory.rb +31 -0
- data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
- data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
- data/lib/modules/cmd/maipu/show_version.rb +50 -0
- data/lib/modules/description/style/crc.rb +22 -0
- data/lib/modules/description/style/input_errors.rb +22 -0
- data/lib/modules/description/style/overrun.rb +22 -0
- data/lib/modules/description/style/proc_ratio.rb +22 -0
- data/lib/modules/description/style/protocol.rb +22 -0
- data/lib/modules/description/style/register.rb +22 -0
- data/lib/modules/description/style/runts.rb +22 -0
- data/lib/modules/description/style/template.rb +22 -0
- data/lib/modules/description/style/total_output_drops.rb +22 -0
- data/lib/modules/input/style/compare_xml.rb +89 -0
- data/lib/modules/input/style/console.rb +222 -0
- data/lib/modules/input/style/console.rb.bak +114 -0
- data/lib/modules/input/style/xinhua_nat.rb +70 -0
- data/lib/modules/output/style/boc_day.rb +223 -0
- data/lib/modules/output/style/cmds.rb +77 -0
- data/lib/modules/output/style/compare_json.rb +26 -0
- data/lib/modules/output/style/compare_report.rb +31 -0
- data/lib/modules/output/style/compare_xml.rb +86 -0
- data/lib/modules/output/style/excel_table_office.rb +407 -0
- data/lib/modules/output/style/excel_table_wps.rb +400 -0
- data/lib/modules/output/style/summary_report.rb +563 -0
- data/lib/modules/special/style/compare.rb +110 -0
- metadata +176 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module Aio::Base::Toolkit::IPAddr
|
2
|
+
class << self
|
3
|
+
|
4
|
+
# 子网掩码从点分十进制转换为数值
|
5
|
+
# 255.255.255.0 => 24
|
6
|
+
def mask_dotted_to_i(mask)
|
7
|
+
arr = mask.split(".")
|
8
|
+
binary = ""
|
9
|
+
arr.each do |m|
|
10
|
+
binary << m.to_i.to_s(2)
|
11
|
+
end
|
12
|
+
return binary.scan(/1/).size
|
13
|
+
end
|
14
|
+
|
15
|
+
# 子网掩码从十进制到点分十进制
|
16
|
+
# 24 => 255.255.255.0
|
17
|
+
def mask_i_to_dotted(int)
|
18
|
+
int = int.to_i
|
19
|
+
arr = [nil, nil, nil, nil]
|
20
|
+
binary = (2 ** int - 1) << (32 - int)
|
21
|
+
4.times do |t|
|
22
|
+
arr[3-t] = (binary & 255).to_s
|
23
|
+
binary = binary >> 8
|
24
|
+
end
|
25
|
+
return arr.join(".")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Aio::Base::Toolkit
|
2
|
+
module OS
|
3
|
+
class << self
|
4
|
+
def os_family
|
5
|
+
case RUBY_PLATFORM
|
6
|
+
when /ix/i, /ux/i, /gnu/i,
|
7
|
+
/sysv/i, /solaris/i,
|
8
|
+
/sunos/i, /bsd/i
|
9
|
+
"unix"
|
10
|
+
when /win/i, /ming/i
|
11
|
+
"windows"
|
12
|
+
else
|
13
|
+
"other"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def windows?
|
18
|
+
self.os_family == "windows" ? true : false
|
19
|
+
end
|
20
|
+
|
21
|
+
def linux?
|
22
|
+
self.os_family == "unix" ? true : false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Aio::Base::Toolkit
|
2
|
+
module Regexp
|
3
|
+
class << self
|
4
|
+
def to_reg(cmd)
|
5
|
+
res = cmd.gsub(' ', '([^\s]*)\s+')
|
6
|
+
res.insert(0, '^')
|
7
|
+
res.insert(-1, '([^\s]*)$')
|
8
|
+
return ::Regexp.new(res)
|
9
|
+
end
|
10
|
+
|
11
|
+
def blank
|
12
|
+
return /^[\t]*$/
|
13
|
+
end
|
14
|
+
|
15
|
+
# 产生一个安全的正则表达式
|
16
|
+
def safe(reg)
|
17
|
+
res = reg.to_s.gsub(' ', '\s+')
|
18
|
+
return ::Regexp.new(res)
|
19
|
+
end
|
20
|
+
|
21
|
+
# 将一个数组的正则表达式合并成为一个正则表达式
|
22
|
+
def merge(arr_regs)
|
23
|
+
str_arr = []
|
24
|
+
arr_regs.each {|x| str_arr << x.to_s}
|
25
|
+
new_reg = str_arr.join("|").gsub("?-mix:", "")
|
26
|
+
new_reg = ::Regexp.new(new_reg)
|
27
|
+
return new_reg
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Aio::Base::Toolkit::String
|
2
|
+
class << self
|
3
|
+
|
4
|
+
# 终极解决方案
|
5
|
+
# 遇到了 invalid byte sequence in UTF-8 (ArgumentError) 问题
|
6
|
+
# 解决办法参考 https://stackoverflow.com/questions/29877310/invalid-byte-sequence-in-utf-8-argumenterror
|
7
|
+
def safe(str)
|
8
|
+
case Aio::Base::Toolkit::OS.os_family
|
9
|
+
when "unix"
|
10
|
+
if ! str.valid_encoding?
|
11
|
+
str = str.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
|
12
|
+
end
|
13
|
+
when "windows"
|
14
|
+
#str = str.force_encoding("UTF-8")
|
15
|
+
str = str.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
|
16
|
+
end
|
17
|
+
return str
|
18
|
+
end
|
19
|
+
|
20
|
+
# 改写成安全的Windows书写方式
|
21
|
+
def safe_path(path)
|
22
|
+
if Aio::Base::Toolkit::OS.windows?
|
23
|
+
path.gsub!("/", "\\")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,441 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'ipaddr'
|
3
|
+
|
4
|
+
module Aio::Base::Toolkit
|
5
|
+
|
6
|
+
###
|
7
|
+
#
|
8
|
+
# Prints text in a tablized format. Pretty lame at the moment, but
|
9
|
+
# whatever.
|
10
|
+
# 经过修改增加了对中文字体格式的支持 by Elin
|
11
|
+
#
|
12
|
+
###
|
13
|
+
class Table
|
14
|
+
|
15
|
+
#
|
16
|
+
# Initializes a text table instance using the supplied properties. The
|
17
|
+
# Table class supports the following hash attributes:
|
18
|
+
#
|
19
|
+
# Header
|
20
|
+
#
|
21
|
+
# The string to display as a heading above the table. If none is
|
22
|
+
# specified, no header will be displayed.
|
23
|
+
#
|
24
|
+
# HeaderIndent
|
25
|
+
#
|
26
|
+
# The amount of space to indent the header. The default is zero.
|
27
|
+
#
|
28
|
+
# Columns
|
29
|
+
#
|
30
|
+
# The array of columns that will exist within the table.
|
31
|
+
#
|
32
|
+
# Rows
|
33
|
+
#
|
34
|
+
# The array of rows that will exist.
|
35
|
+
#
|
36
|
+
# Width
|
37
|
+
#
|
38
|
+
# The maximum width of the table in characters.
|
39
|
+
#
|
40
|
+
# Indent
|
41
|
+
#
|
42
|
+
# The number of characters to indent the table.
|
43
|
+
#
|
44
|
+
# CellPad
|
45
|
+
#
|
46
|
+
# The number of characters to put between each horizontal cell.
|
47
|
+
#
|
48
|
+
# Prefix
|
49
|
+
#
|
50
|
+
# The text to prefix before the table.
|
51
|
+
#
|
52
|
+
# Postfix
|
53
|
+
#
|
54
|
+
# The text to affix to the end of the table.
|
55
|
+
#
|
56
|
+
# Sortindex
|
57
|
+
#
|
58
|
+
# The column to sort the table on, -1 disables sorting.
|
59
|
+
#
|
60
|
+
def initialize(opts = {})
|
61
|
+
self.header = opts['Header']
|
62
|
+
self.headeri = opts['HeaderIndent'] || 0
|
63
|
+
self.columns = opts['Columns'] || []
|
64
|
+
# updated below if we got a "Rows" option
|
65
|
+
self.rows = []
|
66
|
+
|
67
|
+
self.width = opts['Width'] || 80
|
68
|
+
self.indent = opts['Indent'] || 0
|
69
|
+
self.cellpad = opts['CellPad'] || 2
|
70
|
+
self.prefix = opts['Prefix'] || ''
|
71
|
+
self.postfix = opts['Postfix'] || ''
|
72
|
+
self.colprops = []
|
73
|
+
self.scterm = /#{opts['SearchTerm']}/mi if opts['SearchTerm']
|
74
|
+
|
75
|
+
self.sort_index = opts['SortIndex'] || 0
|
76
|
+
self.sort_order = opts['SortOrder'] || :forward
|
77
|
+
|
78
|
+
# Default column properties
|
79
|
+
self.columns.length.times { |idx|
|
80
|
+
self.colprops[idx] = {}
|
81
|
+
self.colprops[idx]['MaxWidth'] = self.columns[idx].length + ch_num(self.columns[idx])
|
82
|
+
}
|
83
|
+
|
84
|
+
# ensure all our internal state gets updated with the given rows by
|
85
|
+
# using add_row instead of just adding them to self.rows. See #3825.
|
86
|
+
opts['Rows'].each { |row| add_row(row) } if opts['Rows']
|
87
|
+
|
88
|
+
# Merge in options
|
89
|
+
if (opts['ColProps'])
|
90
|
+
opts['ColProps'].each_key { |col|
|
91
|
+
idx = self.columns.index(col)
|
92
|
+
|
93
|
+
if (idx)
|
94
|
+
self.colprops[idx].merge!(opts['ColProps'][col])
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Converts table contents to a string.
|
103
|
+
#
|
104
|
+
def to_s
|
105
|
+
str = prefix.dup
|
106
|
+
str << header_to_s || ''
|
107
|
+
str << columns_to_s || ''
|
108
|
+
str << hr_to_s || ''
|
109
|
+
|
110
|
+
sort_rows
|
111
|
+
rows.each { |row|
|
112
|
+
if (is_hr(row))
|
113
|
+
str << hr_to_s
|
114
|
+
else
|
115
|
+
str << row_to_s(row) if row_visible(row)
|
116
|
+
end
|
117
|
+
}
|
118
|
+
|
119
|
+
str << postfix
|
120
|
+
|
121
|
+
return str
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Converts table contents to a csv
|
126
|
+
#
|
127
|
+
def to_csv
|
128
|
+
str = ''
|
129
|
+
str << ( columns.join(",") + "\n" )
|
130
|
+
rows.each { |row|
|
131
|
+
next if is_hr(row) || !row_visible(row)
|
132
|
+
str << ( row.map{|x|
|
133
|
+
x = x.to_s
|
134
|
+
x.gsub(/[\r\n]/, ' ').gsub(/\s+/, ' ').gsub('"', '""')
|
135
|
+
}.map{|x| "\"#{x}\"" }.join(",") + "\n" )
|
136
|
+
}
|
137
|
+
str
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
#
|
142
|
+
# Returns the header string.
|
143
|
+
#
|
144
|
+
def header_to_s # :nodoc:
|
145
|
+
if (header)
|
146
|
+
pad = " " * headeri
|
147
|
+
|
148
|
+
return pad + header + "\n" + pad + "=" * (header.length + ch_num(header)) + "\n\n"
|
149
|
+
end
|
150
|
+
|
151
|
+
return ''
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Prints the contents of the table.
|
156
|
+
#
|
157
|
+
def print
|
158
|
+
puts to_s
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Adds a row using the supplied fields.
|
163
|
+
#
|
164
|
+
def <<(fields)
|
165
|
+
add_row(fields)
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# Adds a row with the supplied fields.
|
170
|
+
#
|
171
|
+
def add_row(fields = [])
|
172
|
+
if fields.length != self.columns.length
|
173
|
+
raise RuntimeError, 'Invalid number of columns!'
|
174
|
+
end
|
175
|
+
fields.each_with_index { |field, idx|
|
176
|
+
# Remove whitespace and ensure String format
|
177
|
+
field = field.to_s.strip
|
178
|
+
field_length = field.to_s.length + ch_num(field.to_s)
|
179
|
+
if (colprops[idx]['MaxWidth'] < field_length)
|
180
|
+
old = colprops[idx]['MaxWidth']
|
181
|
+
colprops[idx]['MaxWidth'] = field_length
|
182
|
+
end
|
183
|
+
}
|
184
|
+
|
185
|
+
rows << fields
|
186
|
+
end
|
187
|
+
|
188
|
+
def ip_cmp(a, b)
|
189
|
+
begin
|
190
|
+
a = ::IPAddr.new(a.to_s)
|
191
|
+
b = ::IPAddr.new(b.to_s)
|
192
|
+
return 1 if a.ipv6? && b.ipv4?
|
193
|
+
return -1 if a.ipv4? && b.ipv6?
|
194
|
+
a <=> b
|
195
|
+
rescue ::IPAddr::Error
|
196
|
+
nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
#
|
201
|
+
# Sorts the rows based on the supplied index of sub-arrays
|
202
|
+
# If the supplied index is an IPv4 address, handle it differently, but
|
203
|
+
# avoid actually resolving domain names.
|
204
|
+
#
|
205
|
+
def sort_rows(index = sort_index, order = sort_order)
|
206
|
+
return if index == -1
|
207
|
+
return unless rows
|
208
|
+
rows.sort! do |a,b|
|
209
|
+
if a[index].nil?
|
210
|
+
cmp = -1
|
211
|
+
elsif b[index].nil?
|
212
|
+
cmp = 1
|
213
|
+
elsif a[index] =~ /^[0-9]+$/ and b[index] =~ /^[0-9]+$/
|
214
|
+
cmp = a[index].to_i <=> b[index].to_i
|
215
|
+
elsif (cmp = ip_cmp(a[index], b[index])) != nil
|
216
|
+
else
|
217
|
+
cmp = a[index] <=> b[index] # assumes otherwise comparable.
|
218
|
+
end
|
219
|
+
cmp ||= 0
|
220
|
+
order == :forward ? cmp : -cmp
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
#
|
225
|
+
# Adds a horizontal line.
|
226
|
+
#
|
227
|
+
def add_hr
|
228
|
+
rows << '__hr__'
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
# Returns new sub-table with headers and rows maching column names submitted
|
233
|
+
#
|
234
|
+
#
|
235
|
+
# Flips table 90 degrees left
|
236
|
+
#
|
237
|
+
def drop_left
|
238
|
+
tbl = self.class.new(
|
239
|
+
'Columns' => Array.new(self.rows.count+1,' '),
|
240
|
+
'Header' => self.header,
|
241
|
+
'Indent' => self.indent)
|
242
|
+
(self.columns.count+1).times do |ti|
|
243
|
+
row = self.rows.map {|r| r[ti]}.unshift(self.columns[ti]).flatten
|
244
|
+
# insert our col|row break. kind of hackish
|
245
|
+
row[1] = "| #{row[1]}" unless row.all? {|e| e.nil? || e.empty?}
|
246
|
+
tbl << row
|
247
|
+
end
|
248
|
+
return tbl
|
249
|
+
end
|
250
|
+
|
251
|
+
def valid_ip?(value)
|
252
|
+
begin
|
253
|
+
::IPAddr.new value
|
254
|
+
true
|
255
|
+
rescue ::IPAddr::Error
|
256
|
+
false
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
#
|
261
|
+
# Build table from CSV dump
|
262
|
+
#
|
263
|
+
def self.new_from_csv(csv)
|
264
|
+
# Read in or keep data, get CSV or die
|
265
|
+
if csv.is_a?(String)
|
266
|
+
csv = File.file?(csv) ? CSV.read(csv) : CSV.parse(csv)
|
267
|
+
end
|
268
|
+
# Adjust for skew
|
269
|
+
if csv.first == ["Keys", "Values"]
|
270
|
+
csv.shift # drop marker
|
271
|
+
cols = []
|
272
|
+
rows = []
|
273
|
+
csv.each do |row|
|
274
|
+
cols << row.shift
|
275
|
+
rows << row
|
276
|
+
end
|
277
|
+
tbl = self.new('Columns' => cols)
|
278
|
+
rows.in_groups_of(cols.count) {|r| tbl << r.flatten}
|
279
|
+
else
|
280
|
+
tbl = self.new('Columns' => csv.shift)
|
281
|
+
while !csv.empty? do
|
282
|
+
tbl << csv.shift
|
283
|
+
end
|
284
|
+
end
|
285
|
+
return tbl
|
286
|
+
end
|
287
|
+
|
288
|
+
def [](*col_names)
|
289
|
+
tbl = self.class.new('Indent' => self.indent,
|
290
|
+
'Header' => self.header,
|
291
|
+
'Columns' => col_names)
|
292
|
+
indexes = []
|
293
|
+
|
294
|
+
col_names.each do |col_name|
|
295
|
+
index = self.columns.index(col_name)
|
296
|
+
raise RuntimeError, "Invalid column name #{col_name}" if index.nil?
|
297
|
+
indexes << index
|
298
|
+
end
|
299
|
+
|
300
|
+
self.rows.each do |old_row|
|
301
|
+
new_row = []
|
302
|
+
indexes.map {|i| new_row << old_row[i]}
|
303
|
+
tbl << new_row
|
304
|
+
end
|
305
|
+
|
306
|
+
return tbl
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
alias p print
|
311
|
+
|
312
|
+
attr_accessor :header, :headeri # :nodoc:
|
313
|
+
attr_accessor :columns, :rows, :colprops # :nodoc:
|
314
|
+
attr_accessor :width, :indent, :cellpad # :nodoc:
|
315
|
+
attr_accessor :prefix, :postfix # :nodoc:
|
316
|
+
attr_accessor :sort_index, :sort_order, :scterm # :nodoc:
|
317
|
+
|
318
|
+
protected
|
319
|
+
|
320
|
+
#
|
321
|
+
# Returns if a row should be visible or not
|
322
|
+
#
|
323
|
+
def row_visible(row)
|
324
|
+
return true if self.scterm.nil?
|
325
|
+
row_to_s(row).match(self.scterm)
|
326
|
+
end
|
327
|
+
|
328
|
+
#
|
329
|
+
# Defaults cell widths and alignments.
|
330
|
+
#
|
331
|
+
def defaults # :nodoc:
|
332
|
+
self.columns.length.times { |idx|
|
333
|
+
}
|
334
|
+
end
|
335
|
+
|
336
|
+
#
|
337
|
+
# Checks to see if the row is an hr.
|
338
|
+
#
|
339
|
+
def is_hr(row) # :nodoc:
|
340
|
+
return ((row.kind_of?(String)) && (row == '__hr__'))
|
341
|
+
end
|
342
|
+
|
343
|
+
#
|
344
|
+
# Converts the columns to a string.
|
345
|
+
#
|
346
|
+
def columns_to_s # :nodoc:
|
347
|
+
nameline = ' ' * indent
|
348
|
+
barline = nameline.dup
|
349
|
+
last_col = nil
|
350
|
+
last_idx = nil
|
351
|
+
columns.each_with_index { |col,idx|
|
352
|
+
if (last_col)
|
353
|
+
# This produces clean to_s output without truncation
|
354
|
+
# Preserves full string in cells for to_csv output
|
355
|
+
padding = pad(' ', last_col, last_idx)
|
356
|
+
nameline << padding
|
357
|
+
remainder = padding.length - cellpad
|
358
|
+
remainder = 0 if remainder < 0
|
359
|
+
barline << (' ' * (cellpad + remainder))
|
360
|
+
end
|
361
|
+
|
362
|
+
nameline << col
|
363
|
+
barline << ('-' * (col.length + ch_num(col)))
|
364
|
+
|
365
|
+
last_col = col
|
366
|
+
last_idx = idx
|
367
|
+
}
|
368
|
+
|
369
|
+
return "#{nameline}\n#{barline}"
|
370
|
+
end
|
371
|
+
|
372
|
+
#
|
373
|
+
# Converts an hr to a string.
|
374
|
+
#
|
375
|
+
def hr_to_s # :nodoc:
|
376
|
+
return "\n"
|
377
|
+
end
|
378
|
+
|
379
|
+
#
|
380
|
+
# Converts a row to a string.
|
381
|
+
#
|
382
|
+
def row_to_s(row) # :nodoc:
|
383
|
+
line = ' ' * indent
|
384
|
+
last_cell = nil
|
385
|
+
last_idx = nil
|
386
|
+
row.each_with_index { |cell, idx|
|
387
|
+
if (idx != 0)
|
388
|
+
line << pad(' ', last_cell.to_s, last_idx)
|
389
|
+
end
|
390
|
+
# Limit wide cells
|
391
|
+
if colprops[idx]['MaxChar']
|
392
|
+
last_cell = cell.to_s[0..colprops[idx]['MaxChar'].to_i]
|
393
|
+
line << last_cell
|
394
|
+
else
|
395
|
+
line << cell.to_s
|
396
|
+
last_cell = cell
|
397
|
+
end
|
398
|
+
last_idx = idx
|
399
|
+
}
|
400
|
+
|
401
|
+
return line + "\n"
|
402
|
+
end
|
403
|
+
|
404
|
+
#
|
405
|
+
# Pads out with the supplied character for the remainder of the space given
|
406
|
+
# some text and a column index.
|
407
|
+
#
|
408
|
+
def pad(chr, buf, colidx, use_cell_pad = true) # :nodoc:
|
409
|
+
# Ensure we pad the minimum required amount
|
410
|
+
max = colprops[colidx]['MaxChar'] || colprops[colidx]['MaxWidth']
|
411
|
+
max = colprops[colidx]['MaxWidth'] if max.to_i > colprops[colidx]['MaxWidth'].to_i
|
412
|
+
encoding = buf.encoding.name
|
413
|
+
if not ["UTF-8", "ASCII-8BIT", "US-ASCII", "GBK"].include? encoding
|
414
|
+
warn '**WARNING** In file ' << __FILE__ << '::' <<\
|
415
|
+
__method__.to_s << ': String with unsupported encoding caught!'
|
416
|
+
end
|
417
|
+
utf8_buf = buf.dup.force_encoding("UTF-8")
|
418
|
+
|
419
|
+
utf8_buf_length = utf8_buf.size + ch_num(utf8_buf)
|
420
|
+
|
421
|
+
remainder = max - utf8_buf_length
|
422
|
+
remainder = 0 if remainder < 0
|
423
|
+
val = chr * remainder
|
424
|
+
|
425
|
+
if (use_cell_pad)
|
426
|
+
val << ' ' * cellpad
|
427
|
+
end
|
428
|
+
|
429
|
+
return val
|
430
|
+
end
|
431
|
+
|
432
|
+
def ch_num(str)
|
433
|
+
s = str.dup
|
434
|
+
s.size-s.gsub(/[\u4e00-\u9fa5]/,'').size
|
435
|
+
end
|
436
|
+
|
437
|
+
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
cwd = File.expand_path(File.dirname(__FILE__))
|
2
|
+
load "#{cwd}/excel.rb"
|
3
|
+
|
4
|
+
|
5
|
+
include Aio::Base::Toolkit::Excel
|
6
|
+
|
7
|
+
excel = WorkBook.new
|
8
|
+
excel.show
|
9
|
+
worksheet = excel.add_worksheet("sheet")
|
10
|
+
=begin
|
11
|
+
worksheet.add_title("title")
|
12
|
+
row = worksheet.add_row
|
13
|
+
row << ["elin", 1]
|
14
|
+
row.height = 20
|
15
|
+
=end
|
16
|
+
|
17
|
+
worksheet.width("a", 15)
|
18
|
+
worksheet.width("b", 10)
|
19
|
+
worksheet.width("c", 15)
|
20
|
+
worksheet.width("d", 15)
|
21
|
+
worksheet.width("e", 14)
|
22
|
+
worksheet.width("f", 7)
|
23
|
+
worksheet.width("g", 12)
|
24
|
+
|
25
|
+
row = worksheet.add_row
|
26
|
+
row.merge("a", "g")
|
27
|
+
row << "湖北中行现场巡检报告"
|
28
|
+
row.set_style("a", "TitleStyle")
|
29
|
+
row = worksheet.add_row
|
30
|
+
row.merge("b", "g")
|
31
|
+
row << ["巡检命令", "1.基本信息"]
|
32
|
+
row.set_style("a", "BoldStyle")
|
33
|
+
row.set_style("b", "BoldStyle")
|
34
|
+
|
35
|
+
#========== show version
|
36
|
+
row = worksheet.add_row
|
37
|
+
row.merge("c", "d")
|
38
|
+
row.merge("f", "g")
|
39
|
+
row << ["show version", "设备名称", "A_HBWHA_COR_CS01", "设备型号", "WS-C6506-E"]
|
40
|
+
row.set_style("a", "BoldStyle")
|
41
|
+
row = worksheet.add_row
|
42
|
+
row.merge("c", "d")
|
43
|
+
row.merge("f", "g")
|
44
|
+
row << ["show version", "IP", "30.48.1.248", "FLASH(MB)", "512"]
|
45
|
+
row = worksheet.add_row
|
46
|
+
row.merge("c", "g")
|
47
|
+
row << ["show version", "运行时间", "26 weeks, 5 days, 5 hours, 44 minutes"]
|
48
|
+
row = worksheet.add_row
|
49
|
+
row << [
|
50
|
+
"show version",
|
51
|
+
"内存", "512",
|
52
|
+
"IOS版本", "12.2(33)SXI4a",
|
53
|
+
"紧急版本", "12.2(17r)SX7" ]
|
54
|
+
row = worksheet.add_row
|
55
|
+
row.merge("c", "g")
|
56
|
+
row << [
|
57
|
+
"show version",
|
58
|
+
"IOS特性集", "s72033-ipservicesk9-mz.122-33.SXI4a"]
|
59
|
+
|
60
|
+
worksheet.merge("a3","a7")
|
61
|
+
|
62
|
+
#========= show inventory
|
63
|
+
row = worksheet.add_row
|
64
|
+
row.merge("e", "g")
|
65
|
+
row << [
|
66
|
+
"show inventory", "硬件信息", "接口卡型号","序列号",
|
67
|
+
"RMA历史记录(年/月/日)"]
|
68
|
+
row.style("a", "BoldStyle")
|
69
|
+
row = worksheet.add_row
|
70
|
+
row << ["show inventory",
|
71
|
+
"机箱", "WS-C6506-E", "SAL1439URLY", "", "", ""]
|
72
|
+
row = worksheet.add_row
|
73
|
+
row << ["show inventory",
|
74
|
+
"插槽1", "WS-C6506-E", "SAL1439URLY", "", "", ""]
|
75
|
+
row = worksheet.add_row
|
76
|
+
row << ["show inventory",
|
77
|
+
"插槽2", "WS-C6506-E", "SAL1439URLY", "", "", ""]
|
78
|
+
row = worksheet.add_row
|
79
|
+
row << ["show inventory",
|
80
|
+
"插槽3", "WS-C6506-E", "SAL1439URLY", "", "", ""]
|
81
|
+
row = worksheet.add_row
|
82
|
+
row << ["show inventory",
|
83
|
+
"插槽4", "WS-C6506-E", "SAL1439URLY", "", "", ""]
|
84
|
+
worksheet.merge("a8", "a13")
|
85
|
+
#=========
|
86
|
+
row = worksheet.add_row
|
87
|
+
row.merge("b", "g")
|
88
|
+
row << ["", "2.运行状态巡检信息采集"]
|
89
|
+
row.style("b", "BoldStyle")
|
90
|
+
row = worksheet.add_row
|
91
|
+
row.merge("d", "f")
|
92
|
+
row << ["", "项目", "内容", "结果", "备注"]
|
93
|
+
row.style("b", "BoldStyle")
|
94
|
+
row.style("c", "BoldStyle")
|
95
|
+
row.style("d", "BoldStyle")
|
96
|
+
row.style("g", "BoldStyle")
|
97
|
+
#========= show process cpu
|
98
|
+
row = worksheet.add_row
|
99
|
+
row.merge("d", "f")
|
100
|
+
row << ["show process cpu", "路由状态",
|
101
|
+
"cpu利用率(%)", "five minutes: 10%", ""]
|
102
|
+
row.style("a", "BoldStyle")
|
103
|
+
row = worksheet.add_row
|
104
|
+
row.merge("d", "f")
|
105
|
+
row << ["show process mem", "路由状态",
|
106
|
+
"内存利用率(%)", "24.00", ""]
|
107
|
+
row.style("a", "BoldStyle")
|
108
|
+
row = worksheet.add_row
|
109
|
+
row.merge("d", "f")
|
110
|
+
row << ["show environment", "路由状态",
|
111
|
+
"温度", "√", ""]
|
112
|
+
row.style("a", "BoldStyle")
|
113
|
+
row = worksheet.add_row
|
114
|
+
row.merge("d", "f")
|
115
|
+
row << ["show environment", "路由状态",
|
116
|
+
"电源", "正常√ 不正常□", ""]
|
117
|
+
|
118
|
+
|