|
@@ -1,9 +1,19 @@
|
|
1
|
+local pkg = {}
|
1
|
2
|
|
2
|
3
|
------------------------------------------------------------------------------
|
3
|
4
|
-- config and handling --
|
4
|
5
|
------------------------------------------------------------------------------
|
5
|
6
|
|
6
|
|
-function file_exists(name)
|
|
7
|
+pkg.load_mailboxes = function()
|
|
8
|
+ --
|
|
9
|
+ -- Load mailboxes from $IMAPDOMO_CFGDIR/mailboxes.lua
|
|
10
|
+ --
|
|
11
|
+ local fname = os.getenv("IMAPDOMO_CFGDIR") .. '/mailboxes.lua'
|
|
12
|
+ assert(pkg.file_exists(fname))
|
|
13
|
+ return dofile(fname)
|
|
14
|
+end
|
|
15
|
+
|
|
16
|
+pkg.file_exists = function(name)
|
7
|
17
|
--
|
8
|
18
|
-- True if file *name* exists
|
9
|
19
|
--
|
|
@@ -16,25 +26,25 @@ function file_exists(name)
|
16
|
26
|
end
|
17
|
27
|
end
|
18
|
28
|
|
19
|
|
-function do_if_exists(filename)
|
|
29
|
+pkg.do_if_exists = function (filename)
|
20
|
30
|
--
|
21
|
31
|
-- Do file from home, if exists
|
22
|
32
|
--
|
23
|
33
|
local file = os.getenv("IMAPFILTER_HOME") .. "/" .. filename
|
24
|
|
- if file_exists(file) then
|
|
34
|
+ if pkg.file_exists(file) then
|
25
|
35
|
dofile(file)
|
26
|
36
|
return
|
27
|
37
|
end
|
28
|
38
|
end
|
29
|
39
|
|
30
|
|
-function handle()
|
|
40
|
+pkg.handle = function()
|
31
|
41
|
--
|
32
|
42
|
-- Handle action if it's valid
|
33
|
43
|
--
|
34
|
44
|
local action = os.getenv("IMAPDOMO_ACTION")
|
35
|
45
|
local file = os.getenv("IMAPFILTER_HOME") .. "/handlers/" .. action .. ".lua"
|
36
|
|
- if file_exists(file) then
|
37
|
|
- do_if_exists("init.lua")
|
|
46
|
+ if pkg.file_exists(file) then
|
|
47
|
+ pkg.do_if_exists("init.lua")
|
38
|
48
|
dofile(file)
|
39
|
49
|
else
|
40
|
50
|
error("no handler for action: " .. action)
|
|
@@ -47,21 +57,21 @@ end
|
47
|
57
|
-- mail getters --
|
48
|
58
|
------------------------------------------------------------------------------
|
49
|
59
|
|
50
|
|
-function get_queue(acct, mbox)
|
|
60
|
+pkg.get_queue = function(acct, mbox)
|
51
|
61
|
--
|
52
|
62
|
-- Get queue from *mbox* from *acct* or nil (no messages)
|
53
|
63
|
--
|
54
|
64
|
-- If mbox is not specified, "FILTER_QUEUE" is used
|
55
|
65
|
--
|
56
|
66
|
mbox = mbox or "FILTER_QUEUE"
|
57
|
|
- local exist, unread, unseen, uidnext = acct[mbox]:check_status()
|
|
67
|
+ local exist = acct[mbox]:check_status()
|
58
|
68
|
if exist > 0 then
|
59
|
69
|
return acct[mbox]:select_all()
|
60
|
70
|
end
|
61
|
71
|
return nil
|
62
|
72
|
end
|
63
|
73
|
|
64
|
|
-function _notifirc1(subj, from, body)
|
|
74
|
+pkg._notifirc1 = function(subj, from, body)
|
65
|
75
|
--
|
66
|
76
|
-- notify about message using (pre-configured) notifirc
|
67
|
77
|
--
|
|
@@ -71,40 +81,41 @@ function _notifirc1(subj, from, body)
|
71
|
81
|
fd:close()
|
72
|
82
|
end
|
73
|
83
|
|
74
|
|
-function notifirc_all(seq)
|
|
84
|
+pkg.notifirc_all = function(seq)
|
75
|
85
|
--
|
76
|
86
|
-- Send notifications about all messages in *seq*
|
77
|
87
|
--
|
78
|
88
|
for _, mesg in ipairs(seq) do
|
|
89
|
+ local mbox, uid, subj, from, body
|
79
|
90
|
mbox, uid = table.unpack(mesg)
|
80
|
91
|
subj = mbox[uid]:fetch_field('Subject')
|
81
|
92
|
from = mbox[uid]:fetch_field('From')
|
82
|
93
|
body = mbox[uid]:fetch_body()
|
83
|
|
- _notifirc1(subj, from, body)
|
|
94
|
+ pkg._notifirc1(subj, from, body)
|
84
|
95
|
end
|
85
|
96
|
end
|
86
|
97
|
|
87
|
|
-function hook_all(seq, hname, ...)
|
|
98
|
+pkg.hook_all = function(seq, hname, ...)
|
88
|
99
|
--
|
89
|
100
|
-- Call hook hname for all messages in seq
|
90
|
101
|
--
|
91
|
102
|
local hfile = os.getenv("IMAPFILTER_HOME") .. "/hooks/" .. hname
|
92
|
103
|
local hargs = {...}
|
93
|
|
- local harg
|
94
|
104
|
local hcmd = hfile
|
95
|
105
|
local fmt = ' %q'
|
96
|
|
- if file_exists(hfile) then
|
|
106
|
+ if pkg.file_exists(hfile) then
|
97
|
107
|
for _, harg in pairs(hargs) do
|
98
|
108
|
hcmd = hcmd .. fmt:format(harg)
|
99
|
109
|
end
|
100
|
110
|
for _, mesg in ipairs(seq) do
|
|
111
|
+ local mbox, uid, subj, body, from, to, date
|
101
|
112
|
mbox, uid = table.unpack(mesg)
|
102
|
113
|
subj = mbox[uid]:fetch_field('Subject')
|
103
|
114
|
from = mbox[uid]:fetch_field('From')
|
104
|
115
|
to = mbox[uid]:fetch_field('To')
|
105
|
116
|
date = mbox[uid]:fetch_field('Date')
|
106
|
117
|
body = mbox[uid]:fetch_body()
|
107
|
|
- _hook1(hcmd, subj, from, to, date, body)
|
|
118
|
+ pkg._hook1(hcmd, subj, from, to, date, body)
|
108
|
119
|
end
|
109
|
120
|
else
|
110
|
121
|
error("no such hook: " .. hname)
|
|
@@ -112,7 +123,7 @@ function hook_all(seq, hname, ...)
|
112
|
123
|
end
|
113
|
124
|
end
|
114
|
125
|
|
115
|
|
-function _hook1(hcmd, subj, from, to, date, body)
|
|
126
|
+pkg._hook1 = function(hcmd, subj, from, to, date, body)
|
116
|
127
|
--
|
117
|
128
|
-- push message through hook script
|
118
|
129
|
--
|
|
@@ -122,7 +133,7 @@ function _hook1(hcmd, subj, from, to, date, body)
|
122
|
133
|
fd:close()
|
123
|
134
|
end
|
124
|
135
|
|
125
|
|
-function _partinf_compare(a, b)
|
|
136
|
+pkg._partinf_compare = function(a, b)
|
126
|
137
|
if not type(a) == type(b) then
|
127
|
138
|
return false
|
128
|
139
|
end
|
|
@@ -133,7 +144,7 @@ function _partinf_compare(a, b)
|
133
|
144
|
end
|
134
|
145
|
end
|
135
|
146
|
|
136
|
|
-function has_part_like(query, structure)
|
|
147
|
+pkg.has_part_like = function(query, structure)
|
137
|
148
|
--
|
138
|
149
|
-- True if structure has MIME part matching *query*
|
139
|
150
|
--
|
|
@@ -144,8 +155,8 @@ function has_part_like(query, structure)
|
144
|
155
|
local part_answer = true
|
145
|
156
|
-- check all query parts
|
146
|
157
|
for qkey, qvalue in pairs(query) do
|
147
|
|
- value = partinf[qkey]
|
148
|
|
- if not _partinf_compare(value, qvalue) then
|
|
158
|
+ local value = partinf[qkey]
|
|
159
|
+ if not pkg._partinf_compare(value, qvalue) then
|
149
|
160
|
part_answer = false
|
150
|
161
|
break
|
151
|
162
|
end
|
|
@@ -157,7 +168,7 @@ function has_part_like(query, structure)
|
157
|
168
|
return false
|
158
|
169
|
end
|
159
|
170
|
|
160
|
|
-function save_header(mesg, name)
|
|
171
|
+pkg.save_header = function(mesg, name)
|
161
|
172
|
--
|
162
|
173
|
-- Append header from *mesg* to file named *name*
|
163
|
174
|
--
|
|
@@ -166,16 +177,16 @@ function save_header(mesg, name)
|
166
|
177
|
--
|
167
|
178
|
local dest = os.getenv("IMAPDOMO_HEADERS") .. '/' .. name
|
168
|
179
|
local cmd = ('cat >>"%q"'):format(dest)
|
169
|
|
- mbox, uid = table.unpack(mesg)
|
170
|
|
- header = mbox[uid]:fetch_header()
|
171
|
|
- if pipe_to(cmd, header) == 0 then
|
|
180
|
+ local mbox, uid = table.unpack(mesg)
|
|
181
|
+ local header = mbox[uid]:fetch_header()
|
|
182
|
+ if pkg.pipe_to(cmd, header) == 0 then
|
172
|
183
|
return true
|
173
|
184
|
else
|
174
|
185
|
return false
|
175
|
186
|
end
|
176
|
187
|
end
|
177
|
188
|
|
178
|
|
-function filter_header_saved(seq, name)
|
|
189
|
+pkg.filter_header_saved = function(seq, name)
|
179
|
190
|
--
|
180
|
191
|
-- Save headers from sequence
|
181
|
192
|
--
|
|
@@ -183,26 +194,28 @@ function filter_header_saved(seq, name)
|
183
|
194
|
-- *name* and return new sequence with those messages where save was
|
184
|
195
|
-- successful.
|
185
|
196
|
--
|
186
|
|
- result = Set {}
|
|
197
|
+ local result = {}
|
187
|
198
|
for _, mesg in ipairs(seq) do
|
188
|
|
- if save_header(mesg, name) then
|
|
199
|
+ if pkg.save_header(mesg, name) then
|
189
|
200
|
table.insert(result, mesg)
|
190
|
201
|
end
|
191
|
202
|
end
|
192
|
203
|
return result
|
193
|
204
|
end
|
194
|
205
|
|
195
|
|
-function filter_part_like(query, seq)
|
|
206
|
+pkg.filter_part_like = function(query, seq)
|
196
|
207
|
--
|
197
|
208
|
-- Run MIME part query on *seq* sequence of messages
|
198
|
209
|
--
|
199
|
|
- result = Set {}
|
|
210
|
+ local result = {}
|
200
|
211
|
for _, mesg in ipairs(seq) do
|
201
|
|
- mbox, uid = table.unpack(mesg)
|
202
|
|
- structure = mbox[uid]:fetch_structure()
|
203
|
|
- if has_part_like(query, structure) then
|
|
212
|
+ local mbox, uid = table.unpack(mesg)
|
|
213
|
+ local structure = mbox[uid]:fetch_structure()
|
|
214
|
+ if pkg.has_part_like(query, structure) then
|
204
|
215
|
table.insert(result, mesg)
|
205
|
216
|
end
|
206
|
217
|
end
|
207
|
218
|
return result
|
208
|
219
|
end
|
|
220
|
+
|
|
221
|
+return pkg
|