Auto-Archiving, and Unread Threshold Alert
Marco Colombo
marco at esi.it
Wed May 11 08:38:24 EDT 2005
On Tue, 2005-05-10 at 22:41 +0800, Senandung Mendonan wrote:
> Hi,
>
> I need to do the following in Cyrus IMAP 2.2.12:-
>
> 1. Daily auto-archiving
> - On 12am each day, an IMAP/Cyrus agent runs through each user's
> mailbox, and sort out all existing mails into today, yesterday, last
> week, and last month folders.
The best way to achieve this, by far, is client-side. See VFolders in
evolution (those are not real IMAP folders, and the server is totally
unaware of them; it's only a matter client interface). But I understand
sometimes you can't choose the client and you have to band-aid on the
server side.
> 2. Unread threshold alerts
> - Every 5 minutes, an IMAP/Cyrus agent runs through each user's
> mailbox (or any other alternative ways), and upon finding new mails
> that are unread since last poll, alert the sysadmin.
5 mins? Wow. Are you sure you need this? The implications are:
- time to read and process a single message is << 5 mins
- rate of message arrivals is predictable, and is < the rate at which
messages are processed - ever;
- _all_ messages are to be processed (or deleted), no matter if they are
not relevant with the activity (based on the subject) - no one can say
"ok, this one i'll read later".
It the above conditions are not strictly met, all you have is a nice
entropy generator (the sysadmin will receive almost random and useless
notifications).
Anyway, the quickest way to implement your agent is a Perl or Python
script. Here's one (quick and dirty) that prints the number of messages
in each user's INBOX that are both unread and older than 5 minutes. It
assumes you can do PLAIN authentication over SSL to imapd running on
localhost:
#!/usr/bin/env python
import sys
import re
import imaplib
import time
import email.Utils
# authentication credentials for the admin user
auth = "admin"
password = "*******"
def check_one(user, threshold = 300):
conn = imaplib.IMAP4_SSL()
rc, data = conn.authenticate("PLAIN",
lambda x: "\0".join((user, auth, password)))
if rc != "OK":
sys.exit(1)
rc, data = conn.select(readonly = 1) # INBOX
if rc != "OK":
sys.exit(1)
rc, data = conn.uid("SEARCH", "UNSEEN")
if rc != "OK":
sys.exit(1)
uids = ",".join(data[0].split())
if not uids:
return
rs, data = conn.uid("FETCH", uids, "INTERNALDATE")
if rc != "OK":
sys.exit(1)
patt = re.compile(r'\(UID ([0-9]+) INTERNALDATE "([^"]*)"\)')
unread_messages = []
for line in data:
m = patt.search(line)
if not m:
continue
uid = m.group(1)
internaldate_mk = email.Utils.parsedate(m.group(2))
if not internaldate_mk:
continue
internaldate_ts = time.mktime(internaldate_mk)
now_ts = time.time()
if internaldate_ts < now_ts - threshold:
unread_messages.append(uid)
conn.logout()
return unread_messages
# the list of users to check
users = ("user1", "user2", "user3")
for user in users:
mesgs = check_one(user)
if mesgs:
print "user %s has %d messages." % (user, len(check_one(user)))
You can do the same in Perl of course. And moving messages around should
be possible too, for your "daily auto-archiving".
.TM.
--
____/ ____/ /
/ / / Marco Colombo
___/ ___ / / Technical Manager
/ / / ESI s.r.l.
_____/ _____/ _/ Colombo at ESI.it
---
Cyrus Home Page: http://asg.web.cmu.edu/cyrus
Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu
List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html
More information about the Info-cyrus
mailing list