email.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from time import strftime, localtime
  2. import mimetypes
  3. from email.mime.multipart import MIMEMultipart
  4. from email.mime.application import MIMEApplication
  5. from email.mime.audio import MIMEAudio
  6. from email.mime.image import MIMEImage
  7. from email.mime.message import MIMEMessage
  8. from email.mime.text import MIMEText
  9. from email.header import Header
  10. from email.utils import parseaddr, formataddr
  11. class Email:
  12. @staticmethod
  13. def _format_addr(s):
  14. name, addr = parseaddr(s)
  15. return formataddr((Header(name, 'utf-8').encode(), addr))
  16. def __init__(self, from_addr: tuple, subject: str, to_addr=None, cc_addr=None, bcc_addr=None, subtype="mixed"):
  17. self.from_addr = from_addr
  18. self.subject = subject
  19. self.to_addr = to_addr if to_addr else []
  20. self.cc_addr = cc_addr if cc_addr else []
  21. self.bcc_addr = bcc_addr if bcc_addr else []
  22. self.text = []
  23. self.html = []
  24. self.file = []
  25. self.subtype = subtype
  26. def add_text(self, text: str):
  27. self.text.append(text)
  28. def add_text_from_file(self, path):
  29. with open(path, "r", encoding="utf-8") as f:
  30. self.add_text(f.read())
  31. def add_html(self, html: str):
  32. self.html.append(html)
  33. def add_html_from_file(self, path):
  34. with open(path, "r", encoding="utf-8") as f:
  35. self.add_html(f.read())
  36. def add_bytes(self, filename: str, file: bytes):
  37. self.file.append((filename, file))
  38. def add_from_file(self, filename, path):
  39. with open(path, "rb") as f:
  40. self.add_bytes(filename, f.read())
  41. def add_to_addr(self, name, email):
  42. self.to_addr.append((name, email))
  43. def add_cc_addr(self, name, email):
  44. self.cc_addr.append((name, email))
  45. def add_bcc_addr(self, name, email):
  46. self.bcc_addr.append((name, email))
  47. def as_msg(self):
  48. msg = MIMEMultipart(_subtype=self.subtype)
  49. msg['From'] = self._format_addr(f"{self.from_addr[0]}<{self.from_addr[1]}>")
  50. msg['To'] = ",".join([self._format_addr(f"{i[0]}<{i[1]}>") for i in self.to_addr])
  51. msg['Cc'] = ",".join([self._format_addr(f"{i[0]}<{i[1]}>") for i in self.cc_addr])
  52. msg['Subject'] = Header(self.subject, 'utf-8').encode()
  53. msg["Date"] = Header(strftime('%a, %d %b %Y %H:%M:%S %z', localtime())).encode()
  54. for i in self.text:
  55. msg.attach(MIMEText(i, 'plain', 'utf-8'))
  56. for i in self.html:
  57. msg.attach(MIMEText(i, 'html', 'utf-8'))
  58. for filename, i in self.file:
  59. content_type = mimetypes.guess_type(filename)[0]
  60. if not content_type:
  61. content_type = "application/octet-stream"
  62. main_type, sub_type = content_type.split("/")
  63. if main_type == "application":
  64. msg_file = MIMEApplication(i, _subtype=sub_type)
  65. elif main_type == "audio":
  66. msg_file = MIMEAudio(i, _subtype=sub_type)
  67. elif main_type == "image":
  68. msg_file = MIMEImage(i, _subtype=sub_type)
  69. elif main_type == "message":
  70. msg_file = MIMEMessage(i, _subtype=sub_type)
  71. elif main_type == "text":
  72. msg_file = MIMEText(i, _subtype=sub_type)
  73. else:
  74. msg_file = MIMEApplication(i)
  75. msg_file.add_header('Content-Disposition', 'attachment', filename=filename)
  76. msg.attach(msg_file)
  77. return msg
  78. def as_string(self):
  79. return self.as_msg().as_string()