aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/data.lua73
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/data.lua b/lib/data.lua
index 6f1f7ea..8e60d6d 100644
--- a/lib/data.lua
+++ b/lib/data.lua
@@ -517,5 +517,78 @@ function M.month_shape(year, month)
return last.day, (first.wday + 5) % 7 + 1
end
+-- The breaktimer cache written by bin/breaktimer-sample.sh.
+--
+-- Returns a table describing the daemon, or nil when the cache is absent or
+-- carries no 'generated' key (the sampler never ran). The display strings are
+-- derived here rather than in the widget so the phase-to-word and
+-- phase-to-colour decisions can be tested without Cairo:
+--
+-- { running, state, phase, frozen, remain,
+-- countdown = '24:31' or '--',
+-- phase_label = 'working' | 'micro-pausa' | 'pausa lunga' | 'in pausa'
+-- | 'outside working hours' | 'fermo',
+-- next = 'pausa' | 'lavoro' | '--',
+-- role = 'ok' | 'heading' | 'highlight' | 'warning' | 'label' }
+--
+-- `frozen` is the sampler's read of whether the clock is ticking: the phase is
+-- 'working' but the remain file has stopped being rewritten. Outside the work
+-- window that is normal and reads as such; a hung daemon looks the same, and
+-- should.
+--
+-- The countdown leads to the next phase, but the daemon keeps the cycle count
+-- in memory and never writes it, so whether the NEXT break is a micro or a long
+-- one is not knowable here. 'pausa' is the honest answer; the phase word carries
+-- the rest.
+function M.breaktimer_parse(text)
+ if type(text) ~= 'string' then return nil end
+ local kv = M.kv_parse(text)
+ if not kv.generated then return nil end
+
+ local running = kv.running == 'yes'
+ local state = kv.state or 'stopped'
+ local phase = kv.phase or 'stopped'
+ local remain = tonumber(kv.remain) or 0
+ if remain < 0 then remain = 0 end
+
+ local out = {
+ running = running,
+ state = state,
+ phase = phase,
+ frozen = kv.frozen == 'yes',
+ remain = remain,
+ }
+
+ -- Not running and stopped are the same thing on the card. The sampler's
+ -- liveness check is what turns a dead PID into this reading: the state file
+ -- can still say 'running' after a crash or a kill -9.
+ if not running or state == 'stopped' then
+ out.countdown = '--'
+ out.phase_label = 'fermo'
+ out.next = '--'
+ out.role = 'label'
+ return out
+ end
+
+ out.countdown = string.format('%d:%02d', math.floor(remain / 60), remain % 60)
+
+ if state == 'paused' then
+ out.phase_label = 'in pausa'
+ out.role = 'warning'
+ elseif out.frozen then
+ out.phase_label = 'outside working hours'
+ out.role = 'label'
+ else
+ local labels = { working = 'working', breaking = 'micro-pausa',
+ longbreak = 'pausa lunga' }
+ local roles = { working = 'ok', breaking = 'heading',
+ longbreak = 'highlight' }
+ out.phase_label = labels[phase] or phase
+ out.role = roles[phase] or 'value'
+ end
+
+ out.next = (phase == 'working') and 'pausa' or 'lavoro'
+ return out
+end
return M