conky-config/module/Remote.lua

281 lines
6.5 KiB
Lua

local _CR = require 'CR'
local Widget = require 'Widget'
local Text = require 'Text'
local CriticalText = require 'CriticalText'
local Line = require 'Line'
local TextColumn = require 'TextColumn'
local util = require 'util'
local schema = require 'default_patterns'
local _STRING_FIND = string.find
local _STRING_MATCH = string.match
local _STRING_GMATCH = string.gmatch
local NUM_ROWS = 12
local USERNAME_FORMAT = '(%S+)%s+'
local START_TIME_FORMAT = '%S+%s+%S+%s+%S+%s+(%S+)%s+'
--construction params
local SPACING = 20
local SEPARATOR_SPACING = 17
local MODULE_Y = 285
local header = Widget.Header{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = MODULE_Y,
width = CONSTRUCTION_GLOBAL.SIDE_WIDTH,
header = 'REMOTE CONNECTIONS'
}
local FIREWALL_Y = header.bottom_y
local TUNNEL_Y = FIREWALL_Y + SEPARATOR_SPACING * 2
local SOCKS_Y = TUNNEL_Y + SPACING + SEPARATOR_SPACING * 2
local TABLE_Y = SOCKS_Y + SPACING + SEPARATOR_SPACING * 2
local TABLE_BODY_Y = TABLE_Y + SPACING + 6
local RIGHT_X = CONSTRUCTION_GLOBAL.RIGHT_X + CONSTRUCTION_GLOBAL.SIDE_WIDTH
local firewall = {
label = Widget.Text{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = FIREWALL_Y,
text = 'Firewall Status',
},
info = Widget.CriticalText{
x = RIGHT_X,
y = FIREWALL_Y,
x_align = 'right',
text_color = schema.blue,
}
}
local tunnel = {
labels = Widget.TextColumn{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = TUNNEL_Y,
spacing = SPACING,
'Tunnel Loaded',
'Tunnel Running',
},
info = Widget.TextColumn{
x = RIGHT_X,
y = TUNNEL_Y,
spacing = SPACING,
x_align = 'right',
text_color = schema.blue,
num_rows = 2,
}
}
local socks = {
labels = Widget.TextColumn{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = SOCKS_Y,
spacing = SPACING,
'Socks Loaded',
'Socks Running',
},
info = Widget.TextColumn{
x = RIGHT_X,
y = SOCKS_Y,
spacing = SPACING,
x_align = 'right',
text_color = schema.blue,
num_rows = 2,
}
}
local tbl = {
headers = {
Widget.Text{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = TABLE_Y,
text = 'Username',
text_color = schema.blue
},
Widget.Text{
x = RIGHT_X,
y = TABLE_Y,
text = 'Date / Time',
text_color = schema.blue,
x_align = 'right'
}
},
columns = {
Widget.TextColumn{
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = TABLE_BODY_Y,
spacing = SPACING,
num_rows = NUM_ROWS,
font_size = 10,
max_length = 9
},
Widget.TextColumn{
x = RIGHT_X,
y = TABLE_BODY_Y,
spacing = SPACING,
num_rows = NUM_ROWS,
font_size = 10,
x_align = 'right',
}
}
}
local separators = {
Widget.Line{
p1 = {
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = TUNNEL_Y - SEPARATOR_SPACING
},
p2 = {
x = RIGHT_X,
y = TUNNEL_Y - SEPARATOR_SPACING
}
},
Widget.Line{
p1 = {
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = SOCKS_Y - SEPARATOR_SPACING
},
p2 = {
x = RIGHT_X,
y = SOCKS_Y - SEPARATOR_SPACING
}
},
Widget.Line{
p1 = {
x = CONSTRUCTION_GLOBAL.RIGHT_X,
y = TABLE_Y - SEPARATOR_SPACING
},
p2 = {
x = RIGHT_X,
y = TABLE_Y - SEPARATOR_SPACING
}
}
}
local __set_ssh_status = function(status, obj, cr)
TextColumn.set(obj, cr, 1, _STRING_MATCH(status, '/autossh') and 'Yes' or 'No')
TextColumn.set(obj, cr, 2, _STRING_MATCH(status, '/ssh') and 'Yes' or 'No')
end
local __parse_log_line = function(log_line)
if not log_line then return end
local username = _STRING_MATCH(log_line, USERNAME_FORMAT)
local start_date = _STRING_MATCH(log_line, START_TIME_FORMAT)
local start_time_unix = util.execute_cmd('date --date="'..start_date..'" +"%s"', nil, '*n')
local start_time_formatted = util.execute_cmd(
'date --date="'..start_date..'" +"%-m-%-d-%y (%H:%M)"', '(.+)\n')
if _STRING_FIND(log_line, 'still logged in', 1, true) then
return username, start_time_unix, '*!* '..start_time_formatted..' *!*'
else
return username, start_time_unix, start_time_formatted
end
end
local __update = function(cr)
__set_ssh_status(util.execute_cmd('systemctl status tunnel'), tunnel.info, cr)
__set_ssh_status(util.execute_cmd('systemctl status socks'), socks.info, cr)
if util.execute_cmd('systemctl is-active ufw') == 'active\n' then
CriticalText.set(firewall.info, cr, 'Up', 1)
else
CriticalText.set(firewall.info, cr, 'Down', 0)
end
local next_wtmp = _STRING_GMATCH(util.execute_cmd(
"last -iw --time-format iso | grep -v '0.0.0.0' | head -n -2"), '[^\n]+')
local next_btmp = _STRING_GMATCH(util.execute_cmd(
"lastb -iw --time-format iso | grep -v '0.0.0.0' | head -n -2"), '[^\n]+')
local wtmp_username, wtmp_time, wtmp_str = __parse_log_line(next_wtmp())
local btmp_username, btmp_time, btmp_str = __parse_log_line(next_btmp())
local column1 = tbl.columns[1]
local column2 = tbl.columns[2]
for r = 1, NUM_ROWS do
if wtmp_time and btmp_time then
if wtmp_time > btmp_time then
TextColumn.set(column1, cr, r, wtmp_username)
TextColumn.set(column2, cr, r, wtmp_str)
wtmp_username, wtmp_time, wtmp_str = __parse_log_line(next_wtmp())
else
TextColumn.set(column1, cr, r, '*'..btmp_username)
TextColumn.set(column2, cr, r, btmp_str)
btmp_username, btmp_time, btmp_str = __parse_log_line(next_btmp())
end
elseif wtmp_time then
TextColumn.set(column1, cr, r, wtmp_username)
TextColumn.set(column2, cr, r, wtmp_str)
wtmp_username, wtmp_time, wtmp_str = __parse_log_line(next_wtmp())
elseif btmp_time then
TextColumn.set(column1, cr, r, '*'..btmp_username)
TextColumn.set(column2, cr, r, btmp_str)
btmp_username, btmp_time, btmp_str = __parse_log_line(next_btmp())
else
TextColumn.set(column1, cr, r, '--')
TextColumn.set(column2, cr, r, '--')
end
end
end
__update(_CR)
Widget = nil
schema = nil
SPACING = nil
SEPARATOR_SPACING = nil
MODULE_Y = nil
RIGHT_X = nil
TUNNEL_Y = nil
SOCKS_Y = nil
FIREWALL_Y = nil
TABLE_Y = nil
TABLE_BODY_Y = nil
_CR = nil
local draw = function(cr, current_interface, trigger)
if trigger == 0 then __update(cr) end
if current_interface == 1 then
Text.draw(header.text, cr)
Line.draw(header.underline, cr)
TextColumn.draw(tunnel.labels, cr)
TextColumn.draw(tunnel.info, cr)
Line.draw(separators[1], cr)
TextColumn.draw(socks.labels, cr)
TextColumn.draw(socks.info, cr)
Line.draw(separators[2], cr)
Text.draw(firewall.label, cr)
CriticalText.draw(firewall.info, cr)
Line.draw(separators[3], cr)
local headers = tbl.headers
Text.draw(headers[1], cr)
Text.draw(headers[2], cr)
local column1 = tbl.columns[1]
local column2 = tbl.columns[2]
TextColumn.draw(column1, cr)
TextColumn.draw(column2, cr)
end
end
return draw