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) -- -- Get queue from *mbox* from *acct* or nil (no messages) -- -- If mbox is not specified, "FILTER_QUEUE" is used -- mbox = mbox or "FILTER_QUEUE" local exist = acct[mbox]:check_status() if exist > 0 then return 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.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