|
|
|
|
@ -18,6 +18,7 @@ def static_vars(**kwargs):
|
|
|
|
|
return decorate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 检查邮件地址是否合法
|
|
|
|
|
@static_vars(
|
|
|
|
|
matcher=re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"))
|
|
|
|
|
def validate_email(email: str):
|
|
|
|
|
@ -28,11 +29,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(MainWindow, self).__init__()
|
|
|
|
|
self.setupUi(self)
|
|
|
|
|
# 设置Ui
|
|
|
|
|
self.btnSendMail.clicked.connect(self.send_mail)
|
|
|
|
|
self.txtFrom.textChanged.connect(self.mail_changed)
|
|
|
|
|
|
|
|
|
|
def mail_changed(self):
|
|
|
|
|
pass
|
|
|
|
|
# 绑定点击事件
|
|
|
|
|
|
|
|
|
|
def send_mail(self):
|
|
|
|
|
servaddr = self.txtServer.text()
|
|
|
|
|
@ -41,30 +40,38 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
|
|
receiver = self.txtTo.text()
|
|
|
|
|
subjects = self.txtSubject.text()
|
|
|
|
|
contents = self.txtContent.toPlainText()
|
|
|
|
|
# 获取必要信息
|
|
|
|
|
if not validate_email(username) or not validate_email(receiver):
|
|
|
|
|
QMessageBox.critical(self, "Invalid address", "Invalid From or To")
|
|
|
|
|
return
|
|
|
|
|
# 检查发件人与收件人邮箱是否合法
|
|
|
|
|
lw = LogWindow(
|
|
|
|
|
(servaddr, username, password, receiver, subjects, contents))
|
|
|
|
|
lw.exec()
|
|
|
|
|
# 启动发送窗口
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LogWindow(QDialog, Ui_Dialog):
|
|
|
|
|
def __init__(self, data):
|
|
|
|
|
super(LogWindow, self).__init__()
|
|
|
|
|
self.setupUi(self)
|
|
|
|
|
# 设置Ui
|
|
|
|
|
threading.Thread(target=self.do_update_status, args=(data, )).start()
|
|
|
|
|
# 启动实际发送线程
|
|
|
|
|
|
|
|
|
|
def do_update_status(self, data):
|
|
|
|
|
(servaddr, username, password, receiver, subjects, contents) = data
|
|
|
|
|
ss = socket(AF_INET, SOCK_STREAM)
|
|
|
|
|
# 接收数据
|
|
|
|
|
try:
|
|
|
|
|
ss.connect((servaddr, 25))
|
|
|
|
|
# 尝试连接
|
|
|
|
|
except Exception:
|
|
|
|
|
QMessageBox.critical(self, "Connection Failed",
|
|
|
|
|
"Failed connecting smtp server")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 与服务端单次交互及显示到界面
|
|
|
|
|
def comm(msg: str):
|
|
|
|
|
msg += "\r\n"
|
|
|
|
|
ss.sendall(msg.encode())
|
|
|
|
|
@ -72,15 +79,15 @@ class LogWindow(QDialog, Ui_Dialog):
|
|
|
|
|
self.textBrowser.append("S: " + ss.recv(1 << 20).decode())
|
|
|
|
|
self.textBrowser.moveCursor(QTextCursor.End)
|
|
|
|
|
|
|
|
|
|
comm("HELO " + servaddr)
|
|
|
|
|
comm("AUTH LOGIN")
|
|
|
|
|
comm(b64encode(username.encode()).decode())
|
|
|
|
|
comm(b64encode(password.encode()).decode())
|
|
|
|
|
comm("MAIL FROM:<{}>".format(username))
|
|
|
|
|
comm("RCPT TO:<{}>".format(receiver))
|
|
|
|
|
comm("DATA")
|
|
|
|
|
comm('\r\n'.join(["Subject: " + subjects, "", contents, "."]))
|
|
|
|
|
comm("QUIT")
|
|
|
|
|
comm("HELO " + servaddr) # HELO
|
|
|
|
|
comm("AUTH LOGIN") # 现在的SMTP服务器要认证了
|
|
|
|
|
comm(b64encode(username.encode()).decode()) # 发送用户名
|
|
|
|
|
comm(b64encode(password.encode()).decode()) # 发送密码
|
|
|
|
|
comm("MAIL FROM:<{}>".format(username)) # 发件人
|
|
|
|
|
comm("RCPT TO:<{}>".format(receiver)) # 收件人
|
|
|
|
|
comm("DATA") # 开始实际数据
|
|
|
|
|
comm('\r\n'.join(["Subject: " + subjects, "", contents, "."])) # 主题与正文
|
|
|
|
|
comm("QUIT") # 结束
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|