mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-02 14:56:31 +01:00
rework scheduled tasks in preparation of common project going portable
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using MediaBrowser.Model.Cryptography;
|
||||
|
||||
namespace MediaBrowser.Common.Extensions
|
||||
{
|
||||
@@ -12,6 +10,7 @@ namespace MediaBrowser.Common.Extensions
|
||||
/// </summary>
|
||||
public static class BaseExtensions
|
||||
{
|
||||
public static ICryptographyProvider CryptographyProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Strips the HTML.
|
||||
@@ -26,15 +25,6 @@ namespace MediaBrowser.Common.Extensions
|
||||
return Regex.Replace(htmlString, pattern, string.Empty).Trim();
|
||||
}
|
||||
|
||||
public static string RemoveDiacritics(this string text)
|
||||
{
|
||||
return String.Concat(
|
||||
text.Normalize(NormalizationForm.FormD)
|
||||
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
|
||||
UnicodeCategory.NonSpacingMark)
|
||||
).Normalize(NormalizationForm.FormC);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the M d5.
|
||||
/// </summary>
|
||||
@@ -42,10 +32,7 @@ namespace MediaBrowser.Common.Extensions
|
||||
/// <returns>Guid.</returns>
|
||||
public static Guid GetMD5(this string str)
|
||||
{
|
||||
using (var provider = MD5.Create())
|
||||
{
|
||||
return new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(str)));
|
||||
}
|
||||
return CryptographyProvider.GetMD5(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace MediaBrowser.Common
|
||||
/// Gets the plugins.
|
||||
/// </summary>
|
||||
/// <value>The plugins.</value>
|
||||
IEnumerable<IPlugin> Plugins { get; }
|
||||
IPlugin[] Plugins { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes the plugin.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Common.IO
|
||||
{
|
||||
public interface IMemoryStreamProvider
|
||||
{
|
||||
MemoryStream CreateNew();
|
||||
MemoryStream CreateNew(int capacity);
|
||||
MemoryStream CreateNew(byte[] buffer);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Common.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Class StreamDefaults
|
||||
/// </summary>
|
||||
public static class StreamDefaults
|
||||
{
|
||||
/// <summary>
|
||||
/// The default copy to buffer size
|
||||
/// </summary>
|
||||
public const int DefaultCopyToBufferSize = 81920;
|
||||
|
||||
/// <summary>
|
||||
/// The default file stream buffer size
|
||||
/// </summary>
|
||||
public const int DefaultFileStreamBufferSize = 81920;
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,7 @@
|
||||
<Compile Include="Extensions\BaseExtensions.cs" />
|
||||
<Compile Include="Extensions\ResourceNotFoundException.cs" />
|
||||
<Compile Include="IDependencyContainer.cs" />
|
||||
<Compile Include="IO\IMemoryStreamProvider.cs" />
|
||||
<Compile Include="IO\ProgressStream.cs" />
|
||||
<Compile Include="IO\StreamDefaults.cs" />
|
||||
<Compile Include="Configuration\IApplicationPaths.cs" />
|
||||
<Compile Include="Net\HttpRequestOptions.cs" />
|
||||
<Compile Include="Net\HttpResponseInfo.cs" />
|
||||
@@ -69,22 +67,13 @@
|
||||
<Compile Include="Plugins\IDependencyModule.cs" />
|
||||
<Compile Include="Plugins\IPlugin.cs" />
|
||||
<Compile Include="Progress\ActionableProgress.cs" />
|
||||
<Compile Include="ScheduledTasks\IConfigurableScheduledTask.cs" />
|
||||
<Compile Include="ScheduledTasks\IHasKey.cs" />
|
||||
<Compile Include="ScheduledTasks\IScheduledTask.cs" />
|
||||
<Compile Include="ScheduledTasks\IScheduledTaskWorker.cs" />
|
||||
<Compile Include="ScheduledTasks\ITaskManager.cs" />
|
||||
<Compile Include="ScheduledTasks\ITaskTrigger.cs" />
|
||||
<Compile Include="ScheduledTasks\ScheduledTaskHelpers.cs" />
|
||||
<Compile Include="ScheduledTasks\StartupTrigger.cs" />
|
||||
<Compile Include="ScheduledTasks\SystemEventTrigger.cs" />
|
||||
<Compile Include="Plugins\BasePlugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ScheduledTasks\DailyTrigger.cs" />
|
||||
<Compile Include="ScheduledTasks\IntervalTrigger.cs" />
|
||||
<Compile Include="ScheduledTasks\TaskCompletionEventArgs.cs" />
|
||||
<Compile Include="ScheduledTasks\TaskExecutionOptions.cs" />
|
||||
<Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
|
||||
<Compile Include="Security\IRequiresRegistration.cs" />
|
||||
<Compile Include="Security\ISecurityManager.cs" />
|
||||
<Compile Include="Security\PaymentRequiredException.cs" />
|
||||
|
||||
@@ -3,8 +3,6 @@ using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MediaBrowser.Common.Plugins
|
||||
{
|
||||
@@ -12,7 +10,7 @@ namespace MediaBrowser.Common.Plugins
|
||||
/// Provides a common base class for all plugins
|
||||
/// </summary>
|
||||
/// <typeparam name="TConfigurationType">The type of the T configuration type.</typeparam>
|
||||
public abstract class BasePlugin<TConfigurationType> : IPlugin
|
||||
public abstract class BasePlugin<TConfigurationType> : IPlugin, IPluginAssembly
|
||||
where TConfigurationType : BasePluginConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
@@ -57,69 +55,33 @@ namespace MediaBrowser.Common.Plugins
|
||||
get { return typeof(TConfigurationType); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _assembly name
|
||||
/// </summary>
|
||||
private AssemblyName _assemblyName;
|
||||
/// <summary>
|
||||
/// Gets the name of the assembly.
|
||||
/// </summary>
|
||||
/// <value>The name of the assembly.</value>
|
||||
protected AssemblyName AssemblyName
|
||||
public void SetAttributes(string assemblyFilePath, string assemblyFileName, Version assemblyVersion, Guid assemblyId)
|
||||
{
|
||||
get
|
||||
{
|
||||
return _assemblyName ?? (_assemblyName = GetType().Assembly.GetName());
|
||||
}
|
||||
}
|
||||
AssemblyFilePath = assemblyFilePath;
|
||||
AssemblyFileName = assemblyFileName;
|
||||
Version = assemblyVersion;
|
||||
Id = assemblyId;
|
||||
|
||||
/// <summary>
|
||||
/// The _unique id
|
||||
/// </summary>
|
||||
private Guid? _uniqueId;
|
||||
IsFirstRun = !File.Exists(ConfigurationFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique id.
|
||||
/// </summary>
|
||||
/// <value>The unique id.</value>
|
||||
public Guid Id
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (!_uniqueId.HasValue)
|
||||
{
|
||||
var attribute = (GuidAttribute)GetType().Assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
|
||||
_uniqueId = new Guid(attribute.Value);
|
||||
}
|
||||
|
||||
return _uniqueId.Value;
|
||||
}
|
||||
}
|
||||
public Guid Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin version
|
||||
/// </summary>
|
||||
/// <value>The version.</value>
|
||||
public Version Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return AssemblyName.Version;
|
||||
}
|
||||
}
|
||||
public Version Version { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name the assembly file
|
||||
/// </summary>
|
||||
/// <value>The name of the assembly file.</value>
|
||||
public string AssemblyFileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return AssemblyName.Name + ".dll";
|
||||
}
|
||||
}
|
||||
protected string AssemblyFileName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last date modified of the configuration
|
||||
@@ -136,29 +98,11 @@ namespace MediaBrowser.Common.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last date modified of the plugin
|
||||
/// </summary>
|
||||
/// <value>The assembly date last modified.</value>
|
||||
public DateTime AssemblyDateLastModified
|
||||
{
|
||||
get
|
||||
{
|
||||
return File.GetLastWriteTimeUtc(AssemblyFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the assembly file
|
||||
/// </summary>
|
||||
/// <value>The assembly file path.</value>
|
||||
public string AssemblyFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(ApplicationPaths.PluginsPath, AssemblyFileName);
|
||||
}
|
||||
}
|
||||
public string AssemblyFilePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The _configuration sync lock
|
||||
@@ -272,8 +216,6 @@ namespace MediaBrowser.Common.Plugins
|
||||
{
|
||||
ApplicationPaths = applicationPaths;
|
||||
XmlSerializer = xmlSerializer;
|
||||
|
||||
IsFirstRun = !File.Exists(ConfigurationFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -349,4 +291,9 @@ namespace MediaBrowser.Common.Plugins
|
||||
get { return Configuration; }
|
||||
}
|
||||
}
|
||||
|
||||
public interface IPluginAssembly
|
||||
{
|
||||
void SetAttributes(string assemblyFilePath, string assemblyFileName, Version assemblyVersion, Guid assemblyId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,6 @@ namespace MediaBrowser.Common.Plugins
|
||||
/// <value>The version.</value>
|
||||
Version Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name the assembly file
|
||||
/// </summary>
|
||||
/// <value>The name of the assembly file.</value>
|
||||
string AssemblyFileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is first run.
|
||||
/// </summary>
|
||||
@@ -56,12 +50,6 @@ namespace MediaBrowser.Common.Plugins
|
||||
/// <value>The configuration date last modified.</value>
|
||||
DateTime ConfigurationDateLastModified { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last date modified of the plugin
|
||||
/// </summary>
|
||||
/// <value>The assembly date last modified.</value>
|
||||
DateTime AssemblyDateLastModified { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the assembly file
|
||||
/// </summary>
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a task trigger that fires everyday
|
||||
/// </summary>
|
||||
public class DailyTrigger : ITaskTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the time of day to trigger the task to run
|
||||
/// </summary>
|
||||
/// <value>The time of day.</value>
|
||||
public TimeSpan TimeOfDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timer.
|
||||
/// </summary>
|
||||
/// <value>The timer.</value>
|
||||
private Timer Timer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution properties of this task.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The execution properties of this task.
|
||||
/// </value>
|
||||
public TaskExecutionOptions TaskOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
|
||||
{
|
||||
DisposeTimer();
|
||||
|
||||
var now = DateTime.Now;
|
||||
|
||||
var triggerDate = now.TimeOfDay > TimeOfDay ? now.Date.AddDays(1) : now.Date;
|
||||
triggerDate = triggerDate.Add(TimeOfDay);
|
||||
|
||||
var dueTime = triggerDate - now;
|
||||
|
||||
logger.Info("Daily trigger for {0} set to fire at {1}, which is {2} minutes from now.", taskName, triggerDate.ToString(), dueTime.TotalMinutes.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops waiting for the trigger action
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
DisposeTimer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the timer.
|
||||
/// </summary>
|
||||
private void DisposeTimer()
|
||||
{
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [triggered].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [triggered].
|
||||
/// </summary>
|
||||
private void OnTriggered()
|
||||
{
|
||||
if (Triggered != null)
|
||||
{
|
||||
Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
public interface IConfigurableScheduledTask
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is hidden.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
|
||||
bool IsHidden { get; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is enabled.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is enabled; otherwise, <c>false</c>.</value>
|
||||
bool IsEnabled { get; }
|
||||
}
|
||||
|
||||
public interface IScheduledTaskActivityLog
|
||||
{
|
||||
bool IsActivityLogged { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
public interface IHasKey
|
||||
{
|
||||
string Key { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IScheduledTaskWorker
|
||||
/// </summary>
|
||||
public interface IScheduledTask
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the task
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
/// <value>The description.</value>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category.
|
||||
/// </summary>
|
||||
/// <value>The category.</value>
|
||||
string Category { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Executes the task
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task Execute(CancellationToken cancellationToken, IProgress<double> progress);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default triggers.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
||||
IEnumerable<ITaskTrigger> GetDefaultTriggers();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
@@ -62,7 +61,7 @@ namespace MediaBrowser.Common.ScheduledTasks
|
||||
/// </summary>
|
||||
/// <value>The triggers.</value>
|
||||
/// <exception cref="System.ArgumentNullException">value</exception>
|
||||
IEnumerable<ITaskTrigger> Triggers { get; set; }
|
||||
TaskTriggerInfo[] Triggers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique id.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace MediaBrowser.Common.ScheduledTasks
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a task trigger that runs repeatedly on an interval
|
||||
/// </summary>
|
||||
public class IntervalTrigger : ITaskTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the interval.
|
||||
/// </summary>
|
||||
/// <value>The interval.</value>
|
||||
public TimeSpan Interval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timer.
|
||||
/// </summary>
|
||||
/// <value>The timer.</value>
|
||||
private Timer Timer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution properties of this task.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The execution properties of this task.
|
||||
/// </value>
|
||||
public TaskExecutionOptions TaskOptions { get; set; }
|
||||
|
||||
private DateTime _lastStartDate;
|
||||
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
|
||||
{
|
||||
DisposeTimer();
|
||||
|
||||
DateTime triggerDate;
|
||||
|
||||
if (lastResult == null)
|
||||
{
|
||||
// Task has never been completed before
|
||||
triggerDate = DateTime.UtcNow.AddHours(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(Interval);
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow > triggerDate)
|
||||
{
|
||||
triggerDate = DateTime.UtcNow.AddMinutes(1);
|
||||
}
|
||||
|
||||
var dueTime = triggerDate - DateTime.UtcNow;
|
||||
var maxDueTime = TimeSpan.FromDays(7);
|
||||
|
||||
if (dueTime > maxDueTime)
|
||||
{
|
||||
dueTime = maxDueTime;
|
||||
}
|
||||
|
||||
Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops waiting for the trigger action
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
DisposeTimer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the timer.
|
||||
/// </summary>
|
||||
private void DisposeTimer()
|
||||
{
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [triggered].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [triggered].
|
||||
/// </summary>
|
||||
private void OnTriggered()
|
||||
{
|
||||
DisposeTimer();
|
||||
|
||||
if (Triggered != null)
|
||||
{
|
||||
_lastStartDate = DateTime.UtcNow;
|
||||
Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,17 +25,9 @@ namespace MediaBrowser.Common.ScheduledTasks
|
||||
isHidden = configurableTask.IsHidden;
|
||||
}
|
||||
|
||||
string key = null;
|
||||
|
||||
var hasKey = task.ScheduledTask as IHasKey;
|
||||
|
||||
if (hasKey != null)
|
||||
{
|
||||
key = hasKey.Key;
|
||||
}
|
||||
string key = task.ScheduledTask.Key;
|
||||
|
||||
var triggers = task.Triggers
|
||||
.Select(GetTriggerInfo)
|
||||
.OrderBy(i => i.Type)
|
||||
.ThenBy(i => i.DayOfWeek ?? DayOfWeek.Sunday)
|
||||
.ThenBy(i => i.TimeOfDayTicks ?? 0)
|
||||
@@ -57,138 +49,5 @@ namespace MediaBrowser.Common.ScheduledTasks
|
||||
Key = key
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger info.
|
||||
/// </summary>
|
||||
/// <param name="trigger">The trigger.</param>
|
||||
/// <returns>TaskTriggerInfo.</returns>
|
||||
public static TaskTriggerInfo GetTriggerInfo(ITaskTrigger trigger)
|
||||
{
|
||||
var info = new TaskTriggerInfo
|
||||
{
|
||||
Type = trigger.GetType().Name
|
||||
};
|
||||
|
||||
var dailyTrigger = trigger as DailyTrigger;
|
||||
|
||||
if (dailyTrigger != null)
|
||||
{
|
||||
info.TimeOfDayTicks = dailyTrigger.TimeOfDay.Ticks;
|
||||
}
|
||||
|
||||
var weeklyTaskTrigger = trigger as WeeklyTrigger;
|
||||
|
||||
if (weeklyTaskTrigger != null)
|
||||
{
|
||||
info.TimeOfDayTicks = weeklyTaskTrigger.TimeOfDay.Ticks;
|
||||
info.DayOfWeek = weeklyTaskTrigger.DayOfWeek;
|
||||
}
|
||||
|
||||
var intervalTaskTrigger = trigger as IntervalTrigger;
|
||||
|
||||
if (intervalTaskTrigger != null)
|
||||
{
|
||||
info.IntervalTicks = intervalTaskTrigger.Interval.Ticks;
|
||||
}
|
||||
|
||||
var systemEventTrigger = trigger as SystemEventTrigger;
|
||||
|
||||
if (systemEventTrigger != null)
|
||||
{
|
||||
info.SystemEvent = systemEventTrigger.SystemEvent;
|
||||
}
|
||||
|
||||
if (trigger.TaskOptions != null)
|
||||
{
|
||||
info.MaxRuntimeMs = trigger.TaskOptions.MaxRuntimeMs;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a TaskTriggerInfo into a concrete BaseTaskTrigger
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <returns>BaseTaskTrigger.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
/// <exception cref="System.ArgumentException">Invalid trigger type: + info.Type</exception>
|
||||
public static ITaskTrigger GetTrigger(TaskTriggerInfo info)
|
||||
{
|
||||
var options = new TaskExecutionOptions
|
||||
{
|
||||
MaxRuntimeMs = info.MaxRuntimeMs
|
||||
};
|
||||
|
||||
if (info.Type.Equals(typeof(DailyTrigger).Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!info.TimeOfDayTicks.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new DailyTrigger
|
||||
{
|
||||
TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
|
||||
TaskOptions = options
|
||||
};
|
||||
}
|
||||
|
||||
if (info.Type.Equals(typeof(WeeklyTrigger).Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!info.TimeOfDayTicks.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (!info.DayOfWeek.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new WeeklyTrigger
|
||||
{
|
||||
TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
|
||||
DayOfWeek = info.DayOfWeek.Value,
|
||||
TaskOptions = options
|
||||
};
|
||||
}
|
||||
|
||||
if (info.Type.Equals(typeof(IntervalTrigger).Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!info.IntervalTicks.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new IntervalTrigger
|
||||
{
|
||||
Interval = TimeSpan.FromTicks(info.IntervalTicks.Value),
|
||||
TaskOptions = options
|
||||
};
|
||||
}
|
||||
|
||||
if (info.Type.Equals(typeof(SystemEventTrigger).Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!info.SystemEvent.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new SystemEventTrigger
|
||||
{
|
||||
SystemEvent = info.SystemEvent.Value,
|
||||
TaskOptions = options
|
||||
};
|
||||
}
|
||||
|
||||
if (info.Type.Equals(typeof(StartupTrigger).Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new StartupTrigger();
|
||||
}
|
||||
|
||||
throw new ArgumentException("Unrecognized trigger type: " + info.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Class StartupTaskTrigger
|
||||
/// </summary>
|
||||
public class StartupTrigger : ITaskTrigger
|
||||
{
|
||||
public int DelayMs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution properties of this task.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The execution properties of this task.
|
||||
/// </value>
|
||||
public TaskExecutionOptions TaskOptions { get; set; }
|
||||
|
||||
public StartupTrigger()
|
||||
{
|
||||
DelayMs = 3000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
public async void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
|
||||
{
|
||||
if (isApplicationStartup)
|
||||
{
|
||||
await Task.Delay(DelayMs).ConfigureAwait(false);
|
||||
|
||||
OnTriggered();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops waiting for the trigger action
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [triggered].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [triggered].
|
||||
/// </summary>
|
||||
private void OnTriggered()
|
||||
{
|
||||
if (Triggered != null)
|
||||
{
|
||||
Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SystemEventTrigger
|
||||
/// </summary>
|
||||
public class SystemEventTrigger : ITaskTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the system event.
|
||||
/// </summary>
|
||||
/// <value>The system event.</value>
|
||||
public SystemEvent SystemEvent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution properties of this task.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The execution properties of this task.
|
||||
/// </value>
|
||||
public TaskExecutionOptions TaskOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
|
||||
{
|
||||
switch (SystemEvent)
|
||||
{
|
||||
case SystemEvent.WakeFromSleep:
|
||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops waiting for the trigger action
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the PowerModeChanged event of the SystemEvents control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="PowerModeChangedEventArgs" /> instance containing the event data.</param>
|
||||
async void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
if (e.Mode == PowerModes.Resume && SystemEvent == SystemEvent.WakeFromSleep)
|
||||
{
|
||||
// This value is a bit arbitrary, but add a delay to help ensure network connections have been restored before running the task
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
|
||||
OnTriggered();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [triggered].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [triggered].
|
||||
/// </summary>
|
||||
private void OnTriggered()
|
||||
{
|
||||
if (Triggered != null)
|
||||
{
|
||||
Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that encomposases all common task run properties.
|
||||
/// </summary>
|
||||
public class TaskExecutionOptions
|
||||
{
|
||||
public int? MaxRuntimeMs { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
|
||||
namespace MediaBrowser.Common.ScheduledTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a task trigger that fires on a weekly basis
|
||||
/// </summary>
|
||||
public class WeeklyTrigger : ITaskTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the time of day to trigger the task to run
|
||||
/// </summary>
|
||||
/// <value>The time of day.</value>
|
||||
public TimeSpan TimeOfDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the day of week.
|
||||
/// </summary>
|
||||
/// <value>The day of week.</value>
|
||||
public DayOfWeek DayOfWeek { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution properties of this task.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The execution properties of this task.
|
||||
/// </value>
|
||||
public TaskExecutionOptions TaskOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timer.
|
||||
/// </summary>
|
||||
/// <value>The timer.</value>
|
||||
private Timer Timer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stars waiting for the trigger action
|
||||
/// </summary>
|
||||
/// <param name="lastResult">The last result.</param>
|
||||
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
|
||||
public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
|
||||
{
|
||||
DisposeTimer();
|
||||
|
||||
var triggerDate = GetNextTriggerDateTime();
|
||||
|
||||
Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.Now, TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next trigger date time.
|
||||
/// </summary>
|
||||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetNextTriggerDateTime()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
// If it's on the same day
|
||||
if (now.DayOfWeek == DayOfWeek)
|
||||
{
|
||||
// It's either later today, or a week from now
|
||||
return now.TimeOfDay < TimeOfDay ? now.Date.Add(TimeOfDay) : now.Date.AddDays(7).Add(TimeOfDay);
|
||||
}
|
||||
|
||||
var triggerDate = now.Date;
|
||||
|
||||
// Walk the date forward until we get to the trigger day
|
||||
while (triggerDate.DayOfWeek != DayOfWeek)
|
||||
{
|
||||
triggerDate = triggerDate.AddDays(1);
|
||||
}
|
||||
|
||||
// Return the trigger date plus the time offset
|
||||
return triggerDate.Add(TimeOfDay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops waiting for the trigger action
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
DisposeTimer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the timer.
|
||||
/// </summary>
|
||||
private void DisposeTimer()
|
||||
{
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [triggered].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [triggered].
|
||||
/// </summary>
|
||||
private void OnTriggered()
|
||||
{
|
||||
if (Triggered != null)
|
||||
{
|
||||
Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user