115 lines
3.0 KiB
Python
115 lines
3.0 KiB
Python
import re
|
||
from random import randint
|
||
import poplib
|
||
from appPublic.log import debug
|
||
from appPublic.dictObject import DictObject
|
||
from appPublic.timeUtils import curDateString, timestampstr
|
||
from email.parser import Parser
|
||
from email.header import decode_header
|
||
from email.utils import parseaddr
|
||
from ..core import Gateway
|
||
|
||
|
||
def guess_charset(msg):
|
||
charset = msg.get_charset()
|
||
if charset is None:
|
||
content_type = msg.get('Content-Type', '').lower()
|
||
pos = content_type.find('charset=')
|
||
if pos >= 0:
|
||
charset = content_type[pos + 8:].strip()
|
||
return charset
|
||
|
||
class EmailClient:
|
||
def __init__(self, pop3_server, emailaddress, password):
|
||
self.client = poplib.POP3(pop3_server)
|
||
self.client.user(emailaddress)
|
||
self.client.pass_(password)
|
||
|
||
def stat(self):
|
||
return self.client.stat()
|
||
|
||
def mail_list(self):
|
||
resp, mails, octets = self.client.list()
|
||
|
||
def get_mail(self, index):
|
||
resp, lines, octets = self.client.retr(index)
|
||
debug(f'{resp=}, {octets=}')
|
||
msg_content = b'\r\n'.join(lines).decode('utf-8')
|
||
msg = Parser().parsestr(msg_content)
|
||
mail = {
|
||
"mailfrom": msg.get('From'),
|
||
"mailto": msg.get('To'),
|
||
"subject": msg.get('Subject'),
|
||
"body": self.get_body(msg)
|
||
}
|
||
return DictObject(**mail)
|
||
|
||
def get_body(self, msg):
|
||
if msg.is_multipart():
|
||
parts = msg.get_payload()
|
||
content = ''
|
||
for part in parts:
|
||
content += self.get_body(part)
|
||
return content
|
||
else:
|
||
content_type = msg.get_content_type()
|
||
content = msg.get_payload(decode=True)
|
||
charset = guess_charset(msg)
|
||
if charset:
|
||
content = content.decode(charset)
|
||
else:
|
||
content = content.decode('utf-8')
|
||
return content
|
||
|
||
class TransferPay(Gateway):
|
||
def __init__(self, from_mail="", pop3server="", email="", password=""):
|
||
self.from_email = from_email
|
||
self.pop3server = pop3server
|
||
self.email = email
|
||
self.password = password
|
||
self.running = False
|
||
|
||
async def create_payment(self, payload: Dict[str, Any]) -> str:
|
||
"""
|
||
返回一个可以在 H5 里直接重定向的支付宝支付 URL
|
||
"""
|
||
ns = {
|
||
"id": payload["out_trade_no"],
|
||
"customerid": payload['customerid'],
|
||
"amount": payload["amount"],
|
||
"tcode": self.gen_mailcode(),
|
||
"curdate": curDateString(),
|
||
"curtime": timestampstr(),
|
||
"status": '0'
|
||
}
|
||
return
|
||
|
||
def get_transfer_data(self, mail):
|
||
assert mail.mailfrom == '95555@message.cmbchina.com'
|
||
assert mail.mailto == self.email
|
||
assert mail.body.startswith('动账业务通知')
|
||
ns = DictObject()
|
||
match = re.search(r'交易金额\s*[::]?\s*(\d+(?:\.\d+)?)', mail.body)
|
||
if match:
|
||
ns.amount = float(match.group(1))
|
||
p = r'摘要[::]\s*(\d{7})(?!\d)'
|
||
match = re.search(r'摘要[::]\s*(\d{7})(?!\d)', mail.body)
|
||
if match:
|
||
ns.code = match.group(1)
|
||
assert ns.amount
|
||
assert ns.code
|
||
return ns
|
||
|
||
def gen_mailcode(self):
|
||
c = '1'
|
||
for range(6):
|
||
c += randint(0,9)
|
||
return c
|
||
|
||
def run(self):
|
||
self.running = True
|
||
while self.running:
|
||
ec = EmailClient(self.pop3server, self.email, self.password)
|
||
mail = ec.get_mail(1)
|
||
|