From 07791d46a571d3d6eed23e98ec0fe1c46ea0d37f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Oct 2016 15:14:57 -0400 Subject: rework scheduled tasks in preparation of common project going portable --- .../BaseApplicationHost.cs | 39 +++++- .../Cryptography/CryptographyProvider.cs | 18 +++ .../HttpClientManager/HttpClientManager.cs | 1 + .../IO/MemoryStreamProvider.cs | 1 + .../MediaBrowser.Common.Implementations.csproj | 6 + .../ScheduledTasks/DailyTrigger.cs | 91 +++++++++++++ .../ScheduledTasks/IntervalTrigger.cs | 112 ++++++++++++++++ .../ScheduledTasks/ScheduledTaskWorker.cs | 148 ++++++++++++++++++--- .../ScheduledTasks/StartupTrigger.cs | 67 ++++++++++ .../ScheduledTasks/SystemEventTrigger.cs | 84 ++++++++++++ .../ScheduledTasks/Tasks/DeleteCacheFileTask.cs | 20 ++- .../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 18 ++- .../ScheduledTasks/Tasks/ReloadLoggerFileTask.cs | 12 +- .../ScheduledTasks/WeeklyTrigger.cs | 116 ++++++++++++++++ 14 files changed, 699 insertions(+), 34 deletions(-) create mode 100644 MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs create mode 100644 MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs create mode 100644 MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs create mode 100644 MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs create mode 100644 MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs create mode 100644 MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index e68fee829d..b1e6a04533 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. /// /// The plugins. - public IEnumerable Plugins { get; protected set; } + public IPlugin[] Plugins { get; protected set; } /// /// Gets or sets the log manager. @@ -174,6 +179,8 @@ namespace MediaBrowser.Common.Implementations /// true if this instance is running as service; otherwise, false. 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(); ApplicationPaths = applicationPaths; @@ -430,7 +440,28 @@ namespace MediaBrowser.Common.Implementations RegisterModules(); ConfigurationManager.AddParts(GetExports()); - Plugins = GetExports(); + Plugins = GetExports().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; } /// @@ -747,7 +778,7 @@ namespace MediaBrowser.Common.Implementations { var list = Plugins.ToList(); list.Remove(plugin); - Plugins = list; + Plugins = list.ToArray(); } /// diff --git a/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs b/MediaBrowser.Common.Implementations/Cryptography/CryptographyProvider.cs new file mode 100644 index 0000000000..81cbaa3aae --- /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 063529cfc8..bad8c5ce5d 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 c429474816..cc3bf07884 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 ebe9ac5c4b..44e4f88bdd 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -91,6 +91,7 @@ + @@ -101,11 +102,16 @@ + + + + + diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs new file mode 100644 index 0000000000..3d33e958de --- /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 +{ + /// + /// Represents a task trigger that fires everyday + /// + public class DailyTrigger : ITaskTrigger + { + /// + /// Get the time of day to trigger the task to run + /// + /// The time of day. + public TimeSpan TimeOfDay { get; set; } + + /// + /// Gets or sets the timer. + /// + /// The timer. + private Timer Timer { get; set; } + + /// + /// Gets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + public TaskExecutionOptions TaskOptions { get; set; } + + /// + /// Stars waiting for the trigger action + /// + /// The last result. + /// if set to true [is application startup]. + 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)); + } + + /// + /// Stops waiting for the trigger action + /// + public void Stop() + { + DisposeTimer(); + } + + /// + /// Disposes the timer. + /// + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// + /// Occurs when [triggered]. + /// + public event EventHandler> Triggered; + + /// + /// Called when [triggered]. + /// + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs(TaskOptions)); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs new file mode 100644 index 0000000000..8038d5551d --- /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 +{ + /// + /// Represents a task trigger that runs repeatedly on an interval + /// + public class IntervalTrigger : ITaskTrigger + { + /// + /// Gets or sets the interval. + /// + /// The interval. + public TimeSpan Interval { get; set; } + + /// + /// Gets or sets the timer. + /// + /// The timer. + private Timer Timer { get; set; } + + /// + /// Gets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + public TaskExecutionOptions TaskOptions { get; set; } + + private DateTime _lastStartDate; + + /// + /// Stars waiting for the trigger action + /// + /// The last result. + /// if set to true [is application startup]. + 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)); + } + + /// + /// Stops waiting for the trigger action + /// + public void Stop() + { + DisposeTimer(); + } + + /// + /// Disposes the timer. + /// + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// + /// Occurs when [triggered]. + /// + public event EventHandler> Triggered; + + /// + /// Called when [triggered]. + /// + private void OnTriggered() + { + DisposeTimer(); + + if (Triggered != null) + { + _lastStartDate = DateTime.UtcNow; + Triggered(this, new GenericEventArgs(TaskOptions)); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index ced85780f8..f3ed95c812 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -232,13 +232,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// /// The _triggers /// - private List _triggers; + private Tuple[] _triggers; /// /// Gets the triggers that define when the task will run /// /// The triggers. - /// value - public IEnumerable Triggers + private Tuple[] InternalTriggers { get { @@ -257,11 +256,33 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks DisposeTriggers(); } - _triggers = value.ToList(); + _triggers = value.ToArray(); ReloadTriggerEvents(false); + } + } - SaveTriggers(_triggers); + /// + /// Gets the triggers that define when the task will run + /// + /// The triggers. + /// value + 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(i, GetTrigger(i))).ToArray(); } } @@ -304,8 +325,10 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// if set to true [is application startup]. 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. /// /// IEnumerable{BaseTaskTrigger}. - private List LoadTriggers() + private Tuple[] LoadTriggers() + { + var settings = LoadTriggerSettings(); + + return settings.Select(i => new Tuple(i, GetTrigger(i))).ToArray(); + } + + private TaskTriggerInfo[] LoadTriggerSettings() { try { return JsonSerializer.DeserializeFromFile>(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. /// /// The triggers. - private void SaveTriggers(IEnumerable 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); } /// @@ -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) { @@ -655,13 +680,98 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks } } + /// + /// Converts a TaskTriggerInfo into a concrete BaseTaskTrigger + /// + /// The info. + /// BaseTaskTrigger. + /// + /// Invalid trigger type: + info.Type + 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); + } + /// /// Disposes each trigger /// 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 0000000000..41f58a7ad5 --- /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 +{ + /// + /// Class StartupTaskTrigger + /// + public class StartupTrigger : ITaskTrigger + { + public int DelayMs { get; set; } + + /// + /// Gets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + public TaskExecutionOptions TaskOptions { get; set; } + + public StartupTrigger() + { + DelayMs = 3000; + } + + /// + /// Stars waiting for the trigger action + /// + /// The last result. + /// if set to true [is application startup]. + public async void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup) + { + if (isApplicationStartup) + { + await Task.Delay(DelayMs).ConfigureAwait(false); + + OnTriggered(); + } + } + + /// + /// Stops waiting for the trigger action + /// + public void Stop() + { + } + + /// + /// Occurs when [triggered]. + /// + public event EventHandler> Triggered; + + /// + /// Called when [triggered]. + /// + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs(TaskOptions)); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs new file mode 100644 index 0000000000..9972dc8044 --- /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 +{ + /// + /// Class SystemEventTrigger + /// + public class SystemEventTrigger : ITaskTrigger + { + /// + /// Gets or sets the system event. + /// + /// The system event. + public SystemEvent SystemEvent { get; set; } + + /// + /// Gets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + public TaskExecutionOptions TaskOptions { get; set; } + + /// + /// Stars waiting for the trigger action + /// + /// The last result. + /// if set to true [is application startup]. + public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup) + { + switch (SystemEvent) + { + case SystemEvent.WakeFromSleep: + SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + break; + } + } + + /// + /// Stops waiting for the trigger action + /// + public void Stop() + { + SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; + } + + /// + /// Handles the PowerModeChanged event of the SystemEvents control. + /// + /// The source of the event. + /// The instance containing the event data. + 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(); + } + } + + /// + /// Occurs when [triggered]. + /// + public event EventHandler> Triggered; + + /// + /// Called when [triggered]. + /// + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs(TaskOptions)); + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index 0a2b9222a0..3d07047812 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 /// /// IEnumerable{BaseTaskTrigger}. - public IEnumerable GetDefaultTriggers() + public IEnumerable 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 /// The progress. private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress 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"; } + } + /// /// Gets the description. /// @@ -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 b18ea03b1e..f7cbe8dcba 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 /// /// IEnumerable{BaseTaskTrigger}. - public IEnumerable GetDefaultTriggers() + public IEnumerable 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"; } + } + /// /// Gets the name of the task /// @@ -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 78f60632fa..3c33df832e 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. /// /// IEnumerable{BaseTaskTrigger}. - public IEnumerable GetDefaultTriggers() + public IEnumerable 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; } + /// /// Gets the description. /// @@ -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 0000000000..318802e07d --- /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 +{ + /// + /// Represents a task trigger that fires on a weekly basis + /// + public class WeeklyTrigger : ITaskTrigger + { + /// + /// Get the time of day to trigger the task to run + /// + /// The time of day. + public TimeSpan TimeOfDay { get; set; } + + /// + /// Gets or sets the day of week. + /// + /// The day of week. + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + public TaskExecutionOptions TaskOptions { get; set; } + + /// + /// Gets or sets the timer. + /// + /// The timer. + private Timer Timer { get; set; } + + /// + /// Stars waiting for the trigger action + /// + /// The last result. + /// if set to true [is application startup]. + 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)); + } + + /// + /// Gets the next trigger date time. + /// + /// DateTime. + 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); + } + + /// + /// Stops waiting for the trigger action + /// + public void Stop() + { + DisposeTimer(); + } + + /// + /// Disposes the timer. + /// + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// + /// Occurs when [triggered]. + /// + public event EventHandler> Triggered; + + /// + /// Called when [triggered]. + /// + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs(TaskOptions)); + } + } + } +} -- cgit v1.2.3 From 0f8ccfaf496c3c761c06285574048f8866ef692c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Oct 2016 15:47:34 -0400 Subject: prep for portable common --- .../ScheduledTasks/ScheduledTaskService.cs | 1 - .../ScheduledTasksWebSocketListener.cs | 3 +- .../BaseApplicationHost.cs | 32 +++++---- MediaBrowser.Common/MediaBrowser.Common.csproj | 10 +-- .../ScheduledTasks/IScheduledTaskWorker.cs | 77 -------------------- MediaBrowser.Common/ScheduledTasks/ITaskManager.cs | 81 ---------------------- MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs | 36 ---------- .../ScheduledTasks/ScheduledTaskHelpers.cs | 53 -------------- .../ScheduledTasks/TaskCompletionEventArgs.cs | 12 ---- .../Entities/Audio/MusicArtist.cs | 1 + .../Entities/Audio/MusicGenre.cs | 1 + MediaBrowser.Controller/Entities/BaseItem.cs | 1 + MediaBrowser.Controller/Entities/GameGenre.cs | 1 + MediaBrowser.Controller/Entities/Genre.cs | 1 + MediaBrowser.Controller/Entities/Person.cs | 1 + MediaBrowser.Controller/Entities/Studio.cs | 1 + .../Extensions/BaseExtensions.cs | 25 ------- .../Extensions/StringExtensions.cs | 22 ++++++ .../MediaBrowser.Controller.csproj | 2 +- MediaBrowser.Model/Dlna/ConditionProcessor.cs | 6 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 2 +- MediaBrowser.Model/Drawing/ImageSize.cs | 6 +- MediaBrowser.Model/Extensions/BoolHelper.cs | 16 ----- MediaBrowser.Model/Extensions/DoubleHelper.cs | 21 ------ MediaBrowser.Model/Extensions/FloatHelper.cs | 18 ----- MediaBrowser.Model/MediaBrowser.Model.csproj | 8 ++- MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs | 76 ++++++++++++++++++++ MediaBrowser.Model/Tasks/ITaskManager.cs | 80 +++++++++++++++++++++ MediaBrowser.Model/Tasks/ITaskTrigger.cs | 35 ++++++++++ MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs | 52 ++++++++++++++ .../Tasks/TaskCompletionEventArgs.cs | 11 +++ .../MediaInfo/SubtitleScheduledTask.cs | 1 - MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 2 +- .../EntryPoints/ServerEventNotifier.cs | 1 + .../FileOrganization/FileOrganizationNotifier.cs | 1 + .../FileOrganization/FileOrganizationService.cs | 1 + .../IO/FileRefresher.cs | 1 + .../IO/LibraryMonitor.cs | 1 + .../Library/LibraryManager.cs | 1 + .../Library/SearchEngine.cs | 1 + .../LiveTv/LiveTvManager.cs | 1 + .../Persistence/SqliteItemRepository.cs | 1 + .../Sync/SyncManager.cs | 1 + .../Migrations/DbMigration.cs | 1 + 44 files changed, 332 insertions(+), 374 deletions(-) delete mode 100644 MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs delete mode 100644 MediaBrowser.Common/ScheduledTasks/ITaskManager.cs delete mode 100644 MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs delete mode 100644 MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs delete mode 100644 MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs delete mode 100644 MediaBrowser.Controller/Extensions/BaseExtensions.cs create mode 100644 MediaBrowser.Controller/Extensions/StringExtensions.cs delete mode 100644 MediaBrowser.Model/Extensions/BoolHelper.cs delete mode 100644 MediaBrowser.Model/Extensions/DoubleHelper.cs delete mode 100644 MediaBrowser.Model/Extensions/FloatHelper.cs create mode 100644 MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs create mode 100644 MediaBrowser.Model/Tasks/ITaskManager.cs create mode 100644 MediaBrowser.Model/Tasks/ITaskTrigger.cs create mode 100644 MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs create mode 100644 MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index 287b87f776..29b3988ade 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Tasks; using ServiceStack; diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 5d3465c580..6e64345b9f 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index b1e6a04533..baf6d85af6 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -445,20 +445,28 @@ namespace MediaBrowser.Common.Implementations private IPlugin LoadPlugin(IPlugin plugin) { - var assemblyPlugin = plugin as IPluginAssembly; - - if (assemblyPlugin != null) + try { - var assembly = plugin.GetType().Assembly; - var assemblyName = assembly.GetName(); + var assemblyPlugin = plugin as IPluginAssembly; - var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]; - var assemblyId = new Guid(attribute.Value); + if (assemblyPlugin != null) + { + var assembly = plugin.GetType().Assembly; + var assemblyName = assembly.GetName(); - var assemblyFileName = assemblyName.Name + ".dll"; - var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName); + var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]; + var assemblyId = new Guid(attribute.Value); - assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId); + var assemblyFileName = assemblyName.Name + ".dll"; + var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName); + + assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId); + } + } + catch (Exception ex) + { + Logger.ErrorException("Error loading plugin {0}", ex, plugin.GetType().FullName); + return null; } return plugin; @@ -596,7 +604,7 @@ namespace MediaBrowser.Common.Implementations } catch (Exception ex) { - Logger.ErrorException("Error creating {0}", ex, type.Name); + Logger.ErrorException("Error creating {0}", ex, type.FullName); throw; } @@ -615,7 +623,7 @@ namespace MediaBrowser.Common.Implementations } catch (Exception ex) { - Logger.ErrorException("Error creating {0}", ex, type.Name); + Logger.ErrorException("Error creating {0}", ex, type.FullName); // Don't blow up in release mode return null; } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 94ebf8dc94..931ac7227f 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -1,5 +1,5 @@  - + Debug @@ -13,7 +13,8 @@ ..\ 10.0.0 2.0 - v4.5 + v4.6 + true @@ -67,13 +68,8 @@ - - - - - diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs deleted file mode 100644 index a3a28684dd..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs +++ /dev/null @@ -1,77 +0,0 @@ -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Tasks; -using System; - -namespace MediaBrowser.Common.ScheduledTasks -{ - /// - /// Interface IScheduledTaskWorker - /// - public interface IScheduledTaskWorker : IDisposable - { - /// - /// Occurs when [task progress]. - /// - event EventHandler> TaskProgress; - - /// - /// Gets or sets the scheduled task. - /// - /// The scheduled task. - IScheduledTask ScheduledTask { get; } - - /// - /// Gets the last execution result. - /// - /// The last execution result. - TaskResult LastExecutionResult { get; } - - /// - /// Gets the name. - /// - /// The name. - string Name { get; } - - /// - /// Gets the description. - /// - /// The description. - string Description { get; } - - /// - /// Gets the category. - /// - /// The category. - string Category { get; } - - /// - /// Gets the state. - /// - /// The state. - TaskState State { get; } - - /// - /// Gets the current progress. - /// - /// The current progress. - double? CurrentProgress { get; } - - /// - /// Gets the triggers that define when the task will run - /// - /// The triggers. - /// value - TaskTriggerInfo[] Triggers { get; set; } - - /// - /// Gets the unique id. - /// - /// The unique id. - string Id { get; } - - /// - /// Reloads the trigger events. - /// - void ReloadTriggerEvents(); - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs deleted file mode 100644 index e557a6b2c3..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs +++ /dev/null @@ -1,81 +0,0 @@ -using MediaBrowser.Model.Events; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using MediaBrowser.Model.Tasks; - -namespace MediaBrowser.Common.ScheduledTasks -{ - public interface ITaskManager : IDisposable - { - /// - /// Gets the list of Scheduled Tasks - /// - /// The scheduled tasks. - IScheduledTaskWorker[] ScheduledTasks { get; } - - /// - /// Cancels if running and queue. - /// - /// - /// Task options. - void CancelIfRunningAndQueue(TaskExecutionOptions options) - where T : IScheduledTask; - - /// - /// Cancels if running and queue. - /// - /// - void CancelIfRunningAndQueue() - where T : IScheduledTask; - - /// - /// Cancels if running. - /// - /// - void CancelIfRunning() - where T : IScheduledTask; - - /// - /// Queues the scheduled task. - /// - /// - /// Task options. - void QueueScheduledTask(TaskExecutionOptions options) - where T : IScheduledTask; - - /// - /// Queues the scheduled task. - /// - /// - void QueueScheduledTask() - where T : IScheduledTask; - - void QueueIfNotRunning() - where T : IScheduledTask; - - /// - /// Queues the scheduled task. - /// - /// The task. - /// The task run options. - void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options = null); - - /// - /// Adds the tasks. - /// - /// The tasks. - void AddTasks(IEnumerable tasks); - - void Cancel(IScheduledTaskWorker task); - Task Execute(IScheduledTaskWorker task, TaskExecutionOptions options = null); - - void Execute() - where T : IScheduledTask; - - event EventHandler> TaskExecuting; - event EventHandler TaskCompleted; - - bool SuspendTriggers { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs deleted file mode 100644 index d6ca63ad7e..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs +++ /dev/null @@ -1,36 +0,0 @@ -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Tasks; -using System; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Common.ScheduledTasks -{ - /// - /// Interface ITaskTrigger - /// - public interface ITaskTrigger - { - /// - /// Fires when the trigger condition is satisfied and the task should run - /// - event EventHandler> Triggered; - - /// - /// Stars waiting for the trigger action - /// - void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup); - - /// - /// Stops waiting for the trigger action - /// - void Stop(); - - /// - /// Gets or sets the execution properties of this task. - /// - /// - /// The execution properties of this task. - /// - TaskExecutionOptions TaskOptions { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs deleted file mode 100644 index fe45f16213..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs +++ /dev/null @@ -1,53 +0,0 @@ -using MediaBrowser.Model.Tasks; -using System; -using System.Linq; - -namespace MediaBrowser.Common.ScheduledTasks -{ - /// - /// Class ScheduledTaskHelpers - /// - public static class ScheduledTaskHelpers - { - /// - /// Gets the task info. - /// - /// The task. - /// TaskInfo. - public static TaskInfo GetTaskInfo(IScheduledTaskWorker task) - { - var isHidden = false; - - var configurableTask = task.ScheduledTask as IConfigurableScheduledTask; - - if (configurableTask != null) - { - isHidden = configurableTask.IsHidden; - } - - string key = task.ScheduledTask.Key; - - var triggers = task.Triggers - .OrderBy(i => i.Type) - .ThenBy(i => i.DayOfWeek ?? DayOfWeek.Sunday) - .ThenBy(i => i.TimeOfDayTicks ?? 0) - .ToList(); - - return new TaskInfo - { - Name = task.Name, - CurrentProgressPercentage = task.CurrentProgress, - State = task.State, - Id = task.Id, - LastExecutionResult = task.LastExecutionResult, - - Triggers = triggers, - - Description = task.Description, - Category = task.Category, - IsHidden = isHidden, - Key = key - }; - } - } -} diff --git a/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs b/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs deleted file mode 100644 index 2974806d02..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MediaBrowser.Model.Tasks; -using System; - -namespace MediaBrowser.Common.ScheduledTasks -{ - public class TaskCompletionEventArgs : EventArgs - { - public IScheduledTaskWorker Task { get; set; } - - public TaskResult Result { get; set; } - } -} diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 07cf43c5bb..4fdd809e0d 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities.Audio { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index a111166aca..cb17ea2659 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.Serialization; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities.Audio { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 9aad91a28c..4836aca8b4 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -26,6 +26,7 @@ using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Providers; diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 2987a9a077..545bef44c1 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.Serialization; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index cde9c6ce41..6fefdfa558 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index d7acdb65ec..6f7a32a663 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -6,6 +6,7 @@ using System.Runtime.Serialization; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 773250ad9e..114c141554 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.Serialization; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Extensions/BaseExtensions.cs b/MediaBrowser.Controller/Extensions/BaseExtensions.cs deleted file mode 100644 index 84a9b1524e..0000000000 --- a/MediaBrowser.Controller/Extensions/BaseExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Text; -using MediaBrowser.Model.Cryptography; - -namespace MediaBrowser.Controller.Extensions -{ - /// - /// Class BaseExtensions - /// - public static class BaseExtensions - { - public static ICryptographyProvider CryptographyProvider { get; set; } - - public static string RemoveDiacritics(this string text) - { - return String.Concat( - text.Normalize(NormalizationForm.FormD) - .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != - UnicodeCategory.NonSpacingMark) - ).Normalize(NormalizationForm.FormC); - } - } -} diff --git a/MediaBrowser.Controller/Extensions/StringExtensions.cs b/MediaBrowser.Controller/Extensions/StringExtensions.cs new file mode 100644 index 0000000000..4f58d1bc52 --- /dev/null +++ b/MediaBrowser.Controller/Extensions/StringExtensions.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace MediaBrowser.Controller.Extensions +{ + /// + /// Class BaseExtensions + /// + public static class StringExtensions + { + public static string RemoveDiacritics(this string text) + { + return String.Concat( + text.Normalize(NormalizationForm.FormD) + .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != + UnicodeCategory.NonSpacingMark) + ).Normalize(NormalizationForm.FormC); + } + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 46277a7839..670b08a3fa 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -165,7 +165,7 @@ - + diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index 6628e290e7..1fbb4ffa17 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Model.Dlna } bool expected; - if (BoolHelper.TryParseCultureInvariant(condition.Value, out expected)) + if (bool.TryParse(condition.Value, out expected)) { switch (condition.Condition) { @@ -196,7 +196,7 @@ namespace MediaBrowser.Model.Dlna } float expected; - if (FloatHelper.TryParseCultureInvariant(condition.Value, out expected)) + if (float.TryParse(condition.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out expected)) { switch (condition.Condition) { @@ -225,7 +225,7 @@ namespace MediaBrowser.Model.Dlna } double expected; - if (DoubleHelper.TryParseCultureInvariant(condition.Value, out expected)) + if (double.TryParse(condition.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out expected)) { switch (condition.Condition) { diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index a3e447d04a..06a883c069 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1111,7 +1111,7 @@ namespace MediaBrowser.Model.Dlna case ProfileConditionValue.VideoFramerate: { float num; - if (FloatHelper.TryParseCultureInvariant(value, out num)) + if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out num)) { item.MaxFramerate = num; } diff --git a/MediaBrowser.Model/Drawing/ImageSize.cs b/MediaBrowser.Model/Drawing/ImageSize.cs index 5ed6e72933..8cf09da185 100644 --- a/MediaBrowser.Model/Drawing/ImageSize.cs +++ b/MediaBrowser.Model/Drawing/ImageSize.cs @@ -1,4 +1,4 @@ -using MediaBrowser.Model.Extensions; +using System.Globalization; namespace MediaBrowser.Model.Drawing { @@ -71,12 +71,12 @@ namespace MediaBrowser.Model.Drawing { double val; - if (DoubleHelper.TryParseCultureInvariant(parts[0], out val)) + if (double.TryParse(parts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out val)) { _width = val; } - if (DoubleHelper.TryParseCultureInvariant(parts[1], out val)) + if (double.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out val)) { _height = val; } diff --git a/MediaBrowser.Model/Extensions/BoolHelper.cs b/MediaBrowser.Model/Extensions/BoolHelper.cs deleted file mode 100644 index 5b61f864b0..0000000000 --- a/MediaBrowser.Model/Extensions/BoolHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace MediaBrowser.Model.Extensions -{ - public static class BoolHelper - { - /// - /// Tries the parse culture invariant. - /// - /// The s. - /// The result. - /// true if XXXX, false otherwise. - public static bool TryParseCultureInvariant(string s, out bool result) - { - return bool.TryParse(s, out result); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/Extensions/DoubleHelper.cs b/MediaBrowser.Model/Extensions/DoubleHelper.cs deleted file mode 100644 index bcaf2d7800..0000000000 --- a/MediaBrowser.Model/Extensions/DoubleHelper.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Globalization; - -namespace MediaBrowser.Model.Extensions -{ - /// - /// Isolating these helpers allow this entire project to be easily converted to Java - /// - public static class DoubleHelper - { - /// - /// Tries the parse culture invariant. - /// - /// The s. - /// The result. - /// true if XXXX, false otherwise. - public static bool TryParseCultureInvariant(string s, out double result) - { - return double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result); - } - } -} diff --git a/MediaBrowser.Model/Extensions/FloatHelper.cs b/MediaBrowser.Model/Extensions/FloatHelper.cs deleted file mode 100644 index 171eccf931..0000000000 --- a/MediaBrowser.Model/Extensions/FloatHelper.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Globalization; - -namespace MediaBrowser.Model.Extensions -{ - public static class FloatHelper - { - /// - /// Tries the parse culture invariant. - /// - /// The s. - /// The result. - /// true if XXXX, false otherwise. - public static bool TryParseCultureInvariant(string s, out float result) - { - return float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index e5aac6c061..c0ff5464e8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -144,8 +144,6 @@ - - @@ -218,7 +216,6 @@ - @@ -389,6 +386,11 @@ + + + + + diff --git a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs new file mode 100644 index 0000000000..415207f8f0 --- /dev/null +++ b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs @@ -0,0 +1,76 @@ +using System; +using MediaBrowser.Model.Events; + +namespace MediaBrowser.Model.Tasks +{ + /// + /// Interface IScheduledTaskWorker + /// + public interface IScheduledTaskWorker : IDisposable + { + /// + /// Occurs when [task progress]. + /// + event EventHandler> TaskProgress; + + /// + /// Gets or sets the scheduled task. + /// + /// The scheduled task. + IScheduledTask ScheduledTask { get; } + + /// + /// Gets the last execution result. + /// + /// The last execution result. + TaskResult LastExecutionResult { get; } + + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + + /// + /// Gets the description. + /// + /// The description. + string Description { get; } + + /// + /// Gets the category. + /// + /// The category. + string Category { get; } + + /// + /// Gets the state. + /// + /// The state. + TaskState State { get; } + + /// + /// Gets the current progress. + /// + /// The current progress. + double? CurrentProgress { get; } + + /// + /// Gets the triggers that define when the task will run + /// + /// The triggers. + /// value + TaskTriggerInfo[] Triggers { get; set; } + + /// + /// Gets the unique id. + /// + /// The unique id. + string Id { get; } + + /// + /// Reloads the trigger events. + /// + void ReloadTriggerEvents(); + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs new file mode 100644 index 0000000000..b6f847febb --- /dev/null +++ b/MediaBrowser.Model/Tasks/ITaskManager.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using MediaBrowser.Model.Events; + +namespace MediaBrowser.Model.Tasks +{ + public interface ITaskManager : IDisposable + { + /// + /// Gets the list of Scheduled Tasks + /// + /// The scheduled tasks. + IScheduledTaskWorker[] ScheduledTasks { get; } + + /// + /// Cancels if running and queue. + /// + /// + /// Task options. + void CancelIfRunningAndQueue(TaskExecutionOptions options) + where T : IScheduledTask; + + /// + /// Cancels if running and queue. + /// + /// + void CancelIfRunningAndQueue() + where T : IScheduledTask; + + /// + /// Cancels if running. + /// + /// + void CancelIfRunning() + where T : IScheduledTask; + + /// + /// Queues the scheduled task. + /// + /// + /// Task options. + void QueueScheduledTask(TaskExecutionOptions options) + where T : IScheduledTask; + + /// + /// Queues the scheduled task. + /// + /// + void QueueScheduledTask() + where T : IScheduledTask; + + void QueueIfNotRunning() + where T : IScheduledTask; + + /// + /// Queues the scheduled task. + /// + /// The task. + /// The task run options. + void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options = null); + + /// + /// Adds the tasks. + /// + /// The tasks. + void AddTasks(IEnumerable tasks); + + void Cancel(IScheduledTaskWorker task); + Task Execute(IScheduledTaskWorker task, TaskExecutionOptions options = null); + + void Execute() + where T : IScheduledTask; + + event EventHandler> TaskExecuting; + event EventHandler TaskCompleted; + + bool SuspendTriggers { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs new file mode 100644 index 0000000000..3beca569cc --- /dev/null +++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs @@ -0,0 +1,35 @@ +using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Model.Tasks +{ + /// + /// Interface ITaskTrigger + /// + public interface ITaskTrigger + { + /// + /// Fires when the trigger condition is satisfied and the task should run + /// + event EventHandler> Triggered; + + /// + /// Stars waiting for the trigger action + /// + void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup); + + /// + /// Stops waiting for the trigger action + /// + void Stop(); + + /// + /// Gets or sets the execution properties of this task. + /// + /// + /// The execution properties of this task. + /// + TaskExecutionOptions TaskOptions { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs b/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs new file mode 100644 index 0000000000..66f5294e7c --- /dev/null +++ b/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs @@ -0,0 +1,52 @@ +using System; +using System.Linq; + +namespace MediaBrowser.Model.Tasks +{ + /// + /// Class ScheduledTaskHelpers + /// + public static class ScheduledTaskHelpers + { + /// + /// Gets the task info. + /// + /// The task. + /// TaskInfo. + public static TaskInfo GetTaskInfo(IScheduledTaskWorker task) + { + var isHidden = false; + + var configurableTask = task.ScheduledTask as IConfigurableScheduledTask; + + if (configurableTask != null) + { + isHidden = configurableTask.IsHidden; + } + + string key = task.ScheduledTask.Key; + + var triggers = task.Triggers + .OrderBy(i => i.Type) + .ThenBy(i => i.DayOfWeek ?? DayOfWeek.Sunday) + .ThenBy(i => i.TimeOfDayTicks ?? 0) + .ToList(); + + return new TaskInfo + { + Name = task.Name, + CurrentProgressPercentage = task.CurrentProgress, + State = task.State, + Id = task.Id, + LastExecutionResult = task.LastExecutionResult, + + Triggers = triggers, + + Description = task.Description, + Category = task.Category, + IsHidden = isHidden, + Key = key + }; + } + } +} diff --git a/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs b/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs new file mode 100644 index 0000000000..be9eaa613d --- /dev/null +++ b/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs @@ -0,0 +1,11 @@ +using System; + +namespace MediaBrowser.Model.Tasks +{ + public class TaskCompletionEventArgs : EventArgs + { + public IScheduledTaskWorker Task { get; set; } + + public TaskResult Result { get; set; } + } +} diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs index f05bf3ab81..eaaab22fdb 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index e038a3d286..fdea1b205a 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -11,9 +11,9 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Providers.TV { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 3ea8417f86..9fafc561f2 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -13,6 +13,7 @@ using MediaBrowser.Model.Sync; using System; using System.Collections.Generic; using System.Threading; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.EntryPoints { diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs index 5c3814f669..940730b3b2 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs @@ -7,6 +7,7 @@ using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Logging; using System; using System.Threading; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.FileOrganization { diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index a42eba6cae..9aa49946d8 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -18,6 +18,7 @@ using CommonIO; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Events; using MediaBrowser.Common.Events; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.FileOrganization { diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index e689514c5b..1c9a057537 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -12,6 +12,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Tasks; using MediaBrowser.Server.Implementations.ScheduledTasks; namespace MediaBrowser.Server.Implementations.IO diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 76f0e6a1d9..36d9120389 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.IO { diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 6ccfa13ec9..cf175f8617 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -43,6 +43,7 @@ using MediaBrowser.Server.Implementations.Library.Resolvers; using SortOrder = MediaBrowser.Model.Entities.SortOrder; using VideoResolver = MediaBrowser.Naming.Video.VideoResolver; using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.Library { diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 3dff16e24a..c266fb191b 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Server.Implementations.Library { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 7c75abeec4..3f8eb90250 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -35,6 +35,7 @@ using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Events; using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Tasks; using MediaBrowser.Server.Implementations.LiveTv.Listings; namespace MediaBrowser.Server.Implementations.LiveTv diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c76cbf8aea..e6512f4dfd 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -26,6 +26,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Server.Implementations.Devices; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index eaf129e637..6bdb1692ec 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -31,6 +31,7 @@ using System.Threading.Tasks; using CommonIO; using MediaBrowser.Common.IO; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Server.Implementations.Sync { diff --git a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs index 6bcdcca879..5705b3a59a 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Tasks; using MediaBrowser.Server.Implementations.Persistence; namespace MediaBrowser.Server.Startup.Common.Migrations -- cgit v1.2.3