This repository has been archived by the owner on Dec 6, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
recv_info.py
183 lines (158 loc) · 6.76 KB
/
recv_info.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# -*- coding: utf-8 -*-
"""
从邮件接收用户信息,可以选择存入指定队列
基于MikeCrm 的表单
@File: recv_info.py
@Author: still_night
@Contact:still_night@163.com
@Date: 2017/6/16
@Time: 13:28
@License: GPL
"""
from __future__ import unicode_literals
import const
import getpass, sys, email, re, time
import imapclient
from lxml import etree
from io import StringIO
from backports import ssl
import send_mail
# import database
import const
from log import logging
class Mailbox():
"""IMAP邮箱功能"""
def __init__(self, queue=None):
self.context = imapclient.create_default_context()
self.context.check_hostname = False
self.context.verify_mode = ssl.CERT_NONE
self.queue = queue
self.login()
def login(self, username=const.IMAPUSERNAME, password=const.IMAPPASSWORD, hostname=const.IMAPHOST):
"""登录IMAP"""
self.username = username
self.password = password
while True:
try:
self.server = imapclient.IMAPClient(hostname, use_uid=True, ssl=True, ssl_context=self.context)
self.server.login(self.username, self.password)
except (imapclient.IMAPClient.Error, const.SocketError, ssl.core.SSLZeroReturnError), e:
logging.error("IMAP登录失败 %s" % e)
time.sleep(10)
else:
break
def recv(self, parser):
"""接收邮件,使用parser函数解析有价值信息 处理,保存 """
result = self.server.search('UNSEEN')
msgdict = self.server.fetch(result, ['BODY.PEEK[]'])
for message_id, message in msgdict.items():
e = email.message_from_string(message['BODY[]'])
subject = email.Header.decode_header(email.Header.Header(e.get("subject")))[0][0]
sender = email.utils.parseaddr(e.get("from"))[1]
maintype = e.get_content_maintype()
if maintype == 'multipart':
for part in e.get_payload():
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
elif maintype == 'text':
mail_content = e.get_payload(decode=True).strip()
mail_content = mail_content.decode('utf-8')
# logging.debug(mail_content)
if self.save(mail_content, parser):
""" 调用 parser函数解析有价值信息,并调用save保存"""
self.server.set_flags(message_id, [imapclient.SEEN])
def __parser_order_info(self, content):
"""用户订单 解析器"""
info = {}
parser = etree.HTMLParser()
tree = etree.parse(StringIO(content), parser)
# result = etree.tostring(tree.getroot(), pretty_print=True, method="html")
root = tree.getroot()
mailbody = root.xpath('//tr[@class="mk_mailBody"]/td/table')[0]
info['form_title'] = mailbody.xpath("tr/td/p[2]/span")[0].text.strip() # 表单名
info['form_id'] = int(mailbody.xpath("tr[2]/td/table/tr/td[1]/table/tr/td[1]/span")[0].text[1:]) # 序号 '#21'
info['submit_date'] = mailbody.xpath("tr[2]/td/table/tr/td[1]/table/tr/td[4]/span")[
0].text.strip() # 提交时间 '2017-05-19 13:34:43'
info['order_id'] = mailbody.xpath("tr[3]/td/table/tr/td[1]/table/tr/td[1]/p")[0].text.strip().split(u"\uff1a")[
1] # 订单号 麦客订单号:IFP-CN101-1705190004110819
info['payment_id'] = \
mailbody.xpath("tr[3]/td/table/tr/td[1]/table/tr/td/p[2]")[0].text.strip().split(u"\uff1a")[
1] # 支付交易号 支付平台交易号:2017051921001004380237658492
info['price'] = float(mailbody.xpath("tr[3]/td/table/tr[3]/td/p/span[2]")[0].text[2:]) # 价格
info['student_id'] = mailbody.xpath("tr[4]/td/table/tr[1]/td[2]")[0].text.strip() # 学号
info['passwd'] = mailbody.xpath("tr[4]/td/table/tr[2]/td[2]")[0].text.strip()
info['email'] = mailbody.xpath("tr[4]/td/table/tr[3]/td[2]/div/p")[0].text.strip()
return info
def __parser_work_order_info(self, content):
"""工单解析器"""
info = {}
parser = etree.HTMLParser()
tree = etree.parse(StringIO(content), parser)
# result = etree.tostring(tree.getroot(), pretty_print=True, method="html")
root = tree.getroot()
valuetable = root.xpath('/html/body/table/tr/td/table/tr[2]/td/table/tr[3]/td/table')[0]
info['student_id'] = valuetable.xpath("tr[1]/td[2]")[0].text.strip()
info['passwd'] = valuetable.xpath("tr[2]/td[2]")[0].text.strip()
info['email'] = valuetable.xpath("tr[3]/td[2]/div/p")[0].text.strip()
return info
def save(self, content, parser):
"""保存并存入队列"""
info = parser(content)
logging.info("从邮件获取到学号:" + info['student_id'])
if self.queue:
logging.debug("学号存入队列" + info['student_id'])
self.queue.put(info)
return True
def receive_payment(self):
"""接收订单"""
logging.debug("接收payment")
self.server.select_folder(const.PAYMENT_DIR)
self.recv(self.__parser_order_info)
def receive_workorder(self):
"""接收工单"""
logging.debug("接收work_order")
self.server.select_folder(const.WORKORDER_DIR)
self.recv(self.__parser_work_order_info)
def loop_recv(self):
while True:
self.recv()
time.sleep(10)
def recv_to_queue(self, q=None):
"""接收并存入队列,外部调用最佳"""
if not q:
q = self.queue
logging.debug("开始接收邮件")
retry = 5
while retry > 0:
retry -= 1
try:
self.receive_workorder()
self.receive_payment()
except (imapclient.IMAPClient.Error, const.SocketError, ssl.core.SSLZeroReturnError), e:
logging.error("receive mail error : %s %s %s" % (const.IMAPUSERNAME, const.IMAPHOST, e))
try:
self.server.logout()
except (imapclient.IMAPClient.Error, const.SocketError), e2:
logging.error("imap logout error %s" % e2.message)
time.sleep(20)
self.login()
else:
break
# logging.debug("等待下一次接收邮件")
def loop_recv_to_queue(q):
"""持续接收"""
m = Mailbox()
logging.info("imap 登录成功")
while True:
m.recv_to_queue(q)
time.sleep(10)
def main():
import Queue
q = Queue.Queue()
m = Mailbox(queue=q)
m.recv_to_queue()
if not q.empty():
print q.get()
# recv_to_queue(q)
if __name__ == '__main__':
main()