8080
8181import logging
8282from pathlib import Path
83- from typing import Any , Dict , List , Optional
83+ from typing import Any , Dict , List , Optional , Union
8484
8585try :
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