<commit_before>--
-- ion/mod_statusbar/ion-statusd/statusd_mail.lua
-- 
-- Copyright (c) <NAME> 2004-2006.
--
-- Ion is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--

-- The keyword for this monitor
local mon = "mail"

local defaults={
    update_interval=10*1000,
    retry_interval=60*10*1000,
    mbox = os.getenv("MAIL"),
    files = {}
}

local settings=table.join(statusd.get_config(mon), defaults)

local function TR(s, ...)
    return string.format(statusd.gettext(s), unpack(arg))
end

local function check_spool()
    if not settings.mbox then
        statusd.warn(TR("MAIL environment variable not set "..
                        "and no spool given."))
    end
end

if not settings.files["spool"] then
    check_spool()
    settings.files["spool"] = settings.mbox
elseif not(settings.files["spool"] == mbox) then
    statusd.warn(TR("%s.mbox does not match %s.files['spool']; using %s.mbox",
		    mon, mon, mon))
    check_spool()
    settings.files["spool"] = settings.mbox
end

local function calcmail(fname)
    local f, err=io.open(fname, 'r')
    local total, read, old=0, 0, 0
    local had_blank=true
    local in_headers=false
    local had_status=false
    
    if not f then
        statusd.warn(err)
        return
    end

    for l in f:lines() do
        if had_blank and string.find(l, '^From ') then
            total=total+1
            had_status=false
            in_headers=true
            had_blank=false
        else
            had_blank=false
            if l=="" then
                if in_headers then
                    in_headers=false
                end
                had_blank=true
            elseif in_headers and not had_status then
                local st, en, stat=string.find(l, '^Status:(.*)')
                if stat then
                    had_status=true
                    if string.find(l, 'R') then
                        read=read+1
                    end
                    if string.find(l, 'O') then
                        old=old+1
                    end
                end
            end
        end
    end
    
    f:close()
    
    return total, total-read, total-old
end


local mail_timer
local mail_timestamps = {}
function init_timestamps ()
    for key, val in settings.files do
        mail_timestamps[key]=-2.0
    end
end
init_timestamps()

local function update_mail()
    local failed
    for key, mbox in settings.files do
        if not mbox then
            error(TR(key.." not set"))
        end
    
        local old_tm=mail_timestamps[key]
        mail_timestamps[key]=statusd.last_modified(mbox)
    
        if mail_timestamps[key]>old_tm then
	    local mail_total, mail_unread, mail_new=calcmail(mbox)
	    if failed == nil then
	        failed = not mail_total
	    else
	        failed = failed and (not mail_total)
	    end
        
	    if key == "spool" then
	        meter=mon
	    else
	        meter=mon.."_"..key
	    end
	    if mail_total then
	        statusd.inform(meter.."_new", tostring(mail_new))
	        statusd.inform(meter.."_unread", tostring(mail_unread))
	        statusd.inform(meter.."_total", tostring(mail_total))

	        if mail_new>0 then
		    statusd.inform(meter.."_new_hint", "important")
	        else<commit_msg>Few more missing table-iteration changes.<commit_after>--
-- ion/mod_statusbar/ion-statusd/statusd_mail.lua
-- 
-- Copyright (c) <NAME> 2004-2006.
--
-- Ion is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--

-- The keyword for this monitor
local mon = "mail"

local defaults={
    update_interval=10*1000,
    retry_interval=60*10*1000,
    mbox = os.getenv("MAIL"),
    files = {}
}

local settings=table.join(statusd.get_config(mon), defaults)

local function TR(s, ...)
    return string.format(statusd.gettext(s), unpack(arg))
end

local function check_spool()
    if not settings.mbox then
        statusd.warn(TR("MAIL environment variable not set "..
                        "and no spool given."))
    end
end

if not settings.files["spool"] then
    check_spool()
    settings.files["spool"] = settings.mbox
elseif not(settings.files["spool"] == mbox) then
    statusd.warn(TR("%s.mbox does not match %s.files['spool']; using %s.mbox",
		    mon, mon, mon))
    check_spool()
    settings.files["spool"] = settings.mbox
end

local function calcmail(fname)
    local f, err=io.open(fname, 'r')
    local total, read, old=0, 0, 0
    local had_blank=true
    local in_headers=false
    local had_status=false
    
    if not f then
        statusd.warn(err)
        return
    end

    for l in f:lines() do
        if had_blank and string.find(l, '^From ') then
            total=total+1
            had_status=false
            in_headers=true
            had_blank=false
        else
            had_blank=false
            if l=="" then
                if in_headers then
                    in_headers=false
                end
                had_blank=true
            elseif in_headers and not had_status then
                local st, en, stat=string.find(l, '^Status:(.*)')
                if stat then
                    had_status=true
                    if string.find(l, 'R') then
                        read=read+1
                    end
                    if string.find(l, 'O') then
                        old=old+1
                    end
                end
            end
        end
    end
    
    f:close()
    
    return total, total-read, total-old
end


local mail_timer
local mail_timestamps = {}
function init_timestamps ()
    for key, val in pairs(settings.files) do
        mail_timestamps[key]=-2.0
    end
end
init_timestamps()

local function update_mail()
    local failed
    for key, mbox in pairs(settings.files) do
        if not mbox then
            error(TR(key.." not set"))
        end
    
        local old_tm=mail_timestamps[key]
        mail_timestamps[key]=statusd.last_modified(mbox)
    
        if mail_timestamps[key]>old_tm then
	    local mail_total, mail_unread, mail_new=calcmail(mbox)
	    if failed == nil then
	        failed = not mail_total
	    else
	        failed = failed and (not mail_total)
	    end
        
	    if key == "spool" then
	        meter=mon
	    else
	        meter=mon.."_"..key
	    end
	    if mail_total then
	        statusd.inform(meter.."_new", tostring(mail_new))
	        statusd.inform(meter.."_unread", tostring(mail_unread))
	        statusd.inform(meter.."_total", tostring(mail_total))

	        if mail_new>0 then
		    statusd.inform(meter.."_new_hint", "important")
	        else
{'fraction_non_alphanumeric': 0.09936635944700462, 'fraction_numerical': 0.009504608294930876, 'mean_word_length': 1.9340937896070975, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7546711', 'n_tokens_mistral': 2227, 'n_tokens_neox': 2077, 'n_words': 575}