-- Slackware: the distribution version, package count, kernel, install age, and -- how long since slackpkg's ChangeLog last changed. -- -- Everything comes from a cache file written by bin/slackware-sample.sh: -- conky's Lua cannot stat a file for an mtime, and counting the package -- directory every two seconds would be a walk per draw. local card = require 'lib.card' local data = require 'lib.data' local CACHE = (os.getenv('XDG_CACHE_HOME') or (os.getenv('HOME') .. '/.cache')) .. '/udt/slackware.txt' -- Hours. A ChangeLog under a day old is current, under a week is ordinary, and -- past that is worth noticing. This extends the shell prompt's binary green/red -- into the board's three-state language rather than adding a fourth convention. local WARN_H, CRIT_H = 24, 168 local SUBTITLE = 'last slackpkg update' local M = {} -- An age in seconds as a short string: hours below two days, then days. Short -- because it is the card's big value and shares its line with the label. local function age_str(seconds) if not seconds then return '--' end -- A future timestamp yields a negative age. Clock skew and a mirror's dated -- file both produce it, and '-8000h' on the dashboard reads as a bug. if seconds < 0 then seconds = 0 end local hours = seconds / 3600 if hours < 48 then return string.format('%dh', math.floor(hours)) end return string.format('%dd', math.floor(hours / 24)) end function M.draw(cr, rect, colors) local inner = card.card(cr, rect, colors) local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end local LABEL_F, BIG_F, ROW_F, SUB_F = 0.30, 1.0, 0.32, 0.26 local kv = data.kv_parse(data.slurp(CACHE) or '') -- No cache at all: the sampler has not run. Name it, as the cache card does, -- rather than leaving a blank cell that is indistinguishable from a crash. if not kv.version then card.notice(cr, inner, colors, 'SLACKWARE', 'no slackware data', 'bin/slackware-sample.sh') return end -- The ChangeLog age, the card's headline. A cache that exists without this -- key is a different failure from no cache: the sampler ran and the -- ChangeLog is what was missing, so the rows still draw and only this reads -- '--'. local changelog = tonumber(kv.changelog) local age_s = (changelog and changelog > 0) and (os.time() - changelog) or nil local age_txt = age_str(age_s) local age_colour = colors.label if age_s then age_colour = card.threshold(math.max(age_s, 0) / 3600, WARN_H, CRIT_H, colors) end -- 'Slackware 15.0+' -> '15.0+': the header already says which distribution. local version = (kv.version or ''):gsub('^Slackware%s+', '') local birth = tonumber(kv.birth) local install_age = (birth and birth > 0) and string.format('%dd', math.floor((os.time() - birth) / 86400)) or '--' local rows = { { 'VERSION', version ~= '' and version or '--' }, { 'PACKAGES', kv.packages or '--' }, { 'KERNEL', kv.kernel or '--' }, { 'AGE', install_age }, } -- Fluid type: the height budget grows the content to fill the cell, the -- measured width fit pulls it back where a row would overrun. local groups = { { { card.title_str(card.ICON.slackware, 'SLACKWARE'), card.FONT_MONO, LABEL_F }, { age_txt, card.FONT_HEAVY, BIG_F } }, { { SUBTITLE, card.FONT_UI, SUB_F } }, } for _, r in ipairs(rows) do groups[#groups + 1] = { { r[1], card.FONT_MONO, ROW_F }, { tostring(r[2]), card.FONT_MONO, ROW_F } } end local S = clamp(math.min(inner.h * 0.94 / (1.5 + #rows * 0.66), card.fit_unit(cr, inner.w * 0.96, groups, 100)), 10, 72) local label_size = S * LABEL_F local row_size = S * ROW_F card.font(cr, card.FONT_HEAVY, S * BIG_F, false) card.rgba(cr, age_colour) card.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, age_txt) card.font(cr, card.FONT_MONO, label_size, false) card.title(cr, inner.x, inner.y + label_size, card.ICON.slackware, 'SLACKWARE', colors) card.font(cr, card.FONT_UI, S * SUB_F, false) card.rgba(cr, colors.label, 0.65) card.text(cr, inner.x, inner.y + label_size + S * SUB_F * 1.5, SUBTITLE) local ey = inner.y + S * BIG_F + row_size * 1.6 local step = row_size * 2.0 card.font(cr, card.FONT_MONO, row_size, false) for _, r in ipairs(rows) do if ey + step > inner.y + inner.h then break end card.rgba(cr, colors.label) card.text(cr, inner.x, ey, r[1]) card.rgba(cr, colors.value) card.text_right(cr, inner.x + inner.w, ey, tostring(r[2])) ey = ey + step end end return M