aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Common.Implementations')
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationHost.cs39
-rw-r--r--MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs18
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs1
-rw-r--r--MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs1
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj6
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs91
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs112
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs148
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs67
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs84
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs20
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs18
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs12
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs116
14 files changed, 699 insertions, 34 deletions
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
index e68fee829..b1e6a0453 100644
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
@@ -26,11 +26,16 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Implementations.Cryptography;
using MediaBrowser.Common.IO;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.Tasks;
namespace MediaBrowser.Common.Implementations
{
@@ -67,7 +72,7 @@ namespace MediaBrowser.Common.Implementations
/// Gets or sets the plugins.
/// </summary>
/// <value>The plugins.</value>
- public IEnumerable<IPlugin> Plugins { get; protected set; }
+ public IPlugin[] Plugins { get; protected set; }
/// <summary>
/// Gets or sets the log manager.
@@ -174,6 +179,8 @@ namespace MediaBrowser.Common.Implementations
/// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
public abstract bool IsRunningAsService { get; }
+ protected ICryptographyProvider CryptographyProvider = new CryptographyProvider();
+
private DeviceId _deviceId;
public string SystemId
{
@@ -202,7 +209,10 @@ namespace MediaBrowser.Common.Implementations
ILogManager logManager,
IFileSystem fileSystem)
{
- XmlSerializer = new XmlSerializer (fileSystem, logManager.GetLogger("XmlSerializer"));
+ // hack alert, until common can target .net core
+ BaseExtensions.CryptographyProvider = CryptographyProvider;
+
+ XmlSerializer = new XmlSerializer (fileSystem, logManager.GetLogger("XmlSerializer"));
FailedAssemblies = new List<string>();
ApplicationPaths = applicationPaths;
@@ -430,7 +440,28 @@ namespace MediaBrowser.Common.Implementations
RegisterModules();
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
- Plugins = GetExports<IPlugin>();
+ Plugins = GetExports<IPlugin>().Select(LoadPlugin).Where(i => i != null).ToArray();
+ }
+
+ private IPlugin LoadPlugin(IPlugin plugin)
+ {
+ var assemblyPlugin = plugin as IPluginAssembly;
+
+ if (assemblyPlugin != null)
+ {
+ var assembly = plugin.GetType().Assembly;
+ var assemblyName = assembly.GetName();
+
+ var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
+ var assemblyId = new Guid(attribute.Value);
+
+ var assemblyFileName = assemblyName.Name + ".dll";
+ var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName);
+
+ assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId);
+ }
+
+ return plugin;
}
/// <summary>
@@ -747,7 +778,7 @@ namespace MediaBrowser.Common.Implementations
{
var list = Plugins.ToList();
list.Remove(plugin);
- Plugins = list;
+ Plugins = list.ToArray();
}
/// <summary>
diff --git a/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs b/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs
new file mode 100644
index 000000000..81cbaa3aa
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Security.Cryptography;
+using System.Text;
+using MediaBrowser.Model.Cryptography;
+
+namespace MediaBrowser.Common.Implementations.Cryptography
+{
+ public class CryptographyProvider : ICryptographyProvider
+ {
+ public Guid GetMD5(string str)
+ {
+ using (var provider = MD5.Create())
+ {
+ return new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(str)));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 063529cfc..bad8c5ce5 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -18,6 +18,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.IO;
namespace MediaBrowser.Common.Implementations.HttpClientManager
{
diff --git a/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs b/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs
index c42947481..cc3bf0788 100644
--- a/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs
+++ b/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs
@@ -1,5 +1,6 @@
using System.IO;
using MediaBrowser.Common.IO;
+using MediaBrowser.Model.IO;
using Microsoft.IO;
namespace MediaBrowser.Common.Implementations.IO
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index ebe9ac5c4..44e4f88bd 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -91,6 +91,7 @@
<Compile Include="BaseApplicationPaths.cs" />
<Compile Include="Configuration\BaseConfigurationManager.cs" />
<Compile Include="Configuration\ConfigurationHelper.cs" />
+ <Compile Include="Cryptography\CryptographyProvider.cs" />
<Compile Include="Devices\DeviceId.cs" />
<Compile Include="HttpClientManager\HttpClientInfo.cs" />
<Compile Include="HttpClientManager\HttpClientManager.cs" />
@@ -101,11 +102,16 @@
<Compile Include="Logging\NlogManager.cs" />
<Compile Include="Networking\BaseNetworkManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ScheduledTasks\DailyTrigger.cs" />
+ <Compile Include="ScheduledTasks\IntervalTrigger.cs" />
<Compile Include="ScheduledTasks\ScheduledTaskWorker.cs" />
+ <Compile Include="ScheduledTasks\StartupTrigger.cs" />
+ <Compile Include="ScheduledTasks\SystemEventTrigger.cs" />
<Compile Include="ScheduledTasks\TaskManager.cs" />
<Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" />
<Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" />
<Compile Include="ScheduledTasks\Tasks\ReloadLoggerFileTask.cs" />
+ <Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
<Compile Include="Security\MbAdmin.cs" />
<Compile Include="Security\MBLicenseFile.cs" />
<Compile Include="Security\PluginSecurityManager.cs" />
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
new file mode 100644
index 000000000..3d33e958d
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
@@ -0,0 +1,91 @@
+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));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
new file mode 100644
index 000000000..8038d5551
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
@@ -0,0 +1,112 @@
+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));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index ced85780f..f3ed95c81 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -232,13 +232,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <summary>
/// The _triggers
/// </summary>
- private List<ITaskTrigger> _triggers;
+ private Tuple<TaskTriggerInfo,ITaskTrigger>[] _triggers;
/// <summary>
/// Gets the triggers that define when the task will run
/// </summary>
/// <value>The triggers.</value>
- /// <exception cref="System.ArgumentNullException">value</exception>
- public IEnumerable<ITaskTrigger> Triggers
+ private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers
{
get
{
@@ -257,11 +256,33 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
DisposeTriggers();
}
- _triggers = value.ToList();
+ _triggers = value.ToArray();
ReloadTriggerEvents(false);
+ }
+ }
- SaveTriggers(_triggers);
+ /// <summary>
+ /// Gets the triggers that define when the task will run
+ /// </summary>
+ /// <value>The triggers.</value>
+ /// <exception cref="System.ArgumentNullException">value</exception>
+ public TaskTriggerInfo[] Triggers
+ {
+ get
+ {
+ return InternalTriggers.Select(i => i.Item1).ToArray();
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ SaveTriggers(value);
+
+ InternalTriggers = value.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
}
}
@@ -304,8 +325,10 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
private void ReloadTriggerEvents(bool isApplicationStartup)
{
- foreach (var trigger in Triggers)
+ foreach (var triggerInfo in InternalTriggers)
{
+ var trigger = triggerInfo.Item2;
+
trigger.Stop();
trigger.Triggered -= trigger_Triggered;
@@ -507,23 +530,29 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// Loads the triggers.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- private List<ITaskTrigger> LoadTriggers()
+ private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers()
+ {
+ var settings = LoadTriggerSettings();
+
+ return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
+ }
+
+ private TaskTriggerInfo[] LoadTriggerSettings()
{
try
{
return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath())
- .Select(ScheduledTaskHelpers.GetTrigger)
- .ToList();
+ .ToArray();
}
catch (FileNotFoundException)
{
// File doesn't exist. No biggie. Return defaults.
- return ScheduledTask.GetDefaultTriggers().ToList();
+ return ScheduledTask.GetDefaultTriggers().ToArray();
}
catch (DirectoryNotFoundException)
{
// File doesn't exist. No biggie. Return defaults.
- return ScheduledTask.GetDefaultTriggers().ToList();
+ return ScheduledTask.GetDefaultTriggers().ToArray();
}
}
@@ -531,13 +560,13 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// Saves the triggers.
/// </summary>
/// <param name="triggers">The triggers.</param>
- private void SaveTriggers(IEnumerable<ITaskTrigger> triggers)
+ private void SaveTriggers(TaskTriggerInfo[] triggers)
{
var path = GetConfigurationFilePath();
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
- JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), path);
+ JsonSerializer.SerializeToFile(triggers, path);
}
/// <summary>
@@ -561,11 +590,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
Id = Id
};
- var hasKey = ScheduledTask as IHasKey;
- if (hasKey != null)
- {
- result.Key = hasKey.Key;
- }
+ result.Key = ScheduledTask.Key;
if (ex != null)
{
@@ -656,12 +681,97 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
}
/// <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);
+ }
+
+ /// <summary>
/// Disposes each trigger
/// </summary>
private void DisposeTriggers()
{
- foreach (var trigger in Triggers)
+ foreach (var triggerInfo in InternalTriggers)
{
+ var trigger = triggerInfo.Item2;
trigger.Triggered -= trigger_Triggered;
trigger.Stop();
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
new file mode 100644
index 000000000..41f58a7ad
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
@@ -0,0 +1,67 @@
+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));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
new file mode 100644
index 000000000..9972dc804
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
@@ -0,0 +1,84 @@
+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));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
index 0a2b9222a..3d0704781 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -8,6 +8,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Tasks;
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
@@ -40,13 +41,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<ITaskTrigger> GetDefaultTriggers()
+ public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- // Until we can vary these default triggers per server and MBT, we need something that makes sense for both
- return new ITaskTrigger[] {
+ return new[] {
// Every so often
- new IntervalTrigger { Interval = TimeSpan.FromHours(24)}
+ new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
@@ -95,7 +95,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
/// <param name="progress">The progress.</param>
private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> progress)
{
- var filesToDelete = _fileSystem.GetFiles(directory, true)
+ var filesToDelete = _fileSystem.GetFiles(directory, true)
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
.ToList();
@@ -168,6 +168,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
get { return "Cache file cleanup"; }
}
+ public string Key
+ {
+ get { return "DeleteCacheFiles"; }
+ }
+
/// <summary>
/// Gets the description.
/// </summary>
@@ -202,5 +207,10 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
get { return true; }
}
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index b18ea03b1..f7cbe8dcb 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Tasks;
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
@@ -36,13 +37,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<ITaskTrigger> GetDefaultTriggers()
+ public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- // Until we can vary these default triggers per server and MBT, we need something that makes sense for both
- return new ITaskTrigger[] {
+ return new[] {
// Every so often
- new IntervalTrigger { Interval = TimeSpan.FromHours(24)}
+ new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
@@ -82,6 +82,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
return Task.FromResult(true);
}
+ public string Key
+ {
+ get { return "CleanLogFiles"; }
+ }
+
/// <summary>
/// Gets the name of the task
/// </summary>
@@ -125,5 +130,10 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
get { return true; }
}
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
index 78f60632f..3c33df832 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Tasks;
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
@@ -39,9 +40,9 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
/// Gets the default triggers.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public IEnumerable<ITaskTrigger> GetDefaultTriggers()
+ public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(0) }; //12am
+ var trigger = new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerDaily, TimeOfDayTicks = TimeSpan.FromHours(0).Ticks }; //12am
return new[] { trigger };
}
@@ -74,6 +75,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
get { return "Start new log file"; }
}
+ public string Key { get; }
+
/// <summary>
/// Gets the description.
/// </summary>
@@ -101,5 +104,10 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
get { return true; }
}
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
new file mode 100644
index 000000000..318802e07
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
@@ -0,0 +1,116 @@
+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));
+ }
+ }
+ }
+}