星期一, 10月 27, 2008

將過大的mailbox移到收件匣

最近由於某些新進同仁都使用WebMail,但又不砍信,造成Mail Server繁忙,只好請他們自行砍信/移信。有些皮比較癢公務繁忙的同仁沒空處理,只好抽空寫支小程式處理。

由於Openwebmail的限制,不能用maildir,只能維持使用mailbox,這是系統loading高的主因。由於許多原因以及沒有功能更齊全的webmail前提下,只能暫時如此處理。本來要用比較熟悉的Java寫,但是搜尋之下並沒有功能完整的library,而Python內建就支援mailbox處理,在缺乏其他支援/資源的情況下也只能硬著頭皮寫。因為我比較懶,裏頭有用到一個date parser,使用前請先安裝。

這裏的環境針對FreeBSD + Postfix+Openwebmail,sendmail/qmail應該也適用,我在Ubuntu開發,所以在Linux"應該"也能正常執行。

完整程式如下:
#!/usr/bin/env python
# coding: utf-8

import datetime
import mailbox
import email.Errors
import os
from stat import ST_SIZE
#由於python沒有內建的Date Parser,所以找了一個dateutil parser, http://labix.org/python-dateutil
#FreeBSD ports裏在 /usr/ports/devel/py-dateutil
from dateutil.parser import parse

def mailbox_apart(inputfile, outputfile, splitdate):
inbox = mailbox.mbox(inputfile);
mboxNew = mailbox.mbox(outputfile);

for key, message in inbox.iteritems():
timex = parse(message['date']);
timex = datetime.date(timex.year, timex.month, timex.day);
if cmp(timex, splitdate) < 0:
mboxNew.lock();
mboxNew.add(message);
mboxNew.flush();
mboxNew.unlock();
# Remove original message
inbox.lock();
inbox.discard(key);
inbox.flush();
inbox.unlock();
inbox.close();
mboxNew.close();
return;

def read_passwd_and_do_it(passwordfile, daysago):
f=open(passwordfile, 'r');
for line in f:
line=line.lstrip();
if not line.startswith('#'):
x=line.split(':');
userid=x[0];
homedir = x[5];
if homedir.startswith('/home'):
inxfile = '/var/mail/'+userid;
outxfile = homedir +'/mail/saved-messages'
try:
size = os.stat(inxfile)[ST_SIZE];
if size > critial:
mailbox_apart(inxfile, outxfile, daysago);
except (IOError, OSError), e:
pass;
except mailbox.ExternalClashError, e:
pass;
except Exception, e:
print e;
f.close();
return;

#主程式
#超過多大的檔案才處理,此處是500M
critial = 500000000;
#超過幾天的mail才移
removedays = 30;
#帳號檔
passwdfile = '/etc/passwd';
today = datetime.date.today();
theDate = datetime.date(today.year, today.month, today.day);
aMonthAgo = theDate - datetime.timedelta(days=removedays);
read_passwd_and_do_it(passwdfile, aMonthAgo);

本程式提供給有此需求的朋友,版權為GPL

4 則留言:

heath 提到...

這樣做那些皮比較癢的同仁會不會因此找不到信而誤以為你刪了信?這樣很煩,每個找不到信的都會來煩一次...

鳥毅 提到...

heath, you got the point!

所以我才有個選項是超過多大的檔案才處理,而不是一視同仁。

目前這支程式一個檔案也沒處理過!因為我己經先寄了20幾封email逐一通知,請他們自己搬檔案(網管真難為)。

如果貴公司和敝公司一樣,介於100~200個帳號,那麼每個帳號的quota在200Mb以下應該可以保持不錯的效率,不要像鳥毅一樣讓user的mailbox長到500Mb...

上班豬 提到...

請問一下
如果新信匣的信搬到收信匣後

如果新信匣的信又堆到500MB

是不是又會搬到收信匣
變成 500MB+500MB=1000MB
讓收信匣 開不起來呢@@?

鳥毅 提到...

上班豬,應該不致於開不起來,只是很慢而已。

移到新件匣只是權宜之計,你可以修改script,產生新的信件匣,徹底解決此問題。

如同heath所說,皮比較癢的同仁會因此找不到信而誤以為你刪了信,所以我一開始就沒有打算再多開信匣。