File: statusd_mail.lua

package info (click to toggle)
notion 4.0.2%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,676 kB
  • sloc: ansic: 47,508; sh: 2,096; makefile: 603; perl: 270
file content (156 lines) | stat: -rw-r--r-- 3,988 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
--
-- ion/mod_statusbar/ion-statusd/statusd_mail.lua
--
-- Copyright (c) Tuomo Valkonen 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), ...)
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
		    statusd.inform(meter.."_new_hint", "normal")
	        end

	        if mail_unread>0 then
		    statusd.inform(meter.."_unread_hint", "important")
	        else
		    statusd.inform(meter.."_unread_hint", "normal")
	        end
	    end
	end
    end

    if failed then
        statusd.warn(TR("Disabling mail monitor for %d seconds.",
			settings.retry_interval/1000))
	init_timestamps()
	mail_timer:set(settings.retry_interval, update_mail)
	return
    end

    mail_timer:set(settings.update_interval, update_mail)
end

mail_timer=statusd.create_timer()
update_mail()