panda-motd 0.0.7 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ace8e728251d18f1ee3043f9de8cff80fe631a30cd8af80aac5026020f80f7ae
4
- data.tar.gz: 26c7447624bac833cb204c98f7ff528ae4538f91a6c3490fbf5a9feeaf4a385d
3
+ metadata.gz: e96416cb34d16f565eb89916c6156cd2e293a04f0ba8ffeede5df5e92d73acc3
4
+ data.tar.gz: abc7ad56a5b1a0d90dcbf4cd4a7f948bed78232357f2ac7fc352f7388d136d0f
5
5
  SHA512:
6
- metadata.gz: beb33befc6b4372211a23725531d59797d03c50dd45d4f28bef6741b6391d9dc28f8b987ec531ff68c52d374f8c533938357c4e87f3c6b9749f7c124cb35a48c
7
- data.tar.gz: 8bf66b63249f303dc161ea32d9b37d6d1da7d0c4416d848eff3b11984c61f88decd3ee119503790beaf0cb294a64e74d91fbb36b14130fcb2454167ac5696e58
6
+ metadata.gz: 452c47ad204b5dfb044abf370c0f0643c24bcfea8565ca5329ad487717cd116fd1d4c88378985be2d14a4759269cbe363d7b86bfdba31425e673d9f5be4aecef
7
+ data.tar.gz: a2209d1666149ac3222c005b79af5d3edb129a79dec9bc12c8c07c906ad26aa384dfc0222378ce3aa4c8da097cb425c33e4de76b67d92a0c2677ead2ba493366
@@ -17,7 +17,7 @@ class ASCIITextArt
17
17
  begin
18
18
  @art = Artii::Base.new font: @config['font']
19
19
  @results = @art.asciify(@text)
20
- @results = @results.send(@config['color'].to_sym) if @config['color']
20
+ @results = @results.colorize(@config['color'].to_sym) if @config['color']
21
21
  rescue Errno::EISDIR # Artii doesn't handle invalid font names very well
22
22
  @errors << ComponentError.new(self, 'Invalid font name')
23
23
  end
@@ -80,42 +80,30 @@ class Filesystems
80
80
  private
81
81
 
82
82
  def percentage_color(percentage)
83
- return :green if (0..75).cover? percentage
84
- return :yellow if (75..95).cover? percentage
85
- return :red if (95..100).cover? percentage
86
- return :white
87
- end
88
-
89
- def find_header_id_by_text(header_array, text)
90
- return header_array.each_index.select { |i| header_array[i].downcase.include? text }.first
83
+ case percentage
84
+ when 0..75 then :green
85
+ when 76..95 then :yellow
86
+ when 96..100 then :red
87
+ else :white
88
+ end
91
89
  end
92
90
 
93
91
  def parse_filesystem_usage(filesystems)
94
- command_result = `BLOCKSIZE=1024 df`.split("\n")
95
- header = command_result[0].split
96
- entries = command_result[1..command_result.count]
97
-
98
- name_index = find_header_id_by_text(header, 'filesystem')
99
- size_index = find_header_id_by_text(header, 'blocks')
100
- used_index = find_header_id_by_text(header, 'used')
101
- avail_index = find_header_id_by_text(header, 'avail')
102
-
103
- results = filesystems.map do |filesystem, name|
104
- matching_entry = entries.find { |e| e.split[name_index] == filesystem }
105
-
106
- if matching_entry
107
- {
108
- pretty_name: name,
109
- filesystem_name: matching_entry.split[name_index],
110
- size: matching_entry.split[size_index].to_i * 1024,
111
- used: matching_entry.split[used_index].to_i * 1024,
112
- avail: matching_entry.split[avail_index].to_i * 1024
113
- }
114
- else
115
- "#{filesystem} was not found"
116
- end
92
+ entries = `BLOCKSIZE=1024 df --output=source,size,used,avail`.lines
93
+ .drop(1)
94
+
95
+ filesystems.map do |filesystem, pretty_name|
96
+ matching_entry = entries.map(&:split).find { |e| e.first == filesystem }
97
+ next "#{filesystem} was not found" unless matching_entry
98
+
99
+ filesystem_name, size, used, avail = matching_entry
100
+ {
101
+ pretty_name: pretty_name,
102
+ filesystem_name: filesystem_name,
103
+ size: size.to_i * 1024,
104
+ used: used.to_i * 1024,
105
+ avail: avail.to_i * 1024
106
+ }
117
107
  end
118
-
119
- return results
120
108
  end
121
109
  end
@@ -16,55 +16,55 @@ class LastLogin
16
16
  end
17
17
 
18
18
  def to_s
19
- result = "Last Login:\n"
20
-
21
- @results.each do |user, logins|
22
- result += " #{user}:\n"
23
- location_string_size = logins.map { |l| l[:location].length }.max
24
- logins.each do |login|
25
- location_part = login[:location].ljust(location_string_size, ' ')
26
- start_part = login[:time_start].strftime('%m/%d/%Y %I:%M%p')
27
-
28
- end_part = if login[:time_end].is_a? String # still logged in text
29
- login[:time_end].green
30
- else
31
- "#{((login[:time_end] - login[:time_start]) * 24 * 60).to_i} minutes"
32
- end
33
-
34
- result += " from #{location_part} at #{start_part} (#{end_part})\n"
35
- end
36
- result += ' no logins found for user.' if logins.empty?
37
- end
38
-
39
- return result
19
+ <<~LAST
20
+ Last Login:
21
+ #{@results.map do |user, logins|
22
+ logins_part =
23
+ if logins.empty?
24
+ ' no logins found for user.'
25
+ else
26
+ longest_location_size = logins.map { |l| l[:location].length }.max
27
+ logins.map do |login|
28
+ location_part = login[:location].ljust(longest_location_size, ' ')
29
+ start_part = login[:time_start].strftime('%m/%d/%Y %I:%M%p')
30
+ end_part = if login[:time_end].is_a? String # still logged in text
31
+ login[:time_end].green
32
+ else
33
+ "#{((login[:time_end] - login[:time_start]) * 24 * 60).to_i} minutes"
34
+ end
35
+ " from #{location_part} at #{start_part} (#{end_part})"
36
+ end.join("\n")
37
+ end
38
+ <<~USER
39
+ #{user}:
40
+ #{logins_part}
41
+ USER
42
+ end.join("\n")}
43
+ LAST
40
44
  end
41
45
 
42
46
  private
43
47
 
44
48
  def parse_last_logins(users)
45
- all_logins = {}
46
- users.each_with_index do |(username, num_logins), i|
47
- user_logins = []
48
- cmd_result = `last --time-format=iso #{username}`
49
- cmd_result.split("\n").each do |entry|
50
- next unless entry.start_with? username
51
- data = entry.split(/(?:\s{2,})|(?:\s-\s)/)
52
-
53
- time_end = data[4] == 'still logged in' ? data[4] : DateTime.parse(data[4])
54
-
55
- user_logins << {
56
- username: username,
57
- location: data[2],
58
- time_start: DateTime.parse(data[3]),
59
- time_end: time_end
60
- }
61
-
62
- break if user_logins.count >= num_logins
63
- end
49
+ users.map do |(username, num_logins)|
50
+ user_logins =
51
+ `last --time-format=iso #{username}`
52
+ .lines
53
+ .select { |entry| entry.start_with?(username) }
54
+ .take(num_logins)
55
+ .map do |entry|
56
+ data = entry.chomp.split(/(?:\s{2,})|(?:\s-\s)/)
57
+ time_end = data[4] == 'still logged in' ? data[4] : DateTime.parse(data[4])
64
58
 
65
- all_logins[username.to_sym] = user_logins
66
- end
59
+ {
60
+ username: username,
61
+ location: data[2],
62
+ time_start: DateTime.parse(data[3]),
63
+ time_end: time_end
64
+ }
65
+ end
67
66
 
68
- return all_logins
67
+ [username.to_sym, user_logins]
68
+ end.to_h
69
69
  end
70
70
  end
@@ -17,52 +17,38 @@ class ServiceStatus
17
17
  end
18
18
 
19
19
  def to_s
20
- if @results.any?
21
- result = "Services:\n"
22
- longest_name_size = @results.keys.map { |k| k.to_s.length }.max + 1 # add 1 for the ':' at the end
23
- @results.each_with_index do |(name, status), i|
24
- name_part = (name.to_s + ':').ljust(longest_name_size, ' ')
25
- status_part = status.to_s.send(service_colors[status])
26
- result += " #{name_part} #{status_part}"
27
- result += "\n" unless i == @results.count - 1 # don't print newline for last entry
28
- end
29
-
30
- return result
31
- else
32
- return "Services:\n No matching services found."
33
- end
20
+ return "Services:\n No matching services found." unless @results.any?
21
+ longest_name_size = @results.keys.map { |k| k.to_s.length }.max
22
+ <<~HEREDOC
23
+ Services:
24
+ #{@results.map do |(name, status)|
25
+ name_part = name.to_s.ljust(longest_name_size, ' ') + ':'
26
+ status_part = status.to_s.colorize(service_colors[status.to_sym])
27
+ " #{name_part} #{status_part}"
28
+ end.join("\n")}
29
+ HEREDOC
34
30
  end
35
31
 
36
32
  private
37
33
 
38
- def parse_services(services)
39
- results = {}
40
-
41
- cmd_result = `systemctl | grep '\.service'`.delete("^\u{0000}-\u{007F}")
42
-
43
- if cmd_result.empty?
44
- @errors << ComponentError.new(self, 'Unable to parse systemctl output')
45
- end
46
-
47
- cmd_result.split("\n").each do |line|
48
- parsed_name = line.split[0].gsub('.service', '')
49
- parsed_status = line.split[3]
50
-
51
- matching_service = services.find { |service, _name| service == parsed_name }
52
-
53
- if matching_service
54
- results[parsed_name.to_sym] = parsed_status.to_sym
55
- end
56
- end
34
+ def parse_service(service)
35
+ cmd_result = `systemctl is-active #{service[0]}`.strip
36
+ @errors << ComponentError.new(self, 'Unable to parse systemctl output') unless valid_responses.include? cmd_result
37
+ return cmd_result
38
+ end
57
39
 
58
- return results
40
+ def parse_services(services)
41
+ services.map { |service| [service[1].to_sym, parse_service(service).to_sym] }.to_h
59
42
  end
60
43
 
61
44
  def service_colors
62
45
  return {
63
- running: :green,
64
- exited: :white,
65
- failed: :red
46
+ active: :green,
47
+ inactive: :red
66
48
  }
67
49
  end
50
+
51
+ def valid_responses
52
+ return ['active', 'inactive']
53
+ end
68
54
  end
@@ -16,25 +16,19 @@ class SSLCertificates
16
16
  end
17
17
 
18
18
  def to_s
19
- result = "SSL Certificates:\n"
20
19
  longest_name_size = @results.map { |r| r[0].length }.max
20
+ <<~HEREDOC
21
+ SSL Certificates:
22
+ #{@results.map do |cert|
23
+ return " #{cert}" if cert.is_a? String # print the not found message
21
24
 
22
- @results.each_with_index do |cert, i|
23
- if cert.is_a? String # print the not found message
24
- result += " #{cert}"
25
- else
26
- name_portion = " #{cert[0]}".ljust(longest_name_size + 6, ' ')
27
-
28
- status = cert_status(cert[1])
29
-
30
- date_portion = "#{cert_status_strings[status]} ".send(cert_status_colors[status]) + cert[1].strftime('%e %b %Y %H:%M:%S%p').to_s
31
- result += name_portion + date_portion
32
- end
33
-
34
- result += "\n" unless i == @results.count - 1 # don't print newline for last entry
35
- end
36
-
37
- return result
25
+ name_portion = cert[0].ljust(longest_name_size + 6, ' ')
26
+ status = cert_status(cert[1])
27
+ status = cert_status_strings[status].to_s.colorize(cert_status_colors[status])
28
+ date_portion = cert[1].strftime('%e %b %Y %H:%M:%S%p')
29
+ " #{name_portion} #{status} #{date_portion}"
30
+ end.join("\n")}
31
+ HEREDOC
38
32
  end
39
33
 
40
34
  private
@@ -61,10 +55,13 @@ class SSLCertificates
61
55
  end
62
56
 
63
57
  def cert_status(expiry_date)
64
- status = :valid
65
- status = :expiring if (DateTime.now...DateTime.now + 30).cover? expiry_date # ... range excludes end
66
- status = :expired if DateTime.now >= expiry_date
67
- return status
58
+ if (DateTime.now...DateTime.now + 30).cover? expiry_date # ... range excludes end
59
+ :expiring
60
+ elsif DateTime.now >= expiry_date
61
+ :expired
62
+ else
63
+ :valid
64
+ end
68
65
  end
69
66
 
70
67
  def cert_status_colors
@@ -12,8 +12,7 @@ class Uptime
12
12
  end
13
13
 
14
14
  def process
15
- sysinfo = SysInfo.new
16
- uptime = sysinfo.uptime
15
+ uptime = SysInfo.new.uptime
17
16
 
18
17
  @days = (uptime / 24).floor
19
18
  @hours = (uptime - @days * 24).floor
@@ -21,10 +20,15 @@ class Uptime
21
20
  end
22
21
 
23
22
  def to_s
24
- result = ''
25
- result += "#{@days} day#{'s' if @days != 1}, " unless @days.zero?
26
- result += "#{@hours} hour#{'s' if @hours != 1}, " unless @hours.zero? && @days.zero?
27
- result += "#{@minutes} minute#{'s' if @minutes != 1}"
28
- return "#{@config['prefix'] || 'up'} #{result}"
23
+ return "#{@config['prefix'] || 'up'} #{format_uptime}"
24
+ end
25
+
26
+ private
27
+
28
+ def format_uptime
29
+ [@days, @hours, @minutes].zip(%w[day hour minute])
30
+ .reject { |n, _word| n.zero? }
31
+ .map { |n, word| "#{n} #{word}#{'s' if n != 1}" }
32
+ .join(', ')
29
33
  end
30
34
  end
@@ -1,4 +1,4 @@
1
1
  class PandaMOTD
2
2
  #:nodoc:
3
- VERSION ||= '0.0.7'.freeze
3
+ VERSION ||= '0.0.8'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panda-motd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taylor Thurlow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-16 00:00:00.000000000 Z
11
+ date: 2018-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: artii
@@ -210,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
210
210
  requirements:
211
211
  - - ">="
212
212
  - !ruby/object:Gem::Version
213
- version: '2.2'
213
+ version: '2.3'
214
214
  required_rubygems_version: !ruby/object:Gem::Requirement
215
215
  requirements:
216
216
  - - ">="