[Add] Email engine for sending email message.
This commit is contained in:
parent
6e1d90b327
commit
242a97a2b2
@ -5,6 +5,10 @@ import logging
|
||||
from datetime import datetime
|
||||
from abc import ABC
|
||||
from typing import Any
|
||||
from threading import Thread
|
||||
from queue import Queue, Empty
|
||||
import smtplib
|
||||
from email.message import EmailMessage
|
||||
|
||||
from vnpy.event import EventEngine, Event
|
||||
|
||||
@ -62,6 +66,7 @@ class MainEngine:
|
||||
"""
|
||||
self.add_engine(LogEngine)
|
||||
self.add_engine(OmsEngine)
|
||||
self.add_engine(EmailEngine)
|
||||
|
||||
def write_log(self, msg: str):
|
||||
"""
|
||||
@ -135,6 +140,9 @@ class MainEngine:
|
||||
Make sure every gateway and app is closed properly before
|
||||
programme exit.
|
||||
"""
|
||||
for engine in self.engines.values():
|
||||
engine.close()
|
||||
|
||||
for gateway in self.gateways.values():
|
||||
gateway.close()
|
||||
|
||||
@ -157,6 +165,10 @@ class BaseEngine(ABC):
|
||||
self.event_engine = event_engine
|
||||
self.engine_name = engine_name
|
||||
|
||||
def close(self):
|
||||
""""""
|
||||
pass
|
||||
|
||||
|
||||
class LogEngine(BaseEngine):
|
||||
"""
|
||||
@ -397,4 +409,67 @@ class OmsEngine(BaseEngine):
|
||||
order for order in self.active_orders.values()
|
||||
if order.vt_symbol == vt_symbol
|
||||
]
|
||||
return active_orders
|
||||
return active_orders
|
||||
|
||||
|
||||
class EmailEngine(BaseEngine):
|
||||
"""
|
||||
Provides email sending function for VN Trader.
|
||||
"""
|
||||
|
||||
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||
""""""
|
||||
super(EmailEngine, self).__init__(main_engine, event_engine, "email")
|
||||
|
||||
self.thread = Thread(target=self.run)
|
||||
self.queue = Queue()
|
||||
self.active = False
|
||||
|
||||
self.main_engine.send_email = self.send_email
|
||||
|
||||
def send_email(self, subject: str, content: str, receiver: str = ""):
|
||||
""""""
|
||||
# Start email engine when sending first email.
|
||||
if not self.active:
|
||||
self.start()
|
||||
|
||||
# Use default receiver if not specified.
|
||||
if not receiver:
|
||||
receiver = SETTINGS["email.receiver"]
|
||||
|
||||
msg = EmailMessage()
|
||||
msg["From"] = SETTINGS["email.sender"]
|
||||
msg["To"] = SETTINGS["email.receiver"]
|
||||
msg["Subject"] = subject
|
||||
msg.set_content(content)
|
||||
|
||||
self.queue.put(msg)
|
||||
|
||||
def run(self):
|
||||
""""""
|
||||
while self.active:
|
||||
try:
|
||||
msg = self.queue.get(block=True, timeout=1)
|
||||
|
||||
with smtplib.SMTP_SSL(SETTINGS["email.server"],
|
||||
SETTINGS["email.port"]) as smtp:
|
||||
smtp.login(
|
||||
SETTINGS["email.username"],
|
||||
SETTINGS["email.password"]
|
||||
)
|
||||
smtp.send_message(msg)
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
""""""
|
||||
self.active = True
|
||||
self.thread.start()
|
||||
|
||||
def close(self):
|
||||
""""""
|
||||
if not self.active:
|
||||
return
|
||||
|
||||
self.active = False
|
||||
self.thread.join()
|
||||
|
@ -7,9 +7,14 @@ from logging import CRITICAL
|
||||
SETTINGS = {
|
||||
"font.family": "Arial",
|
||||
"font.size": 12,
|
||||
|
||||
"log.active": True,
|
||||
"log.level": CRITICAL,
|
||||
"log.console": True,
|
||||
"log.file": True
|
||||
"log.file": True,
|
||||
"email.server": "smtp.qq.com",
|
||||
"email.port": 465,
|
||||
"email.username": "",
|
||||
"email.password": "",
|
||||
"email.sender": "",
|
||||
"email.receiver": ""
|
||||
}
|
BIN
vnpy/trader/ui/ico/email.ico
Normal file
BIN
vnpy/trader/ui/ico/email.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
@ -103,6 +103,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.restore_window_setting
|
||||
)
|
||||
|
||||
self.add_menu_action(
|
||||
help_menu,
|
||||
"测试邮件",
|
||||
"email.ico",
|
||||
self.send_test_email
|
||||
)
|
||||
|
||||
self.add_menu_action(
|
||||
help_menu,
|
||||
"关于",
|
||||
@ -218,4 +225,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
Restore window to default setting.
|
||||
"""
|
||||
self.load_window_setting("default")
|
||||
self.showMaximized()
|
||||
self.showMaximized()
|
||||
|
||||
def send_test_email(self):
|
||||
"""
|
||||
Sending a test email.
|
||||
"""
|
||||
self.main_engine.send_email("VN Trader", "testing")
|
||||
|
@ -310,6 +310,11 @@ class TickMonitor(BaseMonitor):
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"exchange": {
|
||||
"display": "交易所",
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"last_price": {
|
||||
"display": "最新价",
|
||||
"cell": BaseCell,
|
||||
@ -419,6 +424,11 @@ class TradeMonitor(BaseMonitor):
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"exchange": {
|
||||
"display": "交易所",
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"direction": {
|
||||
"display": "方向",
|
||||
"cell": DirectionCell,
|
||||
@ -466,6 +476,11 @@ class OrderMonitor(BaseMonitor):
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"exchange": {
|
||||
"display": "交易所",
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"direction": {
|
||||
"display": "方向",
|
||||
"cell": DirectionCell,
|
||||
@ -540,6 +555,11 @@ class PositionMonitor(BaseMonitor):
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"exchange": {
|
||||
"display": "交易所",
|
||||
"cell": BaseCell,
|
||||
"update": False
|
||||
},
|
||||
"direction": {
|
||||
"display": "方向",
|
||||
"cell": DirectionCell,
|
||||
|
Loading…
Reference in New Issue
Block a user