Module: Termclock

Defined in:
lib/termclock.rb,
lib/termclock/main.rb,
lib/termclock/hex2rgb.rb,
lib/termclock/version.rb,
lib/termclock/system_info.rb,
lib/termclock/parse_characters.rb

Defined Under Namespace

Modules: ParseCharacters

Constant Summary collapse

COLOURTERM =
ENV.key?('COLORTERM')
CLEAR =
COLOURTERM ? "\e[H\e[2J\e[3J" : "\e[H"
NEWLINE =
?\n.freeze
SPACE =
?\s.freeze
TAB =
?\t.freeze
VERSION =
"0.1.6"
@@cpu_usage =
0
@@cpu_usage_t =
Thread.new { }.join
@@current_net_usage =
''
@@current_net_usage_t =
Thread.new { }.join

Class Method Summary collapse

Class Method Details

.hex2rgb(hex) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/termclock/hex2rgb.rb', line 2

def self.hex2rgb(hex)
	colour = hex.dup.to_s
	colour.strip!
	colour.downcase!
	colour[0] = ''.freeze if colour[0] == ?#.freeze

	# out of range
	oor = colour.scan(/[^a-f0-9]/)

	unless oor.empty?
		invalids = colour.chars.map { |x|
			oor.include?(x) ? "\e[1;31m#{x}\e[0m" : x
		}.join

		puts "Hex Colour ##{invalids} is Out of Range"
		raise ArgumentError
	end

	clen = colour.length
	if clen == 3
		colour.chars.map { |x| x.<<(x).to_i(16) }
	elsif clen == 6
		colour.chars.each_slice(2).map { |x| x.join.to_i(16) }
	else
		sli = clen > 6 ? 'too long'.freeze : clen < 3 ? 'too short'.freeze : 'invalid'.freeze
		raise ArgumentError, "Invalid Hex Colour ##{colour} (length #{sli})"
	end
end

.start(colour1, colour2, colour3, colour4, textcolour1 = nil, textcolour2 = nil, sleep: 0.1, bold: false, print_info: true, print_message: true, print_date: true) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/termclock/main.rb', line 2

def self.start(colour1, colour2, colour3, colour4,
	textcolour1 = nil, textcolour2 = nil,
	sleep: 0.1,
	bold: false,
	print_info: true, print_message: true,
	print_date: true
	)

	generate = proc do |start, stop, n = 5|
		r_op = r_val = nil
		ary = []

		if start > stop
			r_op, r_val = :-, start.-(stop).fdiv(n - 1)
		elsif start < stop
			r_op, r_val = :+, stop.-(start).fdiv(n - 1)
		end

		_r = r_op ? start.send(r_op, r_val * -1) : start
		n.times {
			_r = _r.send(r_op, r_val) if r_op
			ary << _r.clamp(0, 255).to_i
		}

		ary
	end

	gc_compact, gc_compacted = GC.respond_to?(:compact), Time.now.to_i + 7200
	print "\e[H\e[2J\e[3J" unless COLOURTERM

	r1, g1, b1 = *colour1
	r2, g2, b2 = *colour2
	r3, g3, b3 = *colour3
	r4, g4, b4 = *colour4

	# colour1 -> colour3
	rs1 = generate.(r1, r3)
	gs1 = generate.(g1, g3)
	bs1 = generate.(b1, b3)

	# colour2 -> colour4
	rs2 = generate.(r2, r4)
	gs2 = generate.(g2, g4)
	bs2 = generate.(b2, b4)

	# All Gradient Colours
	colours = [rs1, gs1, bs1].transpose.zip([rs2, gs2, bs2].transpose)
	colours.unshift(colours[0])
	colours.push(colours[-1])

	# Text colours
	tc1 = textcolour1 ? hex2rgb(textcolour1) : hex2rgb('5555ff')
	tc2 = textcolour2 ? hex2rgb(textcolour2) : hex2rgb('3ce3b5')

	cpu_usage = 0
	cpu_usage_t = Thread.new { }

	current_net_usage = ''
	current_net_usage_t = Thread.new { }

	message_time = Time.now.to_i - 5
	message_counter = -1
	message = ''
	message_final = ''
	message_temp = ''
	caret = "\u2588"

	date, info = '', ''

	get_message = proc {
		case Time.now.hour
		when 5...12
			"\u{1F304} Good Morning..."
		when 12...16
			"\u26C5 Good Afternoon..."
		when 16...18
			"\u{1F307} Good Evening..."
		when 18...20
			"\u{1F31F} Good Evening..."
		when 20...24
			"\u{1F303} Good Night..."
		else
			"\u{2728} Good Night..."
		end
	}

	while true
		time_now = Time.now
		height, width = *STDOUT.winsize

		if time_now.to_f./(0.5).to_i.even?
			splitter = ?:.freeze
			_caret = caret
		else
			splitter = ?$.freeze
			_caret = ''
		end

		if print_message
			message_counter += 1
			message_align = width - message_counter % width + message.length / 2 - 4
			if (width - message_counter % width <= message.length)
				message.replace(message[1..-1])
				message_align = width - message_counter % width + 4
			else
				message.clear if width - message_counter % width == width
				message_temp = get_message.call

				if message_temp != message
					message << message_temp[message.length..message.length  + 1]
				end
			end

			message_final = message.rjust(message_align).+(_caret).gradient(tc1, tc2, exclude_spaces: true, bold: bold)
		end

		if print_info
			info = system_info(width, tc1, tc2, bold)
		end

		if print_date
			date = time_now.strftime('%a, %d %B %Y').center(width)
				.gradient(tc1, tc2, bold: bold)
		end

		time = time_now.strftime('%H %M %S %2N').split.join(splitter)
		art = Termclock::ParseCharacters.display(time).lines

		art_aligned = art.each_with_index do |x, i|
			chomped = x.chomp(''.freeze).+(NEWLINE)
			gr = chomped.gradient(*colours[i], bold: bold)
			x.replace(SPACE.*(width./(2.0).-(chomped.length / 2.0).abs.to_i + 1) + gr)
		end.join

		vertical_gap = "\e[#{height./(2.0).-(art.length / 2.0).to_i + 1}H"

		print "#{CLEAR}#{info}#{vertical_gap}#{art_aligned}\n#{date}\n\n#{message_final}"

		if gc_compact && time_now.to_i > gc_compacted
			GC.compact
			gc_compacted = time_now.to_i + 7200
		end

		sleep(sleep)
	end
end

.system_info(width, tc1, tc2, bold) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/termclock/system_info.rb', line 9

def system_info(width, tc1, tc2, bold)
	unless @@cpu_usage_t.alive?
		@@cpu_usage_t = Thread.new { @@cpu_usage = LS::CPU.usage(0.25) }
	end

	unless @@current_net_usage_t.alive?
		@@current_net_usage_t = Thread.new do
			_m = LS::Net.current_usage(0.25)

			_dl = LS::PrettifyBytes.convert_short_binary(_m[:received], precision: 0)
			_ul = LS::PrettifyBytes.convert_short_binary(_m[:transmitted], precision: 0)

			@@current_net_usage = "\u{1F4CA} Curr. DL/UL: #{sprintf "%-7s", _dl} | #{sprintf "%7s", _ul}"
		end
	end

	cpu = "\u{1F9E0} CPU: #{sprintf "%5s", @@cpu_usage}% (#{LS::CPU.count_online} / #{LS::CPU.count})"

	battery = if LS::Battery.present?
		stat = LS::Battery.stat
		emoji = LS::Battery.charging? ? "\u{1F4A1}" : "\u{1F50B}"
		plug = LS::Battery.charging? ? "\u{1F50C} " : ''.freeze
		"#{emoji} Battery: #{stat[:charge].to_i}% (#{plug}#{stat[:status]})"
	else
		''.freeze
	end

	user = "\u{1F481} User: #{LS::User.get_current_user.capitalize}"
	hostname = "\u{1F4BB} Hostname: #{LS::OS.hostname}"

	_m = LS::Net.total_bytes
	ip = "\u{1F30F} IP Addr: #{LS::Net.ipv4_private}"

	net_usage = "\u{1F4C8} Totl. DL/UL: #{sprintf "%-7s", LS::PrettifyBytes.convert_short_binary(_m[:received], precision: 0)}"\
	" | #{sprintf "%7s", LS::PrettifyBytes.convert_short_binary(_m[:transmitted], precision: 0)}"

	_m = LS::Memory.stat
	memory = "\u{1F3B0} Mem: #{LS::PrettifyBytes.convert_short_binary(_m[:used].to_i * 1024)}"\
	" / #{LS::PrettifyBytes.convert_short_binary(_m[:total].to_i * 1024)}"\
	" (#{_m[:percent_used].to_i}%)"

	_m = LS::Swap.stat
	swap = "\u{1F300} Swap: #{LS::PrettifyBytes.convert_short_binary(_m[:used].to_i * 1024)}"\
	" / #{LS::PrettifyBytes.convert_short_binary(_m[:total].to_i * 1024)}"\
	" (#{_m[:percent_used].to_i}%)"

	_m = LS::Filesystem.stat
	fs = "\u{1F4BD} FS: #{LS::PrettifyBytes.convert_short_binary(_m[:used].to_i)}"\
	" / #{LS::PrettifyBytes.convert_short_binary(_m[:total].to_i)}"\
	" (#{_m[:used].to_i*(100).fdiv(_m[:total].to_i).round(2)}%)"

	process = "\u{1F9EE} Process: #{LS::Process.count}"

	max_l = [hostname, process, ip, battery, @@current_net_usage, net_usage].map(&:length).max + 4

	<<~EOF.gradient(tc1, tc2, exclude_spaces: true, bold: bold)
		\s#{user}#{SPACE.*(width.-(user.length + max_l).abs)}#{hostname}
		\s#{cpu}#{SPACE.*(width.-(cpu.length + max_l).abs)}#{battery}
		\s#{memory}#{SPACE.*(width.-(memory.length + max_l).abs)}#{ip}
		\s#{swap}#{SPACE.*(width.-(swap.length + max_l).abs)}#{@@current_net_usage}
		\s#{fs}#{SPACE.*(width.-(fs.length + max_l).abs)}#{net_usage}
	EOF
end