67 lines
2.2 KiB
Lua
67 lines
2.2 KiB
Lua
|
|
-- Reads memory keys "habit_streak.<habit>.<YYYY-MM-DD>" and computes streak per habit.
|
||
|
|
local t = jarvis.context.time
|
||
|
|
|
||
|
|
local function date_offset(days_back)
|
||
|
|
-- Simple naive backwards calc (no calendar arithmetic — close enough for streaks)
|
||
|
|
local jd_today = t.year * 365 + math.floor(t.year / 4)
|
||
|
|
+ ({0,31,59,90,120,151,181,212,243,273,304,334})[t.month]
|
||
|
|
+ (t.day - 1)
|
||
|
|
local target_jd = jd_today - days_back
|
||
|
|
-- Convert back to YYYY-MM-DD (approximate)
|
||
|
|
local y = math.floor(target_jd / 365.25)
|
||
|
|
local doy = target_jd - math.floor(y * 365.25)
|
||
|
|
local month_starts = {0,31,59,90,120,151,181,212,243,273,304,334}
|
||
|
|
local mo = 12
|
||
|
|
for i = 12, 1, -1 do
|
||
|
|
if doy >= month_starts[i] then mo = i; doy = doy - month_starts[i]; break end
|
||
|
|
end
|
||
|
|
return string.format("%04d-%02d-%02d", y, mo, doy + 1)
|
||
|
|
end
|
||
|
|
|
||
|
|
local all = jarvis.memory.all()
|
||
|
|
|
||
|
|
-- Group keys by habit name
|
||
|
|
local by_habit = {}
|
||
|
|
for _, rec in ipairs(all) do
|
||
|
|
local habit, date = rec.key:match("^habit_streak%.([^%.]+)%.(.+)$")
|
||
|
|
if habit and date then
|
||
|
|
by_habit[habit] = by_habit[habit] or {}
|
||
|
|
by_habit[habit][date] = true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if next(by_habit) == nil then
|
||
|
|
return jarvis.cmd.not_found("Привычек ещё не отмечено. Скажи 'выполнил привычку' после события.")
|
||
|
|
end
|
||
|
|
|
||
|
|
-- For each habit, count consecutive days back from today
|
||
|
|
local results = {}
|
||
|
|
for habit, dates in pairs(by_habit) do
|
||
|
|
local streak = 0
|
||
|
|
for d = 0, 30 do
|
||
|
|
local key_date = date_offset(d)
|
||
|
|
if dates[key_date] then
|
||
|
|
streak = streak + 1
|
||
|
|
else
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
table.insert(results, { habit = habit, streak = streak })
|
||
|
|
end
|
||
|
|
|
||
|
|
table.sort(results, function(a, b) return a.streak > b.streak end)
|
||
|
|
|
||
|
|
local sample = math.min(#results, 3)
|
||
|
|
local lines = {}
|
||
|
|
for i = 1, sample do
|
||
|
|
local r = results[i]
|
||
|
|
if r.streak == 0 then
|
||
|
|
table.insert(lines, r.habit .. " прервана")
|
||
|
|
else
|
||
|
|
local d = r.streak == 1 and "день" or (r.streak < 5 and "дня" or "дней")
|
||
|
|
table.insert(lines, r.habit .. " " .. r.streak .. " " .. d)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return jarvis.cmd.ok("Стрики: " .. table.concat(lines, ", ") .. ".")
|