Skip to content

Commit de0b48a

Browse files
committed
♻️ refactor similar functionality for update and add events.
#2
1 parent 8ea26bf commit de0b48a

1 file changed

Lines changed: 161 additions & 99 deletions

File tree

tools/developer_tools/bely-mqtt-message-broker/examples/handlers/apprise_smart_notification_handler.py

Lines changed: 161 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080

8181
import logging
8282
from pathlib import Path
83-
from typing import Any, Dict, List, Optional
83+
from typing import Any, Dict, List, Optional, Union
8484

8585
try:
8686
import apprise
@@ -272,25 +272,7 @@ async def handle_log_entry_add(self, event: LogEntryAddEvent) -> None:
272272
event: The log entry add event
273273
"""
274274
try:
275-
# Don't notify the creator
276-
if (
277-
event.event_triggered_by_username
278-
== event.parent_log_document_info.created_by_username
279-
):
280-
return
281-
282-
# Check if we should notify about new entries
283-
owner_username = event.parent_log_document_info.owner_username
284-
if not self._should_notify(owner_username, "new_entries"):
285-
return
286-
287-
# Build notification
288-
title = f"New Log Entry in {event.parent_log_document_info.name}"
289-
body = self._format_entry_added_body(event)
290-
291-
# Send notification
292-
await self._send_notification(owner_username, title, body)
293-
275+
await self._handle_add_event(event, is_reply=False)
294276
except Exception as e:
295277
self.logger.error(f"Error processing log entry add: {e}", exc_info=True)
296278

@@ -306,35 +288,7 @@ async def handle_log_entry_update(self, event: LogEntryUpdateEvent) -> None:
306288
event: The log entry update event
307289
"""
308290
try:
309-
notifications_sent = []
310-
311-
# 1. Check if we should notify the original entry creator (own_entry_edits)
312-
creator_username = event.log_info.entered_by_username
313-
if event.event_triggered_by_username != creator_username and self._should_notify(
314-
creator_username, "own_entry_edits"
315-
):
316-
# Build notification for the entry creator
317-
title = f"Your Log Entry Was Edited: {event.parent_log_document_info.name}"
318-
body = self._format_own_entry_edited_body(event)
319-
320-
# Send notification
321-
await self._send_notification(creator_username, title, body)
322-
notifications_sent.append(creator_username)
323-
324-
# 2. Check if document owners should be notified about a change in log entry.
325-
owner_username = event.parent_log_document_info.owner_username
326-
if (
327-
event.event_triggered_by_username != owner_username
328-
and owner_username not in notifications_sent # Avoid duplicate notifications
329-
and self._should_notify(owner_username, "entry_updates")
330-
):
331-
# Build notification for document owner
332-
title = f"Log Entry Updated: {event.parent_log_document_info.name}"
333-
body = self._format_entry_updated_body(event)
334-
335-
# Send notification
336-
await self._send_notification(owner_username, title, body)
337-
291+
await self._handle_update_event(event, is_reply=False)
338292
except Exception as e:
339293
self.logger.error(f"Error processing log entry update: {e}", exc_info=True)
340294

@@ -350,31 +304,7 @@ async def handle_log_entry_reply_add(self, event: LogEntryReplyAddEvent) -> None
350304
event: The log entry reply add event
351305
"""
352306
try:
353-
notifications_sent = []
354-
355-
# 1. Notify the original entry creator (existing logic)
356-
creator_username = event.parent_log_info.entered_by_username
357-
if event.event_triggered_by_username != creator_username and self._should_notify(
358-
creator_username, "entry_replies"
359-
):
360-
361-
title = f"Reply to Your Log Entry in {event.parent_log_document_info.name}"
362-
body = self._format_reply_added_body(event)
363-
await self._send_notification(creator_username, title, body)
364-
notifications_sent.append(creator_username)
365-
366-
# 2. Notify the document owner about new replies in their document
367-
owner_username = event.parent_log_document_info.owner_username
368-
if (
369-
event.event_triggered_by_username != owner_username
370-
and owner_username not in notifications_sent # Avoid duplicate notifications
371-
and self._should_notify(owner_username, "document_replies")
372-
):
373-
374-
title = f"New Reply in Your Document: {event.parent_log_document_info.name}"
375-
body = self._format_document_reply_body(event)
376-
await self._send_notification(owner_username, title, body)
377-
307+
await self._handle_add_event(event, is_reply=True)
378308
except Exception as e:
379309
self.logger.error(f"Error processing log entry reply add: {e}", exc_info=True)
380310

@@ -390,38 +320,170 @@ async def handle_log_entry_reply_update(self, event: LogEntryReplyUpdateEvent) -
390320
event: The log entry reply update event
391321
"""
392322
try:
393-
notifications_sent = []
323+
await self._handle_update_event(event, is_reply=True)
324+
except Exception as e:
325+
self.logger.error(f"Error processing log entry reply update: {e}", exc_info=True)
394326

395-
# 1. Check if we should notify the original entry creator (own_entry_edits)
396-
# This uses own_entry_edits since it's about modifications to content related to the user's entry
397-
creator_username = event.parent_log_info.entered_by_username
398-
if event.event_triggered_by_username != creator_username and self._should_notify(
399-
creator_username, "own_entry_edits"
400-
):
401-
# Build notification for the entry creator
402-
title = f"Reply Updated on Your Log Entry in {event.parent_log_document_info.name}"
403-
body = self._format_own_reply_updated_body(event)
327+
async def _handle_add_event(
328+
self, event: Union[LogEntryAddEvent, LogEntryReplyAddEvent], is_reply: bool = False
329+
) -> None:
330+
"""
331+
Unified handler for add events (entry or reply adds).
332+
333+
Args:
334+
event: The add event
335+
is_reply: Whether this is a reply add
336+
"""
337+
notification_configs = []
338+
339+
if is_reply:
340+
# Cast for type checking
341+
reply_event = event # type: LogEntryReplyAddEvent
342+
343+
# Notify the original entry creator
344+
creator_username = reply_event.parent_log_info.entered_by_username
345+
notification_configs.append(
346+
{
347+
"username": creator_username,
348+
"notification_type": "entry_replies",
349+
"title": f"Reply to Your Log Entry in {reply_event.parent_log_document_info.name}",
350+
"body": self._format_reply_added_body(reply_event),
351+
"context": None,
352+
}
353+
)
404354

405-
# Send notification
406-
await self._send_notification(creator_username, title, body)
407-
notifications_sent.append(creator_username)
355+
# Notify the document owner
356+
owner_username = reply_event.parent_log_document_info.owner_username
357+
notification_configs.append(
358+
{
359+
"username": owner_username,
360+
"notification_type": "document_replies",
361+
"title": f"New Reply in Your Document: {reply_event.parent_log_document_info.name}",
362+
"body": self._format_document_reply_body(reply_event),
363+
"context": "document_owner",
364+
}
365+
)
366+
else:
367+
# Cast for type checking
368+
entry_event = event # type: LogEntryAddEvent
408369

409-
# 2. Check if Document owners should be notified.
410-
owner_username = event.parent_log_document_info.owner_username
370+
# Don't notify if the creator is also the document creator
411371
if (
412-
event.event_triggered_by_username != owner_username
413-
and owner_username not in notifications_sent # Avoid duplicate notifications
414-
and self._should_notify(owner_username, "entry_replies")
372+
entry_event.event_triggered_by_username
373+
== entry_event.parent_log_document_info.created_by_username
415374
):
416-
# Build notification for document owner
417-
title = f"Reply Updated in {event.parent_log_document_info.name}"
418-
body = self._format_reply_updated_body(event)
375+
return
419376

420-
# Send notification
421-
await self._send_notification(owner_username, title, body)
377+
# Notify document owner about new entry
378+
owner_username = entry_event.parent_log_document_info.owner_username
379+
notification_configs.append(
380+
{
381+
"username": owner_username,
382+
"notification_type": "new_entries",
383+
"title": f"New Log Entry in {entry_event.parent_log_document_info.name}",
384+
"body": self._format_entry_added_body(entry_event),
385+
"context": None,
386+
}
387+
)
422388

423-
except Exception as e:
424-
self.logger.error(f"Error processing log entry reply update: {e}", exc_info=True)
389+
await self._process_notifications(event, notification_configs)
390+
391+
async def _handle_update_event(
392+
self, event: Union[LogEntryUpdateEvent, LogEntryReplyUpdateEvent], is_reply: bool = False
393+
) -> None:
394+
"""
395+
Unified handler for update events (entry or reply updates).
396+
397+
Args:
398+
event: The update event
399+
is_reply: Whether this is a reply update
400+
"""
401+
notification_configs = []
402+
403+
if is_reply:
404+
# Cast for type checking
405+
reply_event = event # type: LogEntryReplyUpdateEvent
406+
407+
creator_username = reply_event.parent_log_info.entered_by_username
408+
own_edit_title = (
409+
f"Reply Updated on Your Log Entry in {reply_event.parent_log_document_info.name}"
410+
)
411+
own_edit_body = self._format_own_reply_updated_body(reply_event)
412+
owner_title = f"Reply Updated in {reply_event.parent_log_document_info.name}"
413+
owner_body = self._format_reply_updated_body(reply_event)
414+
owner_notification_type = "entry_replies"
415+
else:
416+
# Cast for type checking
417+
entry_event = event # type: LogEntryUpdateEvent
418+
419+
creator_username = entry_event.log_info.entered_by_username
420+
own_edit_title = (
421+
f"Your Log Entry Was Edited: {entry_event.parent_log_document_info.name}"
422+
)
423+
own_edit_body = self._format_own_entry_edited_body(entry_event)
424+
owner_title = f"Log Entry Updated: {entry_event.parent_log_document_info.name}"
425+
owner_body = self._format_entry_updated_body(entry_event)
426+
owner_notification_type = "entry_updates"
427+
428+
# Config for notifying the original creator
429+
notification_configs.append(
430+
{
431+
"username": creator_username,
432+
"notification_type": "own_entry_edits",
433+
"title": own_edit_title,
434+
"body": own_edit_body,
435+
"context": "own_entry_edit" if not is_reply else "own_reply_update",
436+
}
437+
)
438+
439+
# Config for notifying the document owner
440+
owner_username = event.parent_log_document_info.owner_username
441+
notification_configs.append(
442+
{
443+
"username": owner_username,
444+
"notification_type": owner_notification_type,
445+
"title": owner_title,
446+
"body": owner_body,
447+
"context": None,
448+
}
449+
)
450+
451+
await self._process_notifications(event, notification_configs)
452+
453+
async def _process_notifications(
454+
self, event: Any, notification_configs: List[Dict[str, Any]]
455+
) -> None:
456+
"""
457+
Process and send notifications based on configuration.
458+
459+
Args:
460+
event: The event to process
461+
notification_configs: List of dicts with:
462+
- username: User to notify
463+
- notification_type: Type of notification setting to check
464+
- title: Notification title
465+
- body: Notification body
466+
- context: Optional context for trigger description
467+
"""
468+
notifications_sent = []
469+
470+
for config in notification_configs:
471+
username = config["username"]
472+
notification_type = config["notification_type"]
473+
474+
# Skip if already notified or shouldn't notify
475+
if username in notifications_sent:
476+
continue
477+
if not self._should_notify(username, notification_type):
478+
continue
479+
if event.event_triggered_by_username == username:
480+
continue
481+
482+
title = config["title"]
483+
body = config["body"]
484+
485+
await self._send_notification(username, title, body)
486+
notifications_sent.append(username)
425487

426488
async def _handle_log_reaction_event(self, event: LogReactionEventBase) -> None:
427489
"""

0 commit comments

Comments
 (0)