mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-01-05 04:18:27 -05:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba02aa0e49 | ||
|
|
5adbdbd920 | ||
|
|
b3b211d956 |
@@ -140,6 +140,7 @@ services:
|
||||
volumes:
|
||||
- ./cleanuperr/logs:/var/logs
|
||||
environment:
|
||||
- TZ=America/New_York
|
||||
- DRY_RUN=false
|
||||
|
||||
- LOGGING__LOGLEVEL=Information
|
||||
|
||||
23
code/Executable/HostExtensions.cs
Normal file
23
code/Executable/HostExtensions.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Executable;
|
||||
|
||||
public static class HostExtensions
|
||||
{
|
||||
public static IHost Init(this IHost host)
|
||||
{
|
||||
ILogger<Program> logger = host.Services.GetRequiredService<ILogger<Program>>();
|
||||
|
||||
Version? version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
logger.LogInformation(
|
||||
version is null
|
||||
? "cleanuperr version not detected"
|
||||
: $"cleanuperr v{version.Major}.{version.Minor}.{version.Build}"
|
||||
);
|
||||
|
||||
logger.LogInformation("timezone: {tz}", TimeZoneInfo.Local.DisplayName);
|
||||
|
||||
return host;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
using Executable;
|
||||
using Executable.DependencyInjection;
|
||||
|
||||
var builder = Host.CreateApplicationBuilder(args);
|
||||
@@ -7,15 +7,6 @@ builder.Services.AddInfrastructure(builder.Configuration);
|
||||
builder.Logging.AddLogging(builder.Configuration);
|
||||
|
||||
var host = builder.Build();
|
||||
|
||||
var logger = host.Services.GetRequiredService<ILogger<Program>>();
|
||||
|
||||
var version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
logger.LogInformation(
|
||||
version is null
|
||||
? "cleanuperr version not detected"
|
||||
: $"cleanuperr v{version.Major}.{version.Minor}.{version.Build}"
|
||||
);
|
||||
host.Init();
|
||||
|
||||
host.Run();
|
||||
@@ -32,7 +32,7 @@ public class NotificationPublisher : INotificationPublisher
|
||||
QueueRecord record = ContextProvider.Get<QueueRecord>(nameof(QueueRecord));
|
||||
InstanceType instanceType = (InstanceType)ContextProvider.Get<object>(nameof(InstanceType));
|
||||
Uri instanceUrl = ContextProvider.Get<Uri>(nameof(ArrInstance) + nameof(ArrInstance.Url));
|
||||
Uri imageUrl = GetImageFromContext(record, instanceType);
|
||||
Uri? imageUrl = GetImageFromContext(record, instanceType);
|
||||
|
||||
ArrNotification notification = new()
|
||||
{
|
||||
@@ -63,42 +63,59 @@ public class NotificationPublisher : INotificationPublisher
|
||||
|
||||
public virtual async Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason)
|
||||
{
|
||||
QueueRecord record = ContextProvider.Get<QueueRecord>(nameof(QueueRecord));
|
||||
InstanceType instanceType = (InstanceType)ContextProvider.Get<object>(nameof(InstanceType));
|
||||
Uri instanceUrl = ContextProvider.Get<Uri>(nameof(ArrInstance) + nameof(ArrInstance.Url));
|
||||
Uri imageUrl = GetImageFromContext(record, instanceType);
|
||||
|
||||
QueueItemDeletedNotification notification = new()
|
||||
try
|
||||
{
|
||||
InstanceType = instanceType,
|
||||
InstanceUrl = instanceUrl,
|
||||
Hash = record.DownloadId.ToLowerInvariant(),
|
||||
Title = $"Deleting item from queue with reason: {reason}",
|
||||
Description = record.Title,
|
||||
Image = imageUrl,
|
||||
Fields = [new() { Title = "Removed from download client?", Text = removeFromClient ? "Yes" : "No" }]
|
||||
};
|
||||
|
||||
await _dryRunInterceptor.InterceptAsync(Notify<QueueItemDeletedNotification>, notification);
|
||||
QueueRecord record = ContextProvider.Get<QueueRecord>(nameof(QueueRecord));
|
||||
InstanceType instanceType = (InstanceType)ContextProvider.Get<object>(nameof(InstanceType));
|
||||
Uri instanceUrl = ContextProvider.Get<Uri>(nameof(ArrInstance) + nameof(ArrInstance.Url));
|
||||
Uri? imageUrl = GetImageFromContext(record, instanceType);
|
||||
|
||||
QueueItemDeletedNotification notification = new()
|
||||
{
|
||||
InstanceType = instanceType,
|
||||
InstanceUrl = instanceUrl,
|
||||
Hash = record.DownloadId.ToLowerInvariant(),
|
||||
Title = $"Deleting item from queue with reason: {reason}",
|
||||
Description = record.Title,
|
||||
Image = imageUrl,
|
||||
Fields = [new() { Title = "Removed from download client?", Text = removeFromClient ? "Yes" : "No" }]
|
||||
};
|
||||
|
||||
await _dryRunInterceptor.InterceptAsync(Notify<QueueItemDeletedNotification>, notification);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "failed to notify queue item deleted");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason)
|
||||
{
|
||||
DownloadCleanedNotification notification = new()
|
||||
try
|
||||
{
|
||||
Title = $"Cleaned item from download client with reason: {reason}",
|
||||
Description = ContextProvider.Get<string>("downloadName"),
|
||||
Fields =
|
||||
[
|
||||
new() { Title = "Hash", Text = ContextProvider.Get<string>("hash").ToLowerInvariant() },
|
||||
new() { Title = "Category", Text = categoryName.ToLowerInvariant() },
|
||||
new() { Title = "Ratio", Text = $"{ratio.ToString(CultureInfo.InvariantCulture)}%" },
|
||||
new() { Title = "Seeding hours", Text = $"{Math.Round(seedingTime.TotalHours, 0).ToString(CultureInfo.InvariantCulture)}h" }
|
||||
],
|
||||
Level = NotificationLevel.Important
|
||||
};
|
||||
DownloadCleanedNotification notification = new()
|
||||
{
|
||||
Title = $"Cleaned item from download client with reason: {reason}",
|
||||
Description = ContextProvider.Get<string>("downloadName"),
|
||||
Fields =
|
||||
[
|
||||
new() { Title = "Hash", Text = ContextProvider.Get<string>("hash").ToLowerInvariant() },
|
||||
new() { Title = "Category", Text = categoryName.ToLowerInvariant() },
|
||||
new() { Title = "Ratio", Text = $"{ratio.ToString(CultureInfo.InvariantCulture)}%" },
|
||||
new()
|
||||
{
|
||||
Title = "Seeding hours", Text = $"{Math.Round(seedingTime.TotalHours, 0).ToString(CultureInfo.InvariantCulture)}h"
|
||||
}
|
||||
],
|
||||
Level = NotificationLevel.Important
|
||||
};
|
||||
|
||||
await _dryRunInterceptor.InterceptAsync(Notify<DownloadCleanedNotification>, notification);
|
||||
await _dryRunInterceptor.InterceptAsync(Notify<DownloadCleanedNotification>, notification);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "failed to notify download cleaned");
|
||||
}
|
||||
}
|
||||
|
||||
[DryRunSafeguard]
|
||||
@@ -107,12 +124,21 @@ public class NotificationPublisher : INotificationPublisher
|
||||
return _messageBus.Publish(message);
|
||||
}
|
||||
|
||||
private static Uri GetImageFromContext(QueueRecord record, InstanceType instanceType) =>
|
||||
instanceType switch
|
||||
private Uri? GetImageFromContext(QueueRecord record, InstanceType instanceType)
|
||||
{
|
||||
Uri? image = instanceType switch
|
||||
{
|
||||
InstanceType.Sonarr => record.Series!.Images.FirstOrDefault(x => x.CoverType == "poster")?.RemoteUrl,
|
||||
InstanceType.Radarr => record.Movie!.Images.FirstOrDefault(x => x.CoverType == "poster")?.RemoteUrl,
|
||||
InstanceType.Lidarr => record.Album!.Images.FirstOrDefault(x => x.CoverType == "cover")?.Url,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(instanceType))
|
||||
} ?? throw new Exception("failed to get image url from context");
|
||||
};
|
||||
|
||||
if (image is null)
|
||||
{
|
||||
_logger.LogWarning("no poster found for {title}", record.Title);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -175,6 +175,7 @@ services:
|
||||
image: ghcr.io/flmorg/cleanuperr:latest
|
||||
container_name: cleanuperr
|
||||
environment:
|
||||
- TZ=Europe/Bucharest
|
||||
- DRY_RUN=false
|
||||
|
||||
- LOGGING__LOGLEVEL=Debug
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
|
||||
### General settings
|
||||
|
||||
**`TZ`**
|
||||
- The time zone to use.
|
||||
- Type: String.
|
||||
- Possible values: Any valid timezone.
|
||||
- Default: `UTC`.
|
||||
- Required: No.
|
||||
|
||||
**`DRY_RUN`**
|
||||
- When enabled, simulates irreversible operations (like deletions and notifications) without making actual changes.
|
||||
- Type: Boolean.
|
||||
|
||||
Reference in New Issue
Block a user