6

私たちのオフィスは電子メールに2つのIMAPサーバーを使用しています。1つは受信サーバーで最近の電子メールを保持し、もう1つはアーカイブサーバーです。私たちは主にOutlook2010を使用しており、現在のプロセスは、送信されたメッセージを着信サーバーからアーカイブに定期的にドラッグすることです。

今日、私はスクリプトの作成を検討するように求められました。スクリプトを定期的に(おそらくcrontabを使用して)取得し、送信されたすべてのメッセージをアーカイブに移動します。

サーバーにアクセスして調べ回るSSLまたはtelnetの例をいくつか調べました。ただし、これをスクリプト化する最善の方法や、IMAP環境内でサーバー間でファイルを移動する方法がわかりません。

これを達成するための最良の方法は何ですか?快適なレベルからPythonを使用したいのですが、別の言語で既存のソリューションがすでに存在する場合は、それに対処できます。


アップデート:

わかりました、ここにいくつかのコードがあります。現在、メッセージは問題なくコピーされますが、アーカイブサーバー上の既存のメッセージが複製されます。

import imaplib
import sys

#copy from
f_server = 'some.secret.ip.address'
f_username = 'j@example.com'
f_password = 'password'
f_box_name = 'Sent Messages'

#copy to
t_server = 'archive.server.i.p'
t_username = 'username'
t_password = 'password'
t_box_name = 'test'

To = imaplib.IMAP4(t_server) 
To.login(t_username, t_password)
print 'Logged into mail server'

From = imaplib.IMAP4(f_server)
From.login(f_username, f_password)
print 'Logged into archive'

From.select(f_box_name)  #open box which will have its contents copied
print 'Fetching messages...'
typ, data = From.search(None, 'ALL')  #get all messages in the box
msgs = data[0].split()

sys.stdout.write(" ".join(['Copying', str(len(msgs)), 'messages']))

for num in msgs: #iterate over each messages id number
    typ, data = From.fetch(num, '(RFC822)')
    sys.stdout.write('.')
    To.append(t_box_name, None, None, data[0][1]) #add a copy of the message to the archive box specified above

sys.stdout.write('\n')

try:
    From.close()
From.logout()

try:
    To.close()
To.logout()

いくつかの情報源:
Doug Hellmanのブログ:imaplib-IMAP4クライアントライブラリ
Tyler Lesmannのブログ:Pythonとimaplibを使用したIMAPメールボックスのコピー

私はまだする必要があります:

  • ライブサーバー上のメッセージを削除/消去します
  • 重複をコピーしない(実際には、コピー後にオリジナルを削除することで修正されますが...)
  • エラートラップ

アップデート2:

コピー時に重複を作成しない方法について誰かが何かアイデアがありますか?(今のところ、オリジナルを削除するオプションを除いて)私はテキストを検索することを考えましたが、ネストされた応答がそれを捨てることができることに気づきました。

4

3 に答える 3

5

これが私が使用することになったものです。私はそれが完璧だとは言いません。idではなくmsg_numを使用する方法は少し危険です。しかし、これはかなり少量の移動であり、おそらく1時間(cronで)です。

import imaplib

#copy from
from_server = {'server': '1.1.1.1',
               'username': 'j@example.com',
               'password': 'pass',
               'box_names': ['Sent', 'Sent Messages']}

#copy to
to_server = {'server': '2.2.2.2',
             'username': 'archive',
             'password': 'password',
             'box_name': 'Sent'}

def connect_server(server):
    conn = imaplib.IMAP4(server['server']) 
    conn.login(server['username'], server['password'])
    print 'Logged into mail server @ %s' % server['server']
    return conn

def disconnect_server(server_conn):
    out = server_conn.logout()

if __name__ == '__main__':
    From = connect_server(from_server)
    To = connect_server(to_server)

    for box in from_server['box_names']:
        box_select = From.select(box, readonly = False)  #open box which will have its contents copied
        print 'Fetching messages from \'%s\'...' % box
        resp, items = From.search(None, 'ALL')  #get all messages in the box
        msg_nums = items[0].split()
        print '%s messages to archive' % len(msg_nums)

        for msg_num in msg_nums:
            resp, data = From.fetch(msg_num, "(FLAGS INTERNALDATE BODY.PEEK[])") # get email
            message = data[0][1] 
            flags = imaplib.ParseFlags(data[0][0]) # get flags
            flag_str = " ".join(flags)
            date = imaplib.Time2Internaldate(imaplib.Internaldate2tuple(data[0][0])) #get date
            copy_result = To.append(to_server['box_name'], flag_str, date, message) # copy to archive

            if copy_result[0] == 'OK': 
                del_msg = From.store(msg_num, '+FLAGS', '\\Deleted') # mark for deletion

        ex = From.expunge() # delete marked
        print 'expunge status: %s' % ex[0]
        if not ex[1][0]: # result can be ['OK', [None]] if no messages need to be deleted
            print 'expunge count: 0'
        else:
            print 'expunge count: %s' % len(ex[1])

    disconnect_server(From)
    disconnect_server(To)
于 2015-02-26T17:23:07.603 に答える
1

処理しているメッセージの量はわかりませんが、各メッセージからを抽出し、それMessage-IDを使用して重複しているかどうかを確認できます。メッセージを移動する準備をするたびに、ターゲットサーバー上にすでに存在するIDのリストを生成するか、アーカイブ時にIDを単純なデータベースに追加します。

ルックアップが高すぎる場合など、追加のメッセージプロパティで絞り込み、Date不要になった古いリストを削除することができます。

于 2011-11-02T20:49:53.933 に答える
0

おそらく遅すぎてOPに役立たないかもしれませんが、うまくいけば、これからフォローしている人には役立つでしょう。

これは一般的な要件のように見えます。おそらく、カスタムコーディングを行うべきではありません。

おそらく、すべてのコピーをアーカイブに送信するように構成されたMTAを使用することと、IMAPサーバーにデータを送信することをお勧めします。これを設定するのが難しい場合は、アーカイブを管理するサードパーティのサービスを使用して、既存のメールサーバーにメールを転送することを検討してください。

IMAPからコピーしてこれを本当に実行したい場合は、offlineimapを確認することをお勧めします。

本当に自分でやりたい場合は、すでに見たメッセージを追跡する方法は、Message-IDヘッダーを使用することです。

于 2015-08-21T13:22:46.670 に答える