From a0453a0fe65d19d0484cc83ce2f31b08dadcfd09 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 15 Aug 2020 18:16:20 -0400 Subject: Migrate ServerEventNotifier.OnUserUpdated to IEventConsumer --- .../Events/Consumers/System/TaskCompletedLogger.cs | 158 +++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs (limited to 'Jellyfin.Server.Implementations/Events/Consumers/System') diff --git a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs new file mode 100644 index 000000000..05201a346 --- /dev/null +++ b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Threading.Tasks; +using Jellyfin.Data.Entities; +using MediaBrowser.Controller.Events; +using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Notifications; +using MediaBrowser.Model.Tasks; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Implementations.Events.Consumers.System +{ + /// + /// Creates an activity log entry whenever a task is completed. + /// + public class TaskCompletedLogger : IEventConsumer + { + private readonly ILocalizationManager _localizationManager; + private readonly IActivityManager _activityManager; + + /// + /// Initializes a new instance of the class. + /// + /// The localization manager. + /// The activity manager. + public TaskCompletedLogger(ILocalizationManager localizationManager, IActivityManager activityManager) + { + _localizationManager = localizationManager; + _activityManager = activityManager; + } + + /// + public async Task OnEvent(TaskCompletionEventArgs e) + { + var result = e.Result; + var task = e.Task; + + if (task.ScheduledTask is IConfigurableScheduledTask activityTask + && !activityTask.IsLogged) + { + return; + } + + var time = result.EndTimeUtc - result.StartTimeUtc; + var runningTime = string.Format( + CultureInfo.InvariantCulture, + _localizationManager.GetLocalizedString("LabelRunningTimeValue"), + ToUserFriendlyString(time)); + + if (result.Status == TaskCompletionStatus.Failed) + { + var vals = new List(); + + if (!string.IsNullOrEmpty(e.Result.ErrorMessage)) + { + vals.Add(e.Result.ErrorMessage); + } + + if (!string.IsNullOrEmpty(e.Result.LongErrorMessage)) + { + vals.Add(e.Result.LongErrorMessage); + } + + await _activityManager.CreateAsync(new ActivityLog( + string.Format(CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), + NotificationType.TaskFailed.ToString(), + Guid.Empty) + { + LogSeverity = LogLevel.Error, + Overview = string.Join(Environment.NewLine, vals), + ShortOverview = runningTime + }).ConfigureAwait(false); + } + } + + private static string ToUserFriendlyString(TimeSpan span) + { + const int DaysInYear = 365; + const int DaysInMonth = 30; + + // Get each non-zero value from TimeSpan component + var values = new List(); + + // Number of years + int days = span.Days; + if (days >= DaysInYear) + { + int years = days / DaysInYear; + values.Add(CreateValueString(years, "year")); + days %= DaysInYear; + } + + // Number of months + if (days >= DaysInMonth) + { + int months = days / DaysInMonth; + values.Add(CreateValueString(months, "month")); + days = days % DaysInMonth; + } + + // Number of days + if (days >= 1) + { + values.Add(CreateValueString(days, "day")); + } + + // Number of hours + if (span.Hours >= 1) + { + values.Add(CreateValueString(span.Hours, "hour")); + } + + // Number of minutes + if (span.Minutes >= 1) + { + values.Add(CreateValueString(span.Minutes, "minute")); + } + + // Number of seconds (include when 0 if no other components included) + if (span.Seconds >= 1 || values.Count == 0) + { + values.Add(CreateValueString(span.Seconds, "second")); + } + + // Combine values into string + var builder = new StringBuilder(); + for (int i = 0; i < values.Count; i++) + { + if (builder.Length > 0) + { + builder.Append(i == values.Count - 1 ? " and " : ", "); + } + + builder.Append(values[i]); + } + + // Return result + return builder.ToString(); + } + + /// + /// Constructs a string description of a time-span value. + /// + /// The value of this item. + /// The name of this item (singular form). + private static string CreateValueString(int value, string description) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0:#,##0} {1}", + value, + value == 1 ? description : string.Format(CultureInfo.InvariantCulture, "{0}s", description)); + } + } +} -- cgit v1.2.3 From 5282a5c8c2224ec36121cdf99ef2a14f7d703973 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 15 Aug 2020 18:16:41 -0400 Subject: Migrate ServerEventNotifier.OnTaskCompleted to IEventConsumer --- .../EntryPoints/ServerEventNotifier.cs | 17 ------------ .../Consumers/System/TaskCompletedNotifier.cs | 31 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedNotifier.cs (limited to 'Jellyfin.Server.Implementations/Events/Consumers/System') diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 0e5086685..833c06106 100644 --- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -25,11 +25,6 @@ namespace Emby.Server.Implementations.EntryPoints /// private readonly IServerApplicationHost _appHost; - /// - /// The task manager. - /// - private readonly ITaskManager _taskManager; - private readonly ISessionManager _sessionManager; /// @@ -37,17 +32,14 @@ namespace Emby.Server.Implementations.EntryPoints /// /// The application host. /// The installation manager. - /// The task manager. /// The session manager. public ServerEventNotifier( IServerApplicationHost appHost, IInstallationManager installationManager, - ITaskManager taskManager, ISessionManager sessionManager) { _installationManager = installationManager; _appHost = appHost; - _taskManager = taskManager; _sessionManager = sessionManager; } @@ -62,8 +54,6 @@ namespace Emby.Server.Implementations.EntryPoints _installationManager.PackageInstallationCompleted += OnPackageInstallationCompleted; _installationManager.PackageInstallationFailed += OnPackageInstallationFailed; - _taskManager.TaskCompleted += OnTaskCompleted; - return Task.CompletedTask; } @@ -87,11 +77,6 @@ namespace Emby.Server.Implementations.EntryPoints await SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo).ConfigureAwait(false); } - private async void OnTaskCompleted(object sender, TaskCompletionEventArgs e) - { - await SendMessageToAdminSessions("ScheduledTaskEnded", e.Result).ConfigureAwait(false); - } - /// /// Installations the manager_ plugin uninstalled. /// @@ -145,8 +130,6 @@ namespace Emby.Server.Implementations.EntryPoints _installationManager.PackageInstallationFailed -= OnPackageInstallationFailed; _appHost.HasPendingRestartChanged -= OnHasPendingRestartChanged; - - _taskManager.TaskCompleted -= OnTaskCompleted; } } } diff --git a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedNotifier.cs b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedNotifier.cs new file mode 100644 index 000000000..80ed56cd8 --- /dev/null +++ b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedNotifier.cs @@ -0,0 +1,31 @@ +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Events; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Tasks; + +namespace Jellyfin.Server.Implementations.Events.Consumers.System +{ + /// + /// Notifies admin users when a task is completed. + /// + public class TaskCompletedNotifier : IEventConsumer + { + private readonly ISessionManager _sessionManager; + + /// + /// Initializes a new instance of the class. + /// + /// The session manager. + public TaskCompletedNotifier(ISessionManager sessionManager) + { + _sessionManager = sessionManager; + } + + /// + public async Task OnEvent(TaskCompletionEventArgs eventArgs) + { + await _sessionManager.SendMessageToAdminSessions("ScheduledTaskEnded", eventArgs.Result, CancellationToken.None).ConfigureAwait(false); + } + } +} -- cgit v1.2.3 From dc88e93504a98a377881f7425ffba5d2221fada0 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 15 Aug 2020 18:33:30 -0400 Subject: Migrate ServerEventNotifier.OnHasPendingRestartChanged to IEventConsumer --- .../EntryPoints/ServerEventNotifier.cs | 23 ---------------- .../Events/System/PendingRestartEventArgs.cs | 11 ++++++++ .../Consumers/System/PendingRestartNotifier.cs | 31 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 Jellyfin.Data/Events/System/PendingRestartEventArgs.cs create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/System/PendingRestartNotifier.cs (limited to 'Jellyfin.Server.Implementations/Events/Consumers/System') diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 833c06106..3d58b91e1 100644 --- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -3,7 +3,6 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Updates; @@ -20,34 +19,24 @@ namespace Emby.Server.Implementations.EntryPoints /// private readonly IInstallationManager _installationManager; - /// - /// The kernel. - /// - private readonly IServerApplicationHost _appHost; - private readonly ISessionManager _sessionManager; /// /// Initializes a new instance of the class. /// - /// The application host. /// The installation manager. /// The session manager. public ServerEventNotifier( - IServerApplicationHost appHost, IInstallationManager installationManager, ISessionManager sessionManager) { _installationManager = installationManager; - _appHost = appHost; _sessionManager = sessionManager; } /// public Task RunAsync() { - _appHost.HasPendingRestartChanged += OnHasPendingRestartChanged; - _installationManager.PluginUninstalled += OnPluginUninstalled; _installationManager.PackageInstalling += OnPackageInstalling; _installationManager.PackageInstallationCancelled += OnPackageInstallationCancelled; @@ -87,16 +76,6 @@ namespace Emby.Server.Implementations.EntryPoints await SendMessageToAdminSessions("PluginUninstalled", e).ConfigureAwait(false); } - /// - /// Handles the HasPendingRestartChanged event of the kernel control. - /// - /// The source of the event. - /// The instance containing the event data. - private async void OnHasPendingRestartChanged(object sender, EventArgs e) - { - await _sessionManager.SendRestartRequiredNotification(CancellationToken.None).ConfigureAwait(false); - } - private async Task SendMessageToAdminSessions(string name, T data) { try @@ -128,8 +107,6 @@ namespace Emby.Server.Implementations.EntryPoints _installationManager.PackageInstallationCancelled -= OnPackageInstallationCancelled; _installationManager.PackageInstallationCompleted -= OnPackageInstallationCompleted; _installationManager.PackageInstallationFailed -= OnPackageInstallationFailed; - - _appHost.HasPendingRestartChanged -= OnHasPendingRestartChanged; } } } diff --git a/Jellyfin.Data/Events/System/PendingRestartEventArgs.cs b/Jellyfin.Data/Events/System/PendingRestartEventArgs.cs new file mode 100644 index 000000000..17a454969 --- /dev/null +++ b/Jellyfin.Data/Events/System/PendingRestartEventArgs.cs @@ -0,0 +1,11 @@ +using System; + +namespace Jellyfin.Data.Events.System +{ + /// + /// An event that fires when there is a pending restart. + /// + public class PendingRestartEventArgs : EventArgs + { + } +} diff --git a/Jellyfin.Server.Implementations/Events/Consumers/System/PendingRestartNotifier.cs b/Jellyfin.Server.Implementations/Events/Consumers/System/PendingRestartNotifier.cs new file mode 100644 index 000000000..2fa38dd71 --- /dev/null +++ b/Jellyfin.Server.Implementations/Events/Consumers/System/PendingRestartNotifier.cs @@ -0,0 +1,31 @@ +using System.Threading; +using System.Threading.Tasks; +using Jellyfin.Data.Events.System; +using MediaBrowser.Controller.Events; +using MediaBrowser.Controller.Session; + +namespace Jellyfin.Server.Implementations.Events.Consumers.System +{ + /// + /// Notifies users when there is a pending restart. + /// + public class PendingRestartNotifier : IEventConsumer + { + private readonly ISessionManager _sessionManager; + + /// + /// Initializes a new instance of the class. + /// + /// The session manager. + public PendingRestartNotifier(ISessionManager sessionManager) + { + _sessionManager = sessionManager; + } + + /// + public async Task OnEvent(PendingRestartEventArgs eventArgs) + { + await _sessionManager.SendRestartRequiredNotification(CancellationToken.None).ConfigureAwait(false); + } + } +} -- cgit v1.2.3