Class: WavefrontDisplay::Base
- Inherits:
-
Object
- Object
- WavefrontDisplay::Base
- Includes:
- WavefrontCli::Constants
- Defined in:
- lib/wavefront-cli/display/base.rb
Overview
Print human-friendly output. If a command requires a dedicated handler to format its output, define a method with the same name as that which fetches the data, in a WavefrontDisplay class, extending this one.
We provide #long_output() and #multicolumn() methods to solve standard formatting problems. To use them, define a do_() method but rather than printing the output, have it call the method.
Direct Known Subclasses
Account, Alert, ApiToken, CloudIntegration, Cluster, Dashboard, DerivedMetric, Event, ExternalLink, IngestionPolicy, Integration, MaintenanceWindow, Message, Metric, MetricsPolicy, Notificant, Proxy, Query, Role, SavedSearch, ServiceAccount, Settings, Source, Spy, Usage, UserGroup, Webhook, Write
Constant Summary
Constants included from WavefrontCli::Constants
WavefrontCli::Constants::ALL_PAGE_SIZE, WavefrontCli::Constants::DEFAULT_CONFIG, WavefrontCli::Constants::DEFAULT_OPTS, WavefrontCli::Constants::EVENT_STATE_DIR, WavefrontCli::Constants::HUMAN_TIME_FORMAT, WavefrontCli::Constants::HUMAN_TIME_FORMAT_MS, WavefrontCli::Constants::SEARCH_SPLIT
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#raw ⇒ Object
readonly
Returns the value of attribute raw.
Instance Method Summary collapse
-
#_prioritize_keys(data, keys) ⇒ Hash, Map
Move the given fields to the start of a Hash or Map.
-
#display_brief_freetext_results ⇒ Object
For freetext searches, we just display the matching fields in “brief” mode.
- #do_delete ⇒ Object
- #do_import ⇒ Object
-
#do_list ⇒ Object
The following do_ methods are default handlers called following their namesake operation in the corresponding WavefrontCli class.
- #do_list_brief ⇒ Object
- #do_list_fields ⇒ Object
- #do_queries ⇒ Object
- #do_search ⇒ Object
- #do_search_brief ⇒ Object
- #do_search_fields ⇒ Object
- #do_tag_add ⇒ Object
- #do_tag_clear ⇒ Object
- #do_tag_delete ⇒ Object
- #do_tag_pathsearch ⇒ Object
- #do_tag_set ⇒ Object
- #do_tags ⇒ Object
- #do_undelete ⇒ Object
-
#drop_fields(*keys) ⇒ Nil
Modify, in-place, the data structure to remove fields which we deem not of interest to the user.
-
#filter_data(data, fields) ⇒ Array[Hash]
Modified version of data.
-
#filter_fields_as_arr ⇒ Array
Filter fields from -O option.
- #freetext_keys ⇒ Object
-
#friendly_name ⇒ Object
return [String] the name of the thing we’re operating on, like ‘alert’ or ‘dashboard’.
-
#human_time(time, force_utc = false) ⇒ Object
Make a time human-readable.
-
#index_of_final_item ⇒ Object
Return the offset of the final item in view.
-
#initialize(raw_response, options = {}) ⇒ Base
constructor
A new instance of Base.
-
#key_width(hash = {}, pad = 2) ⇒ Integer
Give it a key-value hash, and it will return the size of the first column to use when formatting that data.
-
#long_output(fields = nil, modified_data = nil) ⇒ Object
Default display method for ‘describe’ and long-list methods.
- #multicolumn(*columns) ⇒ Object
-
#pagination_line ⇒ Object
if this is a section of a larger dataset, say so.
- #prioritize_keys(data, keys) ⇒ Object
-
#priority_keys ⇒ Object
Keys which we wish to float to the top of descriptions and long listing objects.
-
#quoted(things) ⇒ String
All “things”, strong-quoted and comma-separated.
-
#readable_time(*keys) ⇒ Object
Modify, in-place, the @data structure to make times human-readable.
-
#readable_time_arr(*keys) ⇒ Object
As for #readable_time, but when @data is an array.
-
#run(method) ⇒ Object
find the correct method to deal with the output of the user’s command.
-
#run_error(method) ⇒ Object
Display classes can provide a do_method_code() method, which handles <code> errors when running do_method().
-
#run_list ⇒ Object
Choose the correct list handler.
-
#run_search ⇒ Object
Choose the correct search handler.
- #search_display_keys ⇒ Object
-
#search_identifier_key ⇒ Object
Most objects refer to themselves by ‘id’.
-
#time_formats(str) ⇒ String
How do we format a timestamp?.
Constructor Details
#initialize(raw_response, options = {}) ⇒ Base
Returns a new instance of Base.
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/wavefront-cli/display/base.rb', line 25 def initialize(raw_response, = {}) @raw = raw_response data = if raw_response.respond_to?(:items) raw_response.items else raw_response end @data = prioritize_keys(data, priority_keys) @options = @printer_opts = {} end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
19 20 21 |
# File 'lib/wavefront-cli/display/base.rb', line 19 def data @data end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
19 20 21 |
# File 'lib/wavefront-cli/display/base.rb', line 19 def @options end |
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
19 20 21 |
# File 'lib/wavefront-cli/display/base.rb', line 19 def raw @raw end |
Instance Method Details
#_prioritize_keys(data, keys) ⇒ Hash, Map
Move the given fields to the start of a Hash or Map
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/wavefront-cli/display/base.rb', line 130 def _prioritize_keys(data, keys) keys.each.with_object(data.is_a?(Map) ? Map.new : {}) do |k, a| next unless data.key?(k) a[k] = data[k] data.delete(k) end.merge(data) rescue NoMethodError data end |
#display_brief_freetext_results ⇒ Object
For freetext searches, we just display the matching fields in “brief” mode.
263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/wavefront-cli/display/base.rb', line 263 def display_brief_freetext_results search_keys = freetext_keys data.map! do |d| mf = d.select do |_k, v| search_keys.any? { |s| v.to_s.include?(s) } end { id: d[:id], matching_fields: mf.to_h.keys } end multicolumn(:id, :matching_fields) end |
#do_delete ⇒ Object
236 237 238 |
# File 'lib/wavefront-cli/display/base.rb', line 236 def do_delete puts "Deleted #{friendly_name} '#{[:'<id>']}'." end |
#do_import ⇒ Object
231 232 233 234 |
# File 'lib/wavefront-cli/display/base.rb', line 231 def do_import puts "Imported #{friendly_name}." long_output end |
#do_list ⇒ Object
The following do_ methods are default handlers called following their namesake operation in the corresponding WavefrontCli class. They can be overriden in the inheriting class.
219 220 221 |
# File 'lib/wavefront-cli/display/base.rb', line 219 def do_list long_output end |
#do_list_brief ⇒ Object
227 228 229 |
# File 'lib/wavefront-cli/display/base.rb', line 227 def do_list_brief multicolumn(:id, :name) end |
#do_list_fields ⇒ Object
223 224 225 |
# File 'lib/wavefront-cli/display/base.rb', line 223 def do_list_fields multicolumn(*filter_fields_as_arr.map(&:to_sym)) end |
#do_queries ⇒ Object
332 333 334 335 336 337 338 |
# File 'lib/wavefront-cli/display/base.rb', line 332 def do_queries if [:brief] multicolumn(:condition) else multicolumn(:id, :condition) end end |
#do_search ⇒ Object
294 295 296 |
# File 'lib/wavefront-cli/display/base.rb', line 294 def do_search long_output end |
#do_search_brief ⇒ Object
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/wavefront-cli/display/base.rb', line 244 def do_search_brief search_keys = search_display_keys if search_keys.include?(:freetext) display_brief_freetext_results else multicolumn(*search_keys) end rescue KeyError raise WavefrontCli::Exception::ImpossibleSearch end |
#do_search_fields ⇒ Object
256 257 258 |
# File 'lib/wavefront-cli/display/base.rb', line 256 def do_search_fields do_list_fields end |
#do_tag_add ⇒ Object
298 299 300 |
# File 'lib/wavefront-cli/display/base.rb', line 298 def do_tag_add puts "Tagged #{friendly_name} '#{[:'<id>']}'." end |
#do_tag_clear ⇒ Object
306 307 308 |
# File 'lib/wavefront-cli/display/base.rb', line 306 def do_tag_clear puts "Cleared tags on #{friendly_name} '#{[:'<id>']}'." end |
#do_tag_delete ⇒ Object
302 303 304 |
# File 'lib/wavefront-cli/display/base.rb', line 302 def do_tag_delete puts "Deleted tag from #{friendly_name} '#{[:'<id>']}'." end |
#do_tag_pathsearch ⇒ Object
322 323 324 325 326 327 328 329 330 |
# File 'lib/wavefront-cli/display/base.rb', line 322 def do_tag_pathsearch if data.empty? puts 'No matches.' elsif [:long] long_output else multicolumn(:id, :name) end end |
#do_tag_set ⇒ Object
310 311 312 |
# File 'lib/wavefront-cli/display/base.rb', line 310 def do_tag_set puts "Set tags on #{friendly_name} '#{[:'<id>']}'." end |
#do_tags ⇒ Object
314 315 316 317 318 319 320 |
# File 'lib/wavefront-cli/display/base.rb', line 314 def if data.empty? puts "No tags set on #{friendly_name} '#{[:'<id>']}'." else data.sort.each { |t| puts t } end end |
#do_undelete ⇒ Object
240 241 242 |
# File 'lib/wavefront-cli/display/base.rb', line 240 def do_undelete puts "Undeleted #{friendly_name} '#{[:'<id>']}'." end |
#drop_fields(*keys) ⇒ Nil
Modify, in-place, the data structure to remove fields which we deem not of interest to the user.
346 347 348 349 350 351 352 |
# File 'lib/wavefront-cli/display/base.rb', line 346 def drop_fields(*keys) if data.is_a?(Array) data.each { |i| i.delete_if { |k, _v| keys.include?(k.to_sym) } } else data.delete_if { |k, _v| keys.include?(k.to_sym) } end end |
#filter_data(data, fields) ⇒ Array[Hash]
Returns modified version of data. Each hash will contain only the fields given in ‘fields`, in the given order.
78 79 80 81 82 |
# File 'lib/wavefront-cli/display/base.rb', line 78 def filter_data(data, fields) data.map! do |d| fields.each_with_object({}) { |f, a| a[f] = d[f] if d.key?(f) } end end |
#filter_fields_as_arr ⇒ Array
Returns filter fields from -O option.
210 211 212 |
# File 'lib/wavefront-cli/display/base.rb', line 210 def filter_fields_as_arr [:fields].split(',') end |
#freetext_keys ⇒ Object
277 278 279 |
# File 'lib/wavefront-cli/display/base.rb', line 277 def freetext_keys [:'<condition>'].map { |c| c.split(SEARCH_SPLIT, 2).last } end |
#friendly_name ⇒ Object
return [String] the name of the thing we’re operating on, like
'alert' or 'dashboard'.
203 204 205 206 |
# File 'lib/wavefront-cli/display/base.rb', line 203 def friendly_name self.class.name.split('::').last.gsub(/([a-z])([A-Z])/, '\\1 \\2') .downcase end |
#human_time(time, force_utc = false) ⇒ Object
Make a time human-readable. Automatically deals with epoch seconds and epoch milliseconds
param t [Integer, String] a timestamp. If it’s a string, it is
converted to an int.
param force_utc [Boolean] force output in UTC. Currently only
used for unit tests.
return [String] a human-readable timestamp
384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/wavefront-cli/display/base.rb', line 384 def human_time(time, force_utc = false) raise ArgumentError unless time.is_a?(Numeric) || time.is_a?(String) return 'FOREVER' if time == -1 str = time.to_s fmt, out_fmt = time_formats(str) ret = DateTime.strptime(str, fmt).to_time ret = force_utc ? ret.utc : ret.localtime ret.strftime(out_fmt) end |
#index_of_final_item ⇒ Object
Return the offset of the final item in view.
183 184 185 |
# File 'lib/wavefront-cli/display/base.rb', line 183 def index_of_final_item raw.limit.positive? ? raw.offset + raw.limit - 1 : 0 end |
#key_width(hash = {}, pad = 2) ⇒ Integer
Give it a key-value hash, and it will return the size of the first column to use when formatting that data.
194 195 196 197 198 |
# File 'lib/wavefront-cli/display/base.rb', line 194 def key_width(hash = {}, pad = 2) return 0 if hash.keys.empty? hash.keys.map(&:size).max + pad end |
#long_output(fields = nil, modified_data = nil) ⇒ Object
Default display method for ‘describe’ and long-list methods. Wraps around #_two_columns() giving you the chance to modify
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/wavefront-cli/display/base.rb', line 151 def long_output(fields = nil, modified_data = nil) if data.empty? || modified_data&.empty? puts 'No data.' else require_relative 'printer/long' puts WavefrontDisplayPrinter::Long.new(data, fields, modified_data, @printer_opts) pagination_line end end |
#multicolumn(*columns) ⇒ Object
162 163 164 165 166 |
# File 'lib/wavefront-cli/display/base.rb', line 162 def multicolumn(*columns) require_relative 'printer/terse' puts WavefrontDisplayPrinter::Terse.new(data, columns) pagination_line end |
#pagination_line ⇒ Object
if this is a section of a larger dataset, say so
170 171 172 173 174 175 176 177 178 179 |
# File 'lib/wavefront-cli/display/base.rb', line 170 def pagination_line return unless raw.respond_to?(:moreItems) && raw.moreItems == true puts format('List shows items %<first>d to %<last>d. ' \ 'Use -o and -L for more.', first: raw.offset, last: index_of_final_item) rescue StandardError puts 'List shows paginated output. Use -o and -L for more.' end |
#prioritize_keys(data, keys) ⇒ Object
119 120 121 122 123 |
# File 'lib/wavefront-cli/display/base.rb', line 119 def prioritize_keys(data, keys) return _prioritize_keys(data, keys) unless data.is_a?(Array) data.map { |e| _prioritize_keys(e, keys) } end |
#priority_keys ⇒ Object
Keys which we wish to float to the top of descriptions and long listing objects. Subclasses may define their own.
115 116 117 |
# File 'lib/wavefront-cli/display/base.rb', line 115 def priority_keys %i[id name identifier] end |
#quoted(things) ⇒ String
Returns all “things”, strong-quoted and comma-separated.
415 416 417 |
# File 'lib/wavefront-cli/display/base.rb', line 415 def quoted(things) things.map { |item| "'#{item}'" }.join(', ') end |
#readable_time(*keys) ⇒ Object
Modify, in-place, the @data structure to make times human-readable. Automatically handles second and millisecond epoch times. Currently only operates on top-level keys.
param keys [Symbol, Array] the keys you wish to be
turned into readable times.
return [Nil]
362 363 364 |
# File 'lib/wavefront-cli/display/base.rb', line 362 def readable_time(*keys) keys.each { |k| data[k] = human_time(data[k]) if data.key?(k) } end |
#readable_time_arr(*keys) ⇒ Object
As for #readable_time, but when @data is an array. For instance in “firing” alerts
369 370 371 372 373 |
# File 'lib/wavefront-cli/display/base.rb', line 369 def readable_time_arr(*keys) data.map do |row| keys.each { |k| row[k] = human_time(row[k]) if row.key?(k) } end end |
#run(method) ⇒ Object
find the correct method to deal with the output of the user’s command.
rubocop:disable Metrics/MethodLength
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/wavefront-cli/display/base.rb', line 43 def run(method) if method == 'do_list' run_list elsif method == 'do_search' run_search elsif respond_to?(:"#{method}_brief") && ![:long] send(:"#{method}_brief") elsif respond_to?(method) send(method) else long_output end end |
#run_error(method) ⇒ Object
Display classes can provide a do_method_code() method, which handles <code> errors when running do_method(). (Code is 404 etc.)
105 106 107 108 109 110 |
# File 'lib/wavefront-cli/display/base.rb', line 105 def run_error(method) return unless respond_to?(method) send(method) exit 1 end |
#run_list ⇒ Object
Choose the correct list handler. The user can specifiy a long listing with the –long options.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/wavefront-cli/display/base.rb', line 61 def run_list if [:long] @data = filter_data(data, filter_fields_as_arr) if [:fields] do_list elsif [:fields] do_list_fields else do_list_brief end end |
#run_search ⇒ Object
Choose the correct search handler. The user can specifiy a long listing with the –long options.
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/wavefront-cli/display/base.rb', line 87 def run_search if data.empty? puts 'No matches.' elsif [:long] do_search elsif [:fields] do_search_fields else do_search_brief end end |
#search_display_keys ⇒ Object
281 282 283 284 285 |
# File 'lib/wavefront-cli/display/base.rb', line 281 def search_display_keys ([search_identifier_key] + [:'<condition>'].map do |c| c.split(SEARCH_SPLIT, 2).first.to_sym end).uniq end |
#search_identifier_key ⇒ Object
Most objects refer to themselves by ‘id’. Some, like accounts, don’t. Override here.
290 291 292 |
# File 'lib/wavefront-cli/display/base.rb', line 290 def search_identifier_key :id end |
#time_formats(str) ⇒ String
How do we format a timestamp?
401 402 403 404 405 406 407 408 409 410 |
# File 'lib/wavefront-cli/display/base.rb', line 401 def time_formats(str) case str when /^\d{13}$/ ['%Q', HUMAN_TIME_FORMAT_MS] when /^\d{10}$/ ['%s', HUMAN_TIME_FORMAT] else raise ArgumentError end end |