【问题标题】:How to set one instance of imaplib mailbox for few threads?如何为少数线程设置一个 imaplib 邮箱实例?
【发布时间】:2019-05-17 17:36:42
【问题描述】:

如何在几个不同的线程中为用户设置一个邮箱解析器?每个用户有 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 家公司进行解析。如何为用户的所有操作设置一封全局邮件?

【问题讨论】:

    标签: python python-3.x imaplib


    【解决方案1】:

    对多个对话使用同一个 IMAP 连接并没有什么意义,因为只有一个套接字连接和一个服务器端上下文。如果一个线程请求mailbox1,第二个线程请求mailbox2,服务器将依次选择2个邮箱,并停留在最后一个。

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

    【讨论】:

      猜你喜欢
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2022-11-08
      相关资源
      最近更新 更多