first commit
This commit is contained in:
97
notifier.py
Normal file
97
notifier.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
邮件通知模块
|
||||
"""
|
||||
|
||||
import logging
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EmailNotifier:
|
||||
def __init__(self, config):
|
||||
self.smtp_host = config['smtp_host']
|
||||
self.smtp_port = config['smtp_port']
|
||||
self.smtp_user = config['smtp_user']
|
||||
self.smtp_password = config['smtp_password']
|
||||
self.to_email = config['to_email']
|
||||
self.use_tls = config.get('use_tls', True)
|
||||
|
||||
def send(self, notifications):
|
||||
"""发送邮件通知"""
|
||||
if not notifications:
|
||||
return
|
||||
|
||||
subject = f"【通知监控】发现 {len(notifications)} 条新通知"
|
||||
|
||||
html_body = self._build_html(notifications)
|
||||
text_body = self._build_text(notifications)
|
||||
|
||||
msg = MIMEMultipart('alternative')
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = self.smtp_user
|
||||
msg['To'] = self.to_email
|
||||
|
||||
msg.attach(MIMEText(text_body, 'plain', 'utf-8'))
|
||||
msg.attach(MIMEText(html_body, 'html', 'utf-8'))
|
||||
|
||||
try:
|
||||
server = smtplib.SMTP(self.smtp_host, self.smtp_port)
|
||||
if self.use_tls:
|
||||
server.starttls()
|
||||
server.login(self.smtp_user, self.smtp_password)
|
||||
server.send_message(msg)
|
||||
server.quit()
|
||||
logger.info(f"邮件发送成功: {subject}")
|
||||
except Exception as e:
|
||||
logger.error(f"邮件发送失败: {e}")
|
||||
|
||||
def _build_html(self, notifications):
|
||||
# 按来源网站分组
|
||||
from collections import defaultdict
|
||||
by_site = defaultdict(list)
|
||||
for n in notifications:
|
||||
source = n.get('source', '未知来源')
|
||||
by_site[source].append(n)
|
||||
|
||||
html_parts = []
|
||||
for site_name, items in by_site.items():
|
||||
rows = []
|
||||
for n in items:
|
||||
date = n.get('date', '')
|
||||
rows.append(f'<tr><td><a href="{n["link"]}">{n["title"]}</a></td><td>{date}</td></tr>')
|
||||
html_parts.append(f'''
|
||||
<h3>{site_name}</h3>
|
||||
<table border="1" cellpadding="5" cellspacing="0">
|
||||
<thead><tr><th>标题</th><th>日期</th></tr></thead>
|
||||
<tbody>{''.join(rows)}</tbody>
|
||||
</table>
|
||||
''')
|
||||
|
||||
return f'''
|
||||
<html>
|
||||
<body>
|
||||
<h2>新通知 (共 {len(notifications)} 条)</h2>
|
||||
{''.join(html_parts)}
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
def _build_text(self, notifications):
|
||||
from collections import defaultdict
|
||||
by_site = defaultdict(list)
|
||||
for n in notifications:
|
||||
source = n.get('source', '未知来源')
|
||||
by_site[source].append(n)
|
||||
|
||||
lines = [f'新通知 (共 {len(notifications)} 条)\n']
|
||||
for site_name, items in by_site.items():
|
||||
lines.append(f'\n=== {site_name} ===')
|
||||
for n in items:
|
||||
date = n.get('date', '')
|
||||
lines.append(f"- {n['title']} {date}")
|
||||
lines.append(f" {n['link']}")
|
||||
return '\n'.join(lines)
|
||||
Reference in New Issue
Block a user