如何为几个线程设置一个imaplib邮箱实例?

时间:2019-05-17 09:15:13

标签: python python-3.x imaplib

如何在几个不同的线程中为用户设置一个邮箱解析器?每个用户有2个或更多应分析其邮件的公司。在我的例子中,我总是有错误。

class User():
    services = {'company1': 'STOPED',
                'company2': 'STOPED'}

    def __init__(self, user_settings):
        self.user_name = user_settings['User']
        self.user_settings = user_settings

        self.global_mailbox = None

    def company1(self):
        service_name = 'company1'
        settings = self.user_settings['Company1']
        gb_mail = False

        def mailbox_check(mailbox):
            nonlocal settings, service_name

            mailbox.noop()
            status, mails = mailbox.search(None, '(UNSEEN)', '(FROM "company1@cmp.com")')

            ....

        if not settings['Mail Login']:
            if self.global_mailbox:
                mailbox = self.global_mailbox
                gb_mail = True
            else:
                self.SET_GLOBAL_MAIL()
                if not self.global_mailbox:
                    return
                else:
                    mailbox = self.global_mailbox
        else:
            mail_host = 'imap.{0}'.format(settings['Mail Login'].split('@')[-1])
            mail_login = settings['Mail Login']
            mail_password = settings['Mail Password']

            mailbox = imaplib.IMAP4_SSL(mail_host)
            mailbox.sock.settimeout(43200)

            mailbox.login(mail_login, mail_password)
            mailbox.select('INBOX')
            gb_mail = False

         while self.services[service_name] != 'STOPED':
             time.sleep(5)
             new_orders = self.mailbox_check(mailbox)
             if new_orders:
                 action()    
             if self.services[service_name] == 'STOPED':
                 break

    def company2(self):
        service_name = 'company2'
        settings = self.user_settings['Company2']
        gb_mail = False

        def mailbox_check(mailbox):
            nonlocal settings, service_name

            mailbox.noop()
            status, mails = mailbox.search(None, '(UNSEEN)', '(FROM "company2@cmp.com")')

            ....

        if not settings['Mail Login']:
            if self.global_mailbox:
                mailbox = self.global_mailbox
                gb_mail = True
            else:
                self.SET_GLOBAL_MAIL()
                if not self.global_mailbox:
                    return
                else:
                    mailbox = self.global_mailbox
        else:
            mail_host = 'imap.{0}'.format(settings['Mail Login'].split('@')[-1])
            mail_login = settings['Mail Login']
            mail_password = settings['Mail Password']

            mailbox = imaplib.IMAP4_SSL(mail_host)
            mailbox.sock.settimeout(43200)

            mailbox.login(mail_login, mail_password)
            mailbox.select('INBOX')
            gb_mail = False

         while self.services[service_name] != 'STOPED':
             time.sleep(5)
             new_orders = self.mailbox_check(mailbox)
             if new_orders:
                 action()    
             if self.services[service_name] == 'STOPED':
                 break

def SET_GLOBAL_MAIL(self)
    try:
        gb_mail = self.user_settings['Global Mail']
        mail_host = 'imap.{0}'.format(gb_mail['Login'].split('@')[-1])
        mail_login = gb_mail['Login']
        mail_password = gb_mail['Password']
        mailbox = imaplib.IMAP4_SSL(mail_host)
        mailbox.sock.settimeout(43200)
        mailbox.login(mail_login, mail_password)
        mailbox.select('INBOX')
        self.global_mailbox = mailbox
    except:
        self.global_mailbox = None
        pass

def START_ALL(self):
    self.SET_GLOBAL_MAIL()
    for service in self.services.keys():
        self.services[service] = 'RUNNING'
        threading.Thread(target=lambda: self.__getattribute__(service)(), name='{0} [{1} service thread]'.format(self.user_name, service), daemon=True).start()

>>>user = User(settings)
>>>user.START_ALL()

几秒钟后,我得到了这些错误:

  

imaplib.IMAP4.abort:命令:SEARCH =>套接字错误:EOF

     

imaplib.IMAP4.abort:套接字错误:EOF

     

imaplib.IMAP4.abort:命令:NOOP =>套接字错误:EOF

     

imaplib.IMAP4.abort:套接字错误:[WinError 10014]系统检测到   尝试在调用中使用指针参数时无效的指针地址

     

ssl.SSLError:[SSL:SSLV3_ALERT_BAD_RECORD_MAC] sslv3警报错误记录mac(_ssl.c:2273)

如果我为每个线程创建一个新的imap会话,一切正常,但是GMAIL对于通过imap同时连接有一个限制。用户可能有超过15家公司要解析。如何为用户的所有操作设置一封全局邮件?

1 个答案:

答案 0 :(得分:1)

对于多个会话使用相同的IMAP连接并没有多大意义,因为只有一个套接字连接和一个服务器端上下文。如果一个线程问一个邮箱1,第二个线程问一个邮箱2,则服务器将依次选择两个邮箱,并保留在最后一个邮箱中。

如果两个线程同时从同一个套接字中读取,则不涉及竞争条件:每个线程将仅获得准随机部分数据,而另一部分将被另一个线程读取。抱歉,这是不可能的。