简体   繁体   English

将消息从一个 IMAP 服务器移动到另一个的脚本

[英]Script to move messages from one IMAP server to another

Our office uses 2 IMAP servers for e-mail, one is the incoming server and holds the recent e-mails and the other is an archive server.我们的办公室使用两台 IMAP 服务器来处理电子邮件,一台是接收服务器,保存最近的电子邮件,另一台是存档服务器。 We mainly use Outlook 2010 and our current process is to periodically drag sent messages from the incoming server to the archive.我们主要使用 Outlook 2010 并且我们当前的过程是定期将发送的消息从传入服务器拖到存档中。

Today I was asked into looking into writing a script and that would periodically (probably using crontab) grab all sent messages and move them to archive.今天我被要求研究编写一个脚本,它会定期(可能使用 crontab)抓取所有发送的消息并将它们移动到存档。

I've looked into some example of SSL or telnet to access the server and poke around.我研究了一些 SSL 或 telnet 的示例来访问服务器并四处寻找。 However I don't know the best way to script this or how to move files cross server within the IMAP environment.但是,我不知道编写此脚本的最佳方式或如何在 IMAP 环境中跨服务器移动文件。

What's the best way to accomplish this?实现这一目标的最佳方法是什么? I'd prefer to use Python just from comfort level, but if there is already an existing solution in another language, I could deal with it.我更喜欢使用 Python 只是从舒适的角度来看,但如果已经有另一种语言的现有解决方案,我可以处理它。


Update:更新:

Ok, here's some code.好的,这里有一些代码。 Currently It copies the messages just fine, however, it will duplicate exisiting messages on the archive server.目前它可以很好地复制邮件,但是,它将复制存档服务器上的现有邮件。

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()

Some sources:一些资料来源:
Doug Hellman's Blog: imaplib - IMAP4 Client Library Doug Hellman 的博客:imaplib - IMAP4 客户端库
Tyler Lesmann's Blog: Copying IMAP Mailboxes with Python and imaplib Tyler Lesmann 的博客:使用 Python 和 imaplib 复制 IMAP 邮箱

I still need to:我仍然需要:

  • delete/expunge messages on the live server删除/删除实时服务器上的消息
  • not copy duplicates (actually this would be fixed by deleting originals after copying, but...)不复制副本(实际上这可以通过在复制后删除原件来解决,但是......)
  • error trapping错误捕获

Update 2:更新 2:

Anyone have any ideas on how to not create duplicates when copying?有人对复制时如何不创建重复项有任何想法吗? (excluding the option of deleting originals, for now) I thought about searching text, but realized nested replies could throw that off. (暂时不包括删除原件的选项)我考虑过搜索文本,但意识到嵌套回复可能会将其排除在外。

Here's what I ended up using.这是我最终使用的。 I don't claim that it's perfect, the way it uses msg_num and not id is a little risky.我并不声称它是完美的,它使用 msg_num 而不是 id 的方式有点冒险。 But this is fairly low volume moves, maybe a couple an hour (on cron).但这是相当低的交易量,可能一个小时(在 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)

I'm not sure what volume of messages you're dealing with, but you could extract the Message-ID from each one and use that to find out if it's a duplicate.我不确定您正在处理多少消息,但您可以从每条消息中提取Message-ID并使用它来确定它是否是重复的。 Either generate a list of IDs already on the target server each time you prepare to move messages, or add them to a simple database as they are archived.每次准备移动消息时,生成目标服务器上已有的 ID 列表,或者在归档时将它们添加到简单的数据库中。

You could narrow things down by an additional message property like Date if the lookups are too expensive, then drop the older lists when you no longer need them.如果查找过于昂贵,您可以通过附加消息属性(如Date )来缩小范围,然后在不再需要旧列表时删除它们。

Presumably too late to be helpful to the OP, but hopefully useful for anyone following along after now.大概为时已晚,无法对 OP 有所帮助,但希望对以后跟随的任何人都有用。

This looks like a generic requirement.这看起来像一个通用要求。 You probably shouldn't be custom coding anything.您可能不应该自定义编码任何东西。

You would probably be better off using an MTA configured to send copies of everything to an archive as well as sending stuff to your IMAP server.您最好使用配置为将所有内容的副本发送到存档以及将内容发送到 IMAP 服务器的 MTA。 If this is hard for you to set up, consider using a third party service, who would manage your archives, and forward mail on to your existing mail server.如果这对您来说很难设置,请考虑使用第三方服务,该服务将管理您的档案,并将邮件转发到您现有的邮件服务器。

If you really do want to do this by copying from IMAP, I'd suggest looking at offlineimap .如果您确实想通过从 IMAP 复制来做到这一点,我建议您查看offlineimap

If you really do want to do it yourself, the way to track the messages you've already seen is by using the Message-ID header.如果您确实想自己做,那么跟踪您已经看到的消息的方法是使用 Message-ID header。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Python imaplib将消息从一台imap服务器复制到另一台imap服务器? - How to copy a message from one imap server to another imap server using Python imaplib? 如何从IMAP服务器获取最近的10条消息? - How to fetch last 10 messages from IMAP server? 在python中使用IMAP4将邮件从一个邮箱移动到另一个邮箱 - Use IMAP4 in python to move mail from a mailbox to another mailbox 如何将iCalendear条目从一台服务器移动到另一台服务器? - How do I move iCalendear entries from one server to another? Python脚本将数据从一台MySQL服务器传输到另一台MySQL服务器 - Python script to transfer data from one MySQL server to another one 使用IMAP将gmail中的电子邮件从一个标签转移到python中的另一个标签 - Transferring emails in gmail from one label to another in python using IMAP 如何将参数从服务器上的一个python脚本传递给另一个? - How to pass arguments from one python script on the server to another? 如何创建powershell脚本以将数千个日志文件从一个位置移动到另一个位置? - How can i create a powershell script to move thousands of log files from one location to another? 如何将Python脚本从一个子包移动到另一个目录/包,保持向后兼容性 - How to move a Python script from one subpackage to another directory/package, maintaining backwards compatibility 尝试使用 Python 脚本将数据从一个 Azure Blob 存储移动到另一个 - Trying to move data from one Azure Blob Storage to another using a Python script
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM