main.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. import os
  2. import sys
  3. from PyQt5.QtWidgets import QMessageBox
  4. from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QWidgetItem
  5. from PyQt5.QtCore import Qt, QMetaObject, Q_ARG
  6. import sqlite3
  7. import threading
  8. import time
  9. from datetime import datetime, timedelta
  10. from extract_and_save import run
  11. import logging
  12. from logging.handlers import TimedRotatingFileHandler
  13. # 创建文件夹【日志log】
  14. if not os.path.exists('日志log'):
  15. os.makedirs('日志log')
  16. # class CustomTimedRotatingFileHandler(TimedRotatingFileHandler):
  17. # def doRollover(self):
  18. # # 获取当前时间
  19. # current_time = datetime.now() - timedelta(days=1)
  20. # # 获取当前日期
  21. # current_date = current_time.strftime('%Y-%m-%d')
  22. # # 获取当前日志文件名
  23. # base_filename = os.path.splitext(self.baseFilename)[0]
  24. # extension = os.path.splitext(self.baseFilename)[1]
  25. # # 构建新的日志文件名
  26. # new_filename = f"{base_filename}_{current_date}{extension}"
  27. # # 如果当前日志文件存在,则重命名
  28. # if os.path.exists(self.baseFilename):
  29. # # 添加一个短暂的延迟
  30. # # time.sleep(1)
  31. # try:
  32. # os.rename(self.baseFilename, new_filename)
  33. # except PermissionError as e:
  34. # logger.error(f"无法重命名日志文件: {e}")
  35. # # 调用父类的doRollover方法
  36. # super().doRollover()
  37. # 自定义 namer 函数,用于去掉日期后缀
  38. def namer(default_name):
  39. # 计算前一天的时间
  40. current_time = datetime.now() - timedelta(days=1)
  41. current_date = current_time.strftime('%Y-%m-%d')
  42. log_file = f'日志log/日志.{current_date}.txt'
  43. # 默认情况下,轮转后的文件名会添加日期后缀,这里去掉后缀
  44. return os.path.join(os.path.dirname(default_name), os.path.basename(log_file))
  45. # 创建一个选品logger
  46. logger = logging.getLogger('detailLogger')
  47. logger.setLevel(logging.DEBUG) # 设置日志级别
  48. # 创建一个handler,用于写入文件,并根据时间自动轮换日志文件
  49. detail_handler = TimedRotatingFileHandler('日志log/日志.txt', when='midnight', interval=1, backupCount=30,encoding='utf-8')
  50. detail_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
  51. # 设置 namer 函数
  52. detail_handler.namer = namer
  53. # detail_handler.suffix = "%Y%m%d.txt"
  54. # 添加handler到logger
  55. logger.addHandler(detail_handler)
  56. # 配置日志记录器
  57. logger_cmd = logging.getLogger('logger_cmd')
  58. logger_cmd.setLevel(logging.DEBUG)
  59. # 配置控制台处理器和格式器
  60. console_handler = logging.StreamHandler()
  61. console_handler.setLevel(logging.DEBUG)
  62. formatter = logging.Formatter('[%(asctime)s] %(message)s')
  63. console_handler.setFormatter(formatter)
  64. # 将处理器添加到记录器中
  65. logger_cmd.addHandler(console_handler)
  66. class MailSenderApp(QWidget):
  67. def __init__(self):
  68. super().__init__()
  69. self.initUI()
  70. def initUI(self):
  71. self.setWindowTitle('Mail Sender')
  72. self.setGeometry(100, 100, 200, 200)
  73. main_layout = QVBoxLayout()
  74. main_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 设置垂直布局居中
  75. # 创建标签和输入框,并将它们放在一个水平布局中
  76. def create_row(label_text):
  77. layout = QHBoxLayout()
  78. label = QLabel(label_text, self)
  79. edit = QLineEdit(self)
  80. edit.setFixedWidth(300) # 设置输入框的固定宽度为500
  81. layout.addWidget(label)
  82. layout.addWidget(edit)
  83. return layout, edit
  84. self.phone_layout, self.phone_edit = create_row('手机号码:')
  85. self.session_layout, self.session_edit = create_row('Session:')
  86. self.sender_email_layout, self.sender_email_edit = create_row('发送人邮箱号:')
  87. self.receiver_email_layout, self.receiver_email_edit = create_row('接受人邮箱号:')
  88. self.smtp_proxy_layout, self.smtp_proxy_edit = create_row('邮箱SMTP代理:')
  89. self.smtp_account_layout, self.smtp_account_edit = create_row('SMTP账号:')
  90. self.smtp_password_layout, self.smtp_password_edit = create_row('SMTP密码:')
  91. self.email_alias_layout, self.email_alias_edit = create_row('邮箱特殊代号:')
  92. self.scan_interval_layout, self.scan_interval_edit = create_row('扫描间隔时间:')
  93. self.error_count_layout, self.error_count_edit = create_row('异常次数\n(超出则退出扫描):')
  94. self.success_scan_interval_layout, self.success_scan_interval_edit = create_row('没有短信验证时\n中间间隔时间(秒):')
  95. self.you_scan_interval_layout, self.you_scan_interval_edit = create_row('有短信验证时\n等待时间(秒):')
  96. # 将水平布局添加到垂直布局中
  97. for layout in [
  98. self.phone_layout,
  99. self.session_layout,
  100. self.sender_email_layout,
  101. self.receiver_email_layout,
  102. self.smtp_proxy_layout,
  103. self.smtp_account_layout,
  104. self.smtp_password_layout,
  105. self.email_alias_layout,
  106. self.scan_interval_layout,
  107. self.error_count_layout,
  108. self.success_scan_interval_layout,
  109. self.you_scan_interval_layout
  110. ]:
  111. main_layout.addLayout(layout)
  112. # 创建按钮
  113. self.save_button = QPushButton('保存', self)
  114. self.save_button.clicked.connect(self.save_settings)
  115. self.start_scan_button = QPushButton('开启扫描', self)
  116. self.start_scan_button.clicked.connect(self.start_scan)
  117. self.stop_scan_button = QPushButton('关闭扫描', self)
  118. self.stop_scan_button.clicked.connect(self.stop_scan)
  119. # 创建一个水平布局来放置按钮
  120. button_layout = QHBoxLayout()
  121. button_layout.addWidget(self.save_button)
  122. button_layout.addWidget(self.start_scan_button)
  123. button_layout.addWidget(self.stop_scan_button)
  124. # 将按钮布局添加到主布局中
  125. main_layout.addLayout(button_layout)
  126. # 设置主窗口的布局
  127. container = QWidget()
  128. container.setLayout(main_layout)
  129. container.setMaximumWidth(300) # 设置容器的最大宽度为1000
  130. main_window_layout = QVBoxLayout()
  131. main_window_layout.addWidget(container, alignment=Qt.AlignmentFlag.AlignLeft)
  132. self.setLayout(main_window_layout)
  133. # 从数据库中读取数据并填充到输入框中
  134. self.load_settings()
  135. def save_settings(self):
  136. phone = self.phone_edit.text()
  137. session = self.session_edit.text()
  138. sender_email = self.sender_email_edit.text()
  139. receiver_email = self.receiver_email_edit.text()
  140. smtp_proxy = self.smtp_proxy_edit.text()
  141. smtp_account = self.smtp_account_edit.text()
  142. smtp_password = self.smtp_password_edit.text()
  143. email_alias = self.email_alias_edit.text()
  144. scan_interval = self.scan_interval_edit.text()
  145. error_count = self.error_count_edit.text()
  146. success_scan_interval = self.success_scan_interval_edit.text()
  147. you_scan_interval = self.you_scan_interval_edit.text()
  148. # 保存到SQLite数据库
  149. conn = sqlite3.connect('settings.db')
  150. cursor = conn.cursor()
  151. cursor.execute('''CREATE TABLE IF NOT EXISTS settings (
  152. phone TEXT,
  153. session TEXT,
  154. sender_email TEXT,
  155. receiver_email TEXT,
  156. smtp_proxy TEXT,
  157. smtp_account TEXT,
  158. smtp_password TEXT,
  159. email_alias TEXT,
  160. scan_interval TEXT,
  161. error_count TEXT,
  162. success_scan_interval TEXT,
  163. you_scan_interval TEXT
  164. )''')
  165. cursor.execute('''DELETE FROM settings''') # 删除现有数据
  166. cursor.execute('''INSERT INTO settings (
  167. phone,
  168. session,
  169. sender_email,
  170. receiver_email,
  171. smtp_proxy,
  172. smtp_account,
  173. smtp_password,
  174. email_alias,
  175. scan_interval,
  176. error_count,success_scan_interval,you_scan_interval
  177. ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?)''',
  178. (phone, session, sender_email, receiver_email, smtp_proxy, smtp_account, smtp_password, email_alias, scan_interval,error_count,success_scan_interval,you_scan_interval))
  179. conn.commit()
  180. conn.close()
  181. # 提示保存成功
  182. QMessageBox.information(self, '保存成功', '设置已保存到数据库。')
  183. def load_settings(self):
  184. # 从SQLite数据库中读取数据
  185. conn = sqlite3.connect('settings.db')
  186. cursor = conn.cursor()
  187. cursor.execute('''CREATE TABLE IF NOT EXISTS settings (
  188. phone TEXT,
  189. session TEXT,
  190. sender_email TEXT,
  191. receiver_email TEXT,
  192. smtp_proxy TEXT,
  193. smtp_account TEXT,
  194. smtp_password TEXT,
  195. email_alias TEXT,
  196. scan_interval TEXT,
  197. error_count TEXT,
  198. success_scan_interval TEXT,
  199. you_scan_interval TEXT
  200. )''')
  201. cursor.execute('''SELECT * FROM settings''')
  202. row = cursor.fetchone()
  203. conn.close()
  204. if row:
  205. self.phone_edit.setText(row[0])
  206. self.session_edit.setText(row[1])
  207. self.sender_email_edit.setText(row[2])
  208. self.receiver_email_edit.setText(row[3])
  209. self.smtp_proxy_edit.setText(row[4])
  210. self.smtp_account_edit.setText(row[5])
  211. self.smtp_password_edit.setText(row[6])
  212. self.email_alias_edit.setText(row[7])
  213. self.scan_interval_edit.setText(row[8])
  214. self.error_count_edit.setText(row[9])
  215. self.success_scan_interval_edit.setText(row[10])
  216. self.you_scan_interval_edit.setText(row[11])
  217. def start_scan(self):
  218. # 实现开启扫描的逻辑
  219. # 获取session的值
  220. session = self.session_edit.text()
  221. # 获取发送人邮箱号
  222. sender_email = self.sender_email_edit.text()
  223. # 获取接受人邮箱号
  224. receiver_email = self.receiver_email_edit.text()
  225. smtp_proxy = self.smtp_proxy_edit.text()
  226. smtp_account = self.smtp_account_edit.text()
  227. smtp_password = self.smtp_password_edit.text()
  228. email_alias = self.email_alias_edit.text()
  229. # 获取间隔时间
  230. scan_interval = self.scan_interval_edit.text()
  231. # 异常次数
  232. error_count = self.error_count_edit.text()
  233. # 获取间隔时间
  234. success_scan_interval = self.success_scan_interval_edit.text()
  235. # 获取间隔时间
  236. you_scan_interval = self.you_scan_interval_edit.text()
  237. logger.info(f'session:{session}')
  238. logger.info(f'发送人邮箱号:sender_email:{sender_email}')
  239. logger.info(f'接收人邮箱号:receiver_email:{receiver_email}')
  240. logger.info(f'smtp代理:smtp_proxy:{smtp_proxy}')
  241. logger.info(f'smtp账号:smtp_account:{smtp_account}')
  242. logger.info(f'smtp密码:smtp_password:{smtp_password}')
  243. logger.info(f'邮箱特殊代号:email_alias:{email_alias}')
  244. logger.info(f'间隔时长(秒):scan_interval:{scan_interval}')
  245. logger.info(f'异常次数:error_count:{int(error_count)}')
  246. logger.info(f'没有短信验证中间间隔时长(秒):success_scan_interval:{success_scan_interval}')
  247. logger.info(f'有短信验证等待间隔时长(秒):you_scan_interval:{you_scan_interval}')
  248. logger_cmd.info(f'session:{session}')
  249. logger_cmd.info(f'发送人邮箱号:sender_email:{sender_email}')
  250. logger_cmd.info(f'接收人邮箱号:receiver_email:{receiver_email}')
  251. logger_cmd.info(f'smtp代理:smtp_proxy:{smtp_proxy}')
  252. logger_cmd.info(f'smtp账号:smtp_account:{smtp_account}')
  253. logger_cmd.info(f'smtp密码:smtp_password:{smtp_password}')
  254. logger_cmd.info(f'邮箱特殊代号:email_alias:{email_alias}')
  255. logger_cmd.info(f'间隔时长(秒):scan_interval:{scan_interval}')
  256. logger_cmd.info(f'异常次数:error_count:{int(error_count)}')
  257. logger_cmd.info(f'没有短信验证中间间隔时长(秒):success_scan_interval:{success_scan_interval}')
  258. logger_cmd.info(f'有短信验证等待间隔时长(秒):you_scan_interval:{you_scan_interval}')
  259. # self.start_scan_button 无法点击
  260. self.start_scan_button.setEnabled(False)
  261. global stop_flag
  262. stop_flag = False
  263. # 清空表
  264. logger.info("清空表sms_codes")
  265. conn = sqlite3.connect('settings.db')
  266. cursor = conn.cursor()
  267. cursor.execute('''CREATE TABLE IF NOT EXISTS sms_codes (edit_content TEXT, send_content_short TEXT)''')
  268. cursor.execute('delete from sms_codes')
  269. conn.commit()
  270. conn.close()
  271. # 创建一个线程,并启动线程,线程每间隔10时间执行一下extract_and_save.py中的run方法
  272. thread = threading.Thread(target=thread_function, args=(session, sender_email, receiver_email, smtp_proxy, smtp_account, smtp_password, email_alias,scan_interval,error_count,success_scan_interval,you_scan_interval,self))
  273. thread.start()
  274. # thread_function(session, sender_email, receiver_email, smtp_proxy, smtp_account, smtp_password, email_alias,scan_interval,error_count,success_scan_interval,you_scan_interval,self)
  275. logger.info("扫描已开启")
  276. logger_cmd.info(f'扫描已开启')
  277. QMessageBox.information(self, '扫描已开启', '扫描已开启。')
  278. def stop_scan(self):
  279. # 获取全局的变量 stop_flag
  280. global stop_flag
  281. stop_flag = True
  282. logger.info("扫描关闭中,请等待")
  283. logger_cmd.info(f'扫描关闭中,请等待')
  284. # QMessageBox.information(self, '扫描关闭中,请等待', '扫描关闭中,请等待。')
  285. def thread_function(session, sender_email, receiver_email, smtp_proxy, smtp_account, smtp_password, email_alias,scan_interval,error_count,success_scan_interval,you_scan_interval,self):
  286. #获取 全局的变量 stop_flag
  287. global stop_flag
  288. stop_back_flag = 'success'
  289. iconCount = 0
  290. while True:
  291. session = self.session_edit.text()
  292. logger.info(f'扫描:session = {session}')
  293. # stop_flag 为true 则跳出
  294. if stop_flag:
  295. logger.info(f'扫描已成功关闭')
  296. logger_cmd.info(f'扫描已成功关闭')
  297. # self.start_scan_button.setEnabled(True)
  298. QMetaObject.invokeMethod(self.start_scan_button, "setEnabled", Qt.QueuedConnection, Q_ARG(bool, True))
  299. return
  300. stop1_flag = run(
  301. session=session,
  302. sender_email=sender_email,
  303. receiver_email=receiver_email,
  304. smtp_proxy=smtp_proxy,
  305. smtp_account=smtp_account,
  306. smtp_password=smtp_password,
  307. email_alias=email_alias,
  308. error_count=error_count,
  309. you_scan_interval=you_scan_interval,
  310. logger=logger
  311. )
  312. logger.info(f'没有短信验证标志: {stop1_flag}')
  313. if stop1_flag == 'stop':
  314. logger_cmd.info(f'异常{error_count}次,暂停!')
  315. # self.start_scan_button.setEnabled(True)
  316. QMetaObject.invokeMethod(self.start_scan_button, "setEnabled", Qt.QueuedConnection, Q_ARG(bool, True))
  317. return
  318. elif stop1_flag == 'success':
  319. if stop_back_flag == 'error not stop':
  320. logger_cmd.info(f'第{iconCount}次无验证,等待{float(success_scan_interval)}秒!')
  321. logger.info(f"上一轮有短信验证,本次没有短信验证时,间隔{float(success_scan_interval)}秒")
  322. time.sleep(float(success_scan_interval))
  323. else:
  324. logger.info(f"间隔{float(scan_interval)}秒")
  325. logger_cmd.info(f'无验证,等待{float(scan_interval)}秒!')
  326. time.sleep(float(scan_interval))
  327. iconCount = 0
  328. else:
  329. iconCount += 1
  330. logger.info(f"间隔{float(scan_interval)}秒")
  331. time.sleep(float(scan_interval))
  332. stop_back_flag = stop1_flag
  333. if __name__ == "__main__":
  334. app = QApplication(sys.argv)
  335. ex = MailSenderApp()
  336. ex.show()
  337. sys.exit(app.exec())