如何在几个不同的线程中为用户设置一个邮箱解析器?每个用户有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家公司要解析。如何为用户的所有操作设置一封全局邮件?
答案 0 :(得分:1)
对于多个会话使用相同的IMAP连接并没有多大意义,因为只有一个套接字连接和一个服务器端上下文。如果一个线程问一个邮箱1,第二个线程问一个邮箱2,则服务器将依次选择两个邮箱,并保留在最后一个邮箱中。
如果两个线程同时从同一个套接字中读取,则不涉及竞争条件:每个线程将仅获得准随机部分数据,而另一部分将被另一个线程读取。抱歉,这是不可能的。