@ -1,7 +1,5 @@
using System.Reactive.Disposables ;
using System.Text ;
using Flurl.Http ;
using Recyclarr.Common.Extensions ;
using Recyclarr.Http ;
using Recyclarr.Notifications.Apprise ;
using Recyclarr.Notifications.Apprise.Dto ;
@ -15,38 +13,17 @@ public sealed class NotificationService(
ILogger log ,
IAppriseNotificationApiService apprise ,
ISettingsProvider settingsProvider ,
NotificationEmitter notificationEmitter ) : IDisposable
IReadOnlyCollection< IPresentableNotification > presentableNotifications )
{
private readonly Dictionary < string , List < INotificationEvent > > _events = new ( ) ;
private readonly CompositeDisposable _eventConnection = new ( ) ;
private string? _activeInstanceName ;
public void Dispose ( )
{
_eventConnection . Dispose ( ) ;
}
public void SetInstanceName ( string instanceName )
{
_activeInstanceName = instanceName ;
}
public void BeginWatchEvents ( )
{
_events . Clear ( ) ;
_eventConnection . Clear ( ) ;
_eventConnection . Add ( notificationEmitter . OnNotification . Subscribe ( x = >
{
ArgumentNullException . ThrowIfNull ( _activeInstanceName ) ;
_events . GetOrCreate ( _activeInstanceName ) . Add ( x ) ;
} ) ) ;
}
public async Task SendNotification ( bool succeeded )
{
// stop receiving events while we build the report
_eventConnection . Clear ( ) ;
// If the user didn't configure notifications, exit early and do nothing.
if ( settingsProvider . Settings . Notifications is null )
{
@ -54,12 +31,9 @@ public sealed class NotificationService(
return ;
}
var body = new StringBuilder ( ) ;
ArgumentException . ThrowIfNullOrWhiteSpace ( _activeInstanceName ) ;
foreach ( var ( instanceName , notifications ) in _events )
{
RenderInstanceEvents ( body , instanceName , notifications ) ;
}
var body = RenderInstanceEvents ( _activeInstanceName , presentableNotifications ) ;
var messageType = AppriseMessageType . Success ;
if ( ! succeeded )
@ -72,7 +46,7 @@ public sealed class NotificationService(
await apprise . Notify ( "apprise" , new AppriseNotification
{
Title = $"Recyclarr Sync {(succeeded ? " Completed " : " Failed ")}" ,
Body = body .ToString ( ) ,
Body = body ,
Type = messageType ,
Format = AppriseMessageFormat . Markdown
} ) ;
@ -83,25 +57,22 @@ public sealed class NotificationService(
}
}
private static void RenderInstanceEvents (
StringBuilder body ,
private static string RenderInstanceEvents (
string instanceName ,
IEnumerable < I NotificationEvent > notifications )
IEnumerable < I Presentable Notification> notifications )
{
body . AppendLine ( $"### Instance: `{instanceName}`\n" ) ;
var groupedEvents = notifications
. GroupBy ( x = > x . Category )
. ToDictionary ( x = > x . Key , x = > x . ToList ( ) ) ;
var body = new StringBuilder ( $"### Instance: `{instanceName}`\n" ) ;
foreach ( var ( category , events ) in groupedEvents )
foreach ( var notification in notifications . GroupBy ( x = > x . Category ) )
{
body . AppendLine (
$"" "
{ categor y} :
{ string . Join ( '\n' , events . Select ( x = > x . Render ( ) ) ) }
{ notification. Ke y} :
{ string . Join ( '\n' , notification . Select ( x = > x . Render ( ) ) ) }
"" ");
}
return body . ToString ( ) ;
}
}