refactor(notifications): unify email sending via _send_email; standardize crawler notifications\n\n- Extract _send_email and have send_email/send_custom_email share it\n- BaseCrawler: centralize _send_notifications and add _build_email hook\n- BarronsCrawler: override _build_email to keep original subject/body\n- OpenInsiderCrawler: remove custom _send_notifications, add _build_email\n- /notify_test: use crawler _build_email + send_custom_email for emails
This commit is contained in:
@@ -95,9 +95,11 @@ class BaseCrawler(ABC):
|
||||
|
||||
def _send_notifications(self, items: List[Dict]) -> None:
|
||||
sent = False
|
||||
# Build subject/body via hook for consistency across crawlers
|
||||
subject, body = self._build_email(items)
|
||||
if self.config.email:
|
||||
try:
|
||||
notif.send_email(items, self.config.email)
|
||||
notif.send_custom_email(subject, body, self.config.email)
|
||||
sent = True
|
||||
except Exception as e:
|
||||
self.logger.error(f"電子郵件通知失敗: {e}")
|
||||
@@ -116,6 +118,23 @@ class BaseCrawler(ABC):
|
||||
if sent:
|
||||
self.stats['last_notification'] = datetime.now().isoformat()
|
||||
|
||||
def _build_email(self, items: List[Dict]):
|
||||
"""Construct a generic email subject and body.
|
||||
|
||||
Subclasses can override to customize content/format.
|
||||
"""
|
||||
subject = f"{self.name} ({len(items)}條)"
|
||||
lines = []
|
||||
for pick in items:
|
||||
line = f"📊 {pick.get('title','').strip()}\n"
|
||||
if pick.get('link'):
|
||||
line += f"🔗 {pick['link']}\n"
|
||||
line += f"🕒 {pick.get('scraped_at', datetime.now().isoformat())}\n"
|
||||
line += "-" * 60 + "\n"
|
||||
lines.append(line)
|
||||
body = f"發現 {len(items)} 條新內容:\n\n" + "".join(lines)
|
||||
return subject, body
|
||||
|
||||
# --- Run loop ---
|
||||
def _signal_handler(self, signum, frame):
|
||||
self.logger.info("收到停止信號,正在關閉...")
|
||||
|
Reference in New Issue
Block a user