]> git.decadent.org.uk Git - ion3.git/blob - mod_statusbar/ion-statusd/statusd_mail.lua
[svn-inject] Installing original source of ion3
[ion3.git] / mod_statusbar / ion-statusd / statusd_mail.lua
1 --
2 -- ion/mod_statusbar/ion-statusd/statusd_mail.lua
3 -- 
4 -- Copyright (c) Tuomo Valkonen 2004-2006.
5 --
6 -- Ion is free software; you can redistribute it and/or modify it under
7 -- the terms of the GNU Lesser General Public License as published by
8 -- the Free Software Foundation; either version 2.1 of the License, or
9 -- (at your option) any later version.
10 --
11
12 -- The keyword for this monitor
13 local mon = "mail"
14
15 local defaults={
16     update_interval=10*1000,
17     retry_interval=60*10*1000,
18     mbox = os.getenv("MAIL"),
19     files = {}
20 }
21
22 local settings=table.join(statusd.get_config(mon), defaults)
23
24 local function TR(s, ...)
25     return string.format(statusd.gettext(s), unpack(arg))
26 end
27
28 local function check_spool()
29     if not settings.mbox then
30         statusd.warn(TR("MAIL environment variable not set "..
31                         "and no spool given."))
32     end
33 end
34
35 if not settings.files["spool"] then
36     check_spool()
37     settings.files["spool"] = settings.mbox
38 elseif not(settings.files["spool"] == mbox) then
39     statusd.warn(TR("%s.mbox does not match %s.files['spool']; using %s.mbox",
40                     mon, mon, mon))
41     check_spool()
42     settings.files["spool"] = settings.mbox
43 end
44
45 local function calcmail(fname)
46     local f, err=io.open(fname, 'r')
47     local total, read, old=0, 0, 0
48     local had_blank=true
49     local in_headers=false
50     local had_status=false
51     
52     if not f then
53         statusd.warn(err)
54         return
55     end
56
57     for l in f:lines() do
58         if had_blank and string.find(l, '^From ') then
59             total=total+1
60             had_status=false
61             in_headers=true
62             had_blank=false
63         else
64             had_blank=false
65             if l=="" then
66                 if in_headers then
67                     in_headers=false
68                 end
69                 had_blank=true
70             elseif in_headers and not had_status then
71                 local st, en, stat=string.find(l, '^Status:(.*)')
72                 if stat then
73                     had_status=true
74                     if string.find(l, 'R') then
75                         read=read+1
76                     end
77                     if string.find(l, 'O') then
78                         old=old+1
79                     end
80                 end
81             end
82         end
83     end
84     
85     f:close()
86     
87     return total, total-read, total-old
88 end
89
90
91 local mail_timer
92 local mail_timestamps = {}
93 function init_timestamps ()
94     for key, val in pairs(settings.files) do
95         mail_timestamps[key]=-2.0
96     end
97 end
98 init_timestamps()
99
100 local function update_mail()
101     local failed
102     for key, mbox in pairs(settings.files) do
103         if not mbox then
104             error(TR(key.." not set"))
105         end
106     
107         local old_tm=mail_timestamps[key]
108         mail_timestamps[key]=statusd.last_modified(mbox)
109     
110         if mail_timestamps[key]>old_tm then
111             local mail_total, mail_unread, mail_new=calcmail(mbox)
112             if failed == nil then
113                 failed = not mail_total
114             else
115                 failed = failed and (not mail_total)
116             end
117         
118             if key == "spool" then
119                 meter=mon
120             else
121                 meter=mon.."_"..key
122             end
123             if mail_total then
124                 statusd.inform(meter.."_new", tostring(mail_new))
125                 statusd.inform(meter.."_unread", tostring(mail_unread))
126                 statusd.inform(meter.."_total", tostring(mail_total))
127
128                 if mail_new>0 then
129                     statusd.inform(meter.."_new_hint", "important")
130                 else
131                     statusd.inform(meter.."_new_hint", "normal")
132                 end
133         
134                 if mail_unread>0 then
135                     statusd.inform(meter.."_unread_hint", "important")
136                 else
137                     statusd.inform(meter.."_unread_hint", "normal")
138                 end
139             end
140         end
141     end
142
143     if failed then
144         statusd.warn(TR("Disabling mail monitor for %d seconds.",
145                         settings.retry_interval/1000))
146         init_timestamps()
147         mail_timer:set(settings.retry_interval, update_mail)
148         return
149     end
150    
151     mail_timer:set(settings.update_interval, update_mail)
152 end
153
154 mail_timer=statusd.create_timer()
155 update_mail()
156