smtpx.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import email
  2. from email.header import decode_header
  3. from data import dataInstance
  4. def decode_str(s):
  5. value, charset = decode_header(s)[0]
  6. if charset:
  7. value = value.decode(charset)
  8. return value
  9. def guess_charset(msg):
  10. charset = msg.get_charset()
  11. if charset is None:
  12. content_type = msg.get('Content-Type', '').lower()
  13. pos = content_type.find('charset=')
  14. if pos >= 0:
  15. charset = content_type[pos + 8:].strip()
  16. return charset
  17. def print_part(msg):
  18. rs = ""
  19. content_type = msg.get_content_type()
  20. if content_type == 'text/plain' or content_type == 'text/html':
  21. content = msg.get_payload(decode=True)
  22. charset = guess_charset(msg)
  23. if charset:
  24. content = content.decode(charset)
  25. rs = rs + str(content)
  26. else:
  27. rs = rs + str(content_type)
  28. return rs
  29. def print_info(msg):
  30. rs = ""
  31. if (msg.is_multipart()):
  32. parts = msg.get_payload()
  33. for n, part in enumerate(parts):
  34. if part.is_multipart():
  35. rs = rs + print_info(part)
  36. else:
  37. rs = rs + print_part(part)
  38. else:
  39. return print_part(msg)
  40. return rs
  41. class CrazySrvHandler:
  42. dao = dataInstance
  43. async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
  44. envelope.rcpt_tos.append(address)
  45. return '250 OK'
  46. async def handle_DATA(self, server, session, envelope):
  47. mail_from = envelope.mail_from
  48. rcpt_tos = envelope.rcpt_tos
  49. message = email.message_from_bytes(envelope.content)
  50. content = print_info(message)
  51. subject = decode_str(message['Subject'])
  52. obj = {
  53. "from": mail_from,
  54. "to": rcpt_tos,
  55. "subject": subject,
  56. "content": content
  57. }
  58. self.dao.store_msg(obj)
  59. print("success record msg:" + mail_from + "->" + str(rcpt_tos) + "|" + str(subject))
  60. return '250 Message accepted for delivery'