2011-08-11 22 views
3

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

今日、私はスクリプトを書くことを尋ねられ、定期的に(おそらくcrontabを使用して)送信されたすべてのメッセージを取得し、それらをアーカイブに移動します。

私は、サーバーにアクセスして突っ込むためのSSLまたはtelnetの例を調べました。しかし、私はこれをスクリプト化するための最善の方法やIMAP環境内のファイルを移動する方法を知らない。

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


更新:

[OK]を、ここでいくつかのコードです。現在のところ、メッセージは正常にコピーされますが、既存のメッセージはアーカイブサーバーに複製されます。

import imaplib 
import sys 

#copy from 
f_server = 'some.secret.ip.address' 
f_username = '[email protected]' 
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's Blog: imaplib - IMAP4 Client Library
Tyler Lesmann's Blog: Copying IMAP Mailboxes with Python and imaplib

は、私はまだ行う必要があります。

  • 削除/実際にこれは次のようになります(重複をコピーしない
  • ライブサーバー上のメッセージを抹消しますコピー後に原稿を削除して修正しましたが...)
  • アップデート2

をトラップ

  • エラー:

    誰でもコピーするときに複製を作成しない方法上の任意のアイデアがありますか? (現在はオリジナルを削除するオプションを除いて)テキストを検索することを考えましたが、ネストされた返信はそれを捨てることができました。

  • +0

    rsyncはあるシステムから別のシステムにコピーするためのオプションですか? –

    答えて

    3

    ここで私は使い終わった。私はそれが完全であると主張していない、それはmsg_numを使用し、IDは少し危険です。しかし、これはかなり低い音量の動きで、たぶん数時間(cronで)です。

    import imaplib 
    
    #copy from 
    from_server = {'server': '1.1.1.1', 
           'username': '[email protected]', 
           '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) 
    
    0

    あなたが扱っているメッセージの量はわかりませんが、それぞれからMessage-IDを抽出し、それを使用して重複しているかどうかを調べることができます。メッセージを移動する準備ができるたびに、ターゲットサーバー上のIDのリストを生成するか、アーカイブされたときに単純なデータベースに追加します。

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

    0

    OPに役立つには余りにも遅いかもしれませんが、後に続く人にはうまくいけばいいと思います。

    これは一般的な要件のようです。カスタムコーディングは何もしないでください。

    アーカイブのすべてをコピーしてIMAPサーバーに送信するように設定されたMTAを使用する方がよいでしょう。これをセットアップすることが難しい場合は、アーカイブを管理するサードパーティのサービスを使用し、既存のメールサーバーにメールを転送することを検討してください。

    本当にIMAPからコピーする場合は、offlineimapをお勧めします。

    あなたが実際にやりたければ、既に見たメッセージを追跡する方法は、Message-IDヘッダーを使用することです。

    関連する問題