aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 19:21:54 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 19:21:54 +0200
commitbff7023cd028b06a3e3d841b9769c3b46da06d0d (patch)
treeccd71af4c7d1fa5dbd1d643393bf157387379642
parent3e0177f613a6b04f957d0b4a426a940a9e68092a (diff)
downloadconky-theme-udt-bff7023cd028b06a3e3d841b9769c3b46da06d0d.tar.gz
conky-theme-udt-bff7023cd028b06a3e3d841b9769c3b46da06d0d.zip
feat: add the slackware card
The big value is the time since slackpkg's ChangeLog changed, coloured green under a day, amber to a week, red past it. A cache with no changelog key is a different failure from no cache at all: the sampler ran and the ChangeLog is what was missing, so the rows still draw and only the age reads '--'. Collapsing the two would send the reader to the wrong problem. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
-rw-r--r--widgets/slackware.lua121
1 files changed, 121 insertions, 0 deletions
diff --git a/widgets/slackware.lua b/widgets/slackware.lua
new file mode 100644
index 0000000..709438d
--- /dev/null
+++ b/widgets/slackware.lua
@@ -0,0 +1,121 @@
+-- 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 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 = 0.30, 0.85, 0.32
+
+ 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
+ local S = clamp(inner.h * 0.94 / (1.78 + 2 * 0.72), 10, 72)
+ S = math.min(S, card.fit_unit(cr, inner.w * 0.96, {
+ { { 'SLACKWARE', card.FONT_MONO, LABEL_F } },
+ { { 'no slackware data', card.FONT_UI, 0.36 } },
+ { { 'bin/slackware-sample.sh', card.FONT_MONO, ROW_F } },
+ }, 100))
+ card.font(cr, card.FONT_MONO, S * LABEL_F, false)
+ card.rgba(cr, colors.label)
+ card.text(cr, inner.x, inner.y + S * LABEL_F, 'SLACKWARE')
+ card.font(cr, card.FONT_UI, S * 0.36, true)
+ card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6, 'no slackware data')
+ card.font(cr, card.FONT_MONO, S * ROW_F, false)
+ card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6 + S * 0.72,
+ '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 = {
+ { { 'SLACKWARE', card.FONT_MONO, LABEL_F }, { age_txt, card.FONT_HEAVY, BIG_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.rgba(cr, colors.label)
+ card.text(cr, inner.x, inner.y + label_size, 'SLACKWARE')
+
+ 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