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
Alert, ApiToken, CloudIntegration, Dashboard, DerivedMetric, Event, ExternalLink, Integration, MaintenanceWindow, Message, Metric, Notificant, Proxy, Query, SavedSearch, Settings, Source, User, 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::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_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.
-
#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.
-
#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
-
#time_formats(str) ⇒ String
How do we format a timestamp?.
Constructor Details
#initialize(raw_response, options = {}) ⇒ Base
Returns a new instance of Base.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/wavefront-cli/display/base.rb', line 23 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) = end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
17 18 19 |
# File 'lib/wavefront-cli/display/base.rb', line 17 def data @data end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
17 18 19 |
# File 'lib/wavefront-cli/display/base.rb', line 17 def end |
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
17 18 19 |
# File 'lib/wavefront-cli/display/base.rb', line 17 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
115 116 117 118 119 120 121 122 123 |
# File 'lib/wavefront-cli/display/base.rb', line 115 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.
238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/wavefront-cli/display/base.rb', line 238 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
213 214 215 |
# File 'lib/wavefront-cli/display/base.rb', line 213 def do_delete puts "Deleted #{friendly_name} '#{options[:'<id>']}'." end |
#do_import ⇒ Object
208 209 210 211 |
# File 'lib/wavefront-cli/display/base.rb', line 208 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.
196 197 198 |
# File 'lib/wavefront-cli/display/base.rb', line 196 def do_list long_output end |
#do_list_brief ⇒ Object
204 205 206 |
# File 'lib/wavefront-cli/display/base.rb', line 204 def do_list_brief multicolumn(:id, :name) end |
#do_list_fields ⇒ Object
200 201 202 |
# File 'lib/wavefront-cli/display/base.rb', line 200 def do_list_fields multicolumn(*filter_fields_as_arr.map(&:to_sym)) end |
#do_queries ⇒ Object
304 305 306 307 308 309 310 |
# File 'lib/wavefront-cli/display/base.rb', line 304 def do_queries if [:brief] multicolumn(:condition) else multicolumn(:id, :condition) end end |
#do_search ⇒ Object
262 263 264 265 266 267 268 |
# File 'lib/wavefront-cli/display/base.rb', line 262 def do_search if data.empty? puts 'No matches.' else long_output end end |
#do_search_brief ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/wavefront-cli/display/base.rb', line 221 def do_search_brief search_keys = search_display_keys if data.empty? puts 'No matches.' elsif search_keys.include?(:freetext) display_brief_freetext_results else multicolumn(*search_keys) end rescue KeyError raise WavefrontCli::Exception::ImpossibleSearch end |
#do_tag_add ⇒ Object
270 271 272 |
# File 'lib/wavefront-cli/display/base.rb', line 270 def do_tag_add puts "Tagged #{friendly_name} '#{options[:'<id>']}'." end |
#do_tag_clear ⇒ Object
278 279 280 |
# File 'lib/wavefront-cli/display/base.rb', line 278 def do_tag_clear puts "Cleared tags on #{friendly_name} '#{options[:'<id>']}'." end |
#do_tag_delete ⇒ Object
274 275 276 |
# File 'lib/wavefront-cli/display/base.rb', line 274 def do_tag_delete puts "Deleted tag from #{friendly_name} '#{options[:'<id>']}'." end |
#do_tag_pathsearch ⇒ Object
294 295 296 297 298 299 300 301 302 |
# File 'lib/wavefront-cli/display/base.rb', line 294 def do_tag_pathsearch if data.empty? puts 'No matches.' elsif [:long] long_output else multicolumn(:id, :name) end end |
#do_tag_set ⇒ Object
282 283 284 |
# File 'lib/wavefront-cli/display/base.rb', line 282 def do_tag_set puts "Set tags on #{friendly_name} '#{options[:'<id>']}'." end |
#do_tags ⇒ Object
286 287 288 289 290 291 292 |
# File 'lib/wavefront-cli/display/base.rb', line 286 def if data.empty? puts "No tags set on #{friendly_name} '#{options[:'<id>']}'." else data.sort.each { |t| puts t } end end |
#do_undelete ⇒ Object
217 218 219 |
# File 'lib/wavefront-cli/display/base.rb', line 217 def do_undelete puts "Undeleted #{friendly_name} '#{options[:'<id>']}'." end |
#drop_fields(*keys) ⇒ Nil
Modify, in-place, the data structure to remove fields which we deem not of interest to the user.
318 319 320 321 322 323 324 |
# File 'lib/wavefront-cli/display/base.rb', line 318 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.
73 74 75 76 77 |
# File 'lib/wavefront-cli/display/base.rb', line 73 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.
187 188 189 |
# File 'lib/wavefront-cli/display/base.rb', line 187 def filter_fields_as_arr [:fields].split(',') end |
#freetext_keys ⇒ Object
252 253 254 |
# File 'lib/wavefront-cli/display/base.rb', line 252 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'.
180 181 182 183 |
# File 'lib/wavefront-cli/display/base.rb', line 180 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
356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/wavefront-cli/display/base.rb', line 356 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) # rubocop:disable Style/DateTime ret = DateTime.strptime(str, fmt).to_time # rubocop:enable Style/DateTime ret = force_utc ? ret.utc : ret.localtime ret.strftime(out_fmt) 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.
172 173 174 175 |
# File 'lib/wavefront-cli/display/base.rb', line 172 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
135 136 137 138 139 140 141 142 143 |
# File 'lib/wavefront-cli/display/base.rb', line 135 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) pagination_line end end |
#multicolumn(*columns) ⇒ Object
145 146 147 148 149 |
# File 'lib/wavefront-cli/display/base.rb', line 145 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
rubocop:disable Metrics/AbcSize
154 155 156 157 158 159 160 161 162 |
# File 'lib/wavefront-cli/display/base.rb', line 154 def pagination_line return unless raw.respond_to?(:moreItems) && raw.moreItems == true enditem = raw.limit.positive? ? raw.offset + raw.limit - 1 : 0 puts format('List shows items %d to %d. Use -o and -L for more.', raw.offset, enditem) rescue StandardError puts 'List shows paginated output. Use -o and -L for more.' end |
#prioritize_keys(data, keys) ⇒ Object
105 106 107 108 |
# File 'lib/wavefront-cli/display/base.rb', line 105 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.
101 102 103 |
# File 'lib/wavefront-cli/display/base.rb', line 101 def priority_keys i[id name] 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]
334 335 336 |
# File 'lib/wavefront-cli/display/base.rb', line 334 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
341 342 343 344 345 |
# File 'lib/wavefront-cli/display/base.rb', line 341 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.
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/wavefront-cli/display/base.rb', line 39 def run(method) if method == 'do_list' run_list elsif method == 'do_search' run_search elsif respond_to?("#{method}_brief") 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.)
92 93 94 95 96 |
# File 'lib/wavefront-cli/display/base.rb', line 92 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.
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/wavefront-cli/display/base.rb', line 56 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.
82 83 84 |
# File 'lib/wavefront-cli/display/base.rb', line 82 def run_search [:long] ? do_search : do_search_brief end |
#search_display_keys ⇒ Object
256 257 258 259 260 |
# File 'lib/wavefront-cli/display/base.rb', line 256 def search_display_keys ([:id] + [:'<condition>'].map do |c| c.split(SEARCH_SPLIT, 2).first.to_sym end).uniq end |
#time_formats(str) ⇒ String
How do we format a timestamp?
374 375 376 377 378 379 380 381 382 |
# File 'lib/wavefront-cli/display/base.rb', line 374 def time_formats(str) if str =~ /^\d{13}$/ ['%Q', HUMAN_TIME_FORMAT_MS] elsif str =~ /^\d{10}$/ ['%s', HUMAN_TIME_FORMAT] else raise ArgumentError end end |