mail.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from random import random
  4. import configparser
  5. import base64
  6. from email.MIMEMultipart import MIMEMultipart
  7. from email.MIMEText import MIMEText
  8. from email.MIMEImage import MIMEImage
  9. class MailAdress:
  10. def __init__(self,EMail:str="",Name:str=None):
  11. self._name=Name
  12. self._mail=EMail
  13. @property
  14. def Name(self):
  15. if self._name==None or self._name=="":
  16. return self._mail
  17. return self._name
  18. @Name.setter
  19. def Name(self,value):
  20. self._name = value
  21. @property
  22. def Mail(self):
  23. return self._mail
  24. @Mail.setter
  25. def Mail(self,value):
  26. self._mail = value
  27. class Attachment:
  28. def __init__(self):
  29. self._size = 0
  30. self._fileName=""
  31. self._content=""
  32. @property
  33. def Size(self) -> int:
  34. return self._size
  35. @Size.setter
  36. def Size(self,value:int):
  37. self._size = value
  38. @property
  39. def FileName(self) -> str:
  40. return self._fileName
  41. @FileName.setter
  42. def FileName(self,value:str):
  43. self._fileName = value
  44. @property
  45. def Content(self) -> str:
  46. return self._content
  47. @Content.setter
  48. def Content(self,value:str):
  49. self._content = value
  50. class Mail:
  51. def __init__(self):
  52. self._from = MailAdress()
  53. self._to = MailAdress()
  54. self._toName=""
  55. self._subject=""
  56. self._message=""
  57. self._html=""
  58. self._attachments=list[Attachment]
  59. self._messageID="" #TODO (example Microsoft: Message-Id: <4b5fad31-dcb0-4112-9a75-34bafd9addaa@az.northcentralus.unknown.microsoft.com>)
  60. self._headers=dict[str,str]
  61. self._boundary = self.CreateBoundary()
  62. @property
  63. def From(self) -> MailAdress:
  64. return self._from
  65. @property
  66. def To(self) -> MailAdress:
  67. return self._to
  68. @property
  69. def Subject(self) -> str:
  70. return self._subject
  71. @Subject.setter
  72. def Subject(self,value:str):
  73. self._subject = value
  74. @property
  75. def Message(self)->str:
  76. return self._message
  77. @Message.setter
  78. def Message(self,value:str):
  79. self._message = value
  80. @property
  81. def HTML(self)->str:
  82. return self._html
  83. @HTML.setter
  84. def HTML(self,value:str):
  85. self._html = value
  86. @property
  87. def Attachments(self)->list[Attachment]:
  88. return self._attachments
  89. @property
  90. def MessageID(self) -> str:
  91. return self._messageID
  92. @property
  93. def Headers(self) -> dict[str,str]:
  94. return self._headers
  95. def Base64_Encode(self, text:str) -> str:
  96. return base64.b64encode(text)
  97. def Base64_Decode(self, text:str) -> str:
  98. return base64.b64decode(text)
  99. def Send(self, profile:str=""):
  100. #TODO load Template - format text
  101. # Read Config and Sender-Profile
  102. configMain = configparser.ConfigParser()
  103. configMainFile="config/config.ini"
  104. configMain.read(configMainFile)
  105. deviceName=configMain["global"]["devicename"]
  106. config = configparser.ConfigParser()
  107. configFile="config/email.ini"
  108. config.read(configFile)
  109. if profile=="":
  110. if config and "general" in config and "send" in config["general"]:
  111. profile=config["general"]["send"]
  112. if profile=="":
  113. print("Failed to send E-Mail. No profile found")
  114. return
  115. if profile not in config:
  116. print(f"Profile '{profile}' not found in {configFile}")
  117. return
  118. # Read SMTP Info
  119. smtpHost=config[profile]["smtp"]
  120. smtpUser=config[profile]["login"]
  121. smtpPass=config[profile]["password"]
  122. smtpMail=config[profile]["email"]
  123. if smtpHost=="" or smtpUser=="" or smtpPass=="":
  124. print(f"Failed to load SMTP Host / Login")
  125. return
  126. # Set From / To
  127. strFrom = self.From.Name+" <"+smtpMail+">"
  128. strTo = self.To.Name+" <"+self.To.Mail+">"
  129. # Prepare E-Mail
  130. msgRoot = MIMEMultipart('related')
  131. msgRoot['Subject'] = self._subject
  132. msgRoot['From'] = strFrom
  133. msgRoot['To'] = strTo
  134. msgRoot.preamble = 'This is a multi-part message in MIME format.'
  135. msgAlternative = MIMEMultipart('alternative')
  136. msgRoot.attach(msgAlternative)
  137. msgText = MIMEText(self._message)
  138. msgAlternative.attach(msgText)
  139. msgText = MIMEText(self._html, 'html')
  140. msgAlternative.attach(msgText)
  141. #TODO add images
  142. ## HTML <img src="cid:image1">
  143. ## This example assumes the image is in the current directory
  144. #fp = open('test.jpg', 'rb')
  145. #msgImage = MIMEImage(fp.read())
  146. #fp.close()
  147. ## Define the image's ID as referenced above
  148. #msgImage.add_header('Content-ID', '<image1>')
  149. #msgRoot.attach(msgImage)
  150. #TODO add custom headers
  151. # Create SMTP Connection and send E-Mail
  152. import smtplib
  153. smtp = smtplib.SMTP()
  154. smtp.connect(smtpHost)
  155. smtp.starttls() #TODO check if TLS is working - maybe config.ini option
  156. smtp.login(smtpUser, smtpPass)
  157. smtp.sendmail(strFrom, strTo, msgRoot.as_string())
  158. smtp.quit()