You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.2 KiB
Python

import sys
import re
import threading
from base64 import b64encode
from typing import *
from socket import *
from PyQt5.Qt import *
from main_window_ui import Ui_MainWindow
from log_window_ui import Ui_Dialog
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
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):
return validate_email.matcher.fullmatch(email)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
# 设置Ui
self.btnSendMail.clicked.connect(self.send_mail)
# 绑定点击事件
def send_mail(self):
servaddr = self.txtServer.text()
username = self.txtFrom.text()
password = self.txtPassword.text()
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())
self.textBrowser.append("C: " + msg)
self.textBrowser.append("S: " + ss.recv(1 << 20).decode())
self.textBrowser.moveCursor(QTextCursor.End)
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__":
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
app.exec()