123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- local pkg = {}
-
- ------------------------------------------------------------------------------
- -- config and handling --
- ------------------------------------------------------------------------------
-
- pkg.load_mailboxes = function()
- --
- -- Load mailboxes from $IMAPDOMO_CFGDIR/mailboxes.lua
- --
- local fname = os.getenv("IMAPDOMO_CFGDIR") .. '/mailboxes.lua'
- assert(pkg.file_exists(fname))
- return dofile(fname)
- end
-
- pkg.file_exists = function(name)
- --
- -- True if file *name* exists
- --
- local f = io.open(name,"r")
- if f ~= nil then
- io.close(f)
- return true
- else
- return false
- end
- end
-
- pkg.do_if_exists = function (filename)
- --
- -- Do file from home, if exists
- --
- local file = os.getenv("IMAPFILTER_HOME") .. "/" .. filename
- if pkg.file_exists(file) then
- dofile(file)
- return
- end
- end
-
- pkg.handle = function()
- --
- -- Handle action if it's valid
- --
- local action = os.getenv("IMAPDOMO_ACTION")
- local file = os.getenv("IMAPFILTER_HOME") .. "/handlers/" .. action .. ".lua"
- if pkg.file_exists(file) then
- pkg.do_if_exists("init.lua")
- dofile(file)
- else
- error("no handler for action: " .. action)
- return nil
- end
- end
-
-
- ------------------------------------------------------------------------------
- -- mail getters --
- ------------------------------------------------------------------------------
-
- pkg.get_queue = function(acct, mbox, size)
- --
- -- Get queue from *mbox* from *acct* or nil (no messages)
- --
- -- If mbox is not specified, "FILTER_QUEUE" is used
- --
- mbox = mbox or "FILTER_QUEUE"
- size = size or 512
- local exist = acct[mbox]:check_status()
- if exist > 0 then
- return pkg.head(size, acct[mbox]:select_all())
- end
- return nil
- end
-
- pkg._notifirc1 = function(subj, from, body)
- --
- -- notify about message using (pre-configured) notifirc
- --
- local fd = assert(io.popen('notifirc -c mail -f - "message preview:"', "w"))
- local fmt = "> %s\n> %s\n> BODY: %s"
- fd:write(fmt:format(subj, from, body))
- fd:close()
- end
-
- pkg.notifirc_all = function(seq)
- --
- -- Send notifications about all messages in *seq*
- --
- for _, mesg in ipairs(seq) do
- local mbox, uid, subj, from, body
- mbox, uid = table.unpack(mesg)
- subj = mbox[uid]:fetch_field('Subject')
- from = mbox[uid]:fetch_field('From')
- body = mbox[uid]:fetch_body()
- pkg._notifirc1(subj, from, body)
- end
- end
-
- pkg.hook_all = function(seq, hname, ...)
- --
- -- Call hook hname for all messages in seq
- --
- local hfile = os.getenv("IMAPFILTER_HOME") .. "/hooks/" .. hname
- local hargs = {...}
- local hcmd = hfile
- local fmt = ' %q'
- if pkg.file_exists(hfile) then
- for _, harg in pairs(hargs) do
- hcmd = hcmd .. fmt:format(harg)
- end
- for _, mesg in ipairs(seq) do
- local mbox, uid, subj, body, from, to, date
- mbox, uid = table.unpack(mesg)
- subj = mbox[uid]:fetch_field('Subject')
- from = mbox[uid]:fetch_field('From')
- to = mbox[uid]:fetch_field('To')
- date = mbox[uid]:fetch_field('Date')
- body = mbox[uid]:fetch_body()
- pkg._hook1(hcmd, subj, from, to, date, body)
- end
- else
- error("no such hook: " .. hname)
- return nil
- end
- end
-
- pkg._hook1 = function(hcmd, subj, from, to, date, body)
- --
- -- push message through hook script
- --
- local fd = assert(io.popen(hcmd, "w"))
- local fmt = "subj=%s\nfrom=%s\nto=%s\ndate=%s\n%s"
- fd:write(fmt:format(subj, from, to, date, body))
- fd:close()
- end
-
- pkg._partinf_compare = function(a, b)
- if not type(a) == type(b) then
- return false
- end
- if type(a) == 'number' then
- return a == b
- elseif type(a) == 'string' then
- return a:lower() == b:lower()
- end
- end
-
- pkg.has_part_like = function(query, structure)
- --
- -- True if structure has MIME part matching *query*
- --
- if structure == nil then
- return false
- end
- for partid, partinf in pairs(structure) do
- local part_answer = true
- -- check all query parts
- for qkey, qvalue in pairs(query) do
- local value = partinf[qkey]
- if not pkg._partinf_compare(value, qvalue) then
- part_answer = false
- break
- end
- end
- if part_answer then
- return true
- end
- end
- return false
- end
-
- pkg.save_header = function(mesg, name)
- --
- -- Append header from *mesg* to file named *name*
- --
- -- File will be placed under directory specified by IMAPDOMO_HEADERS
- -- environment variable.
- --
- local dest = os.getenv("IMAPDOMO_HEADERS") .. '/' .. name
- local cmd = ('cat >>"%q"'):format(dest)
- local mbox, uid = table.unpack(mesg)
- local header = mbox[uid]:fetch_header()
- if pkg.pipe_to(cmd, header) == 0 then
- return true
- else
- return false
- end
- end
-
- pkg.filter_header_saved = function(seq, name)
- --
- -- Save headers from sequence
- --
- -- Append header of each message in sequence *seq* to file names
- -- *name* and return new sequence with those messages where save was
- -- successful.
- --
- local result = {}
- for _, mesg in ipairs(seq) do
- if pkg.save_header(mesg, name) then
- table.insert(result, mesg)
- end
- end
- return result
- end
-
- pkg.head = function(num, seq)
- --
- -- Return first *num* elements from sequence
- --
- if not seq then return seq end
- local result = seq:is_smaller(0) -- HACK to generate empty sequence
- for idx, value in ipairs(seq) do
- if idx > num then break end
- table.insert(result, value)
- end
- return result
- end
-
- pkg.filter_part_like = function(query, seq)
- --
- -- Run MIME part query on *seq* sequence of messages
- --
- local result = {}
- for _, mesg in ipairs(seq) do
- local mbox, uid = table.unpack(mesg)
- local structure = mbox[uid]:fetch_structure()
- if pkg.has_part_like(query, structure) then
- table.insert(result, mesg)
- end
- end
- return result
- end
-
- return pkg
|