aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2015-10-26 18:50:19 -0400
committerLuke <luke.pulverenti@gmail.com>2015-10-26 18:50:19 -0400
commit35778ebc02e5931142a1fe31a256b7488a07c5c2 (patch)
treeced0290be8820f5e507b51ca4c5165212b1879d1 /MediaBrowser.Common.Implementations
parentc0dc8d055bfd4d2f58591083beb9e9128357aad6 (diff)
parent8d77308593c3b16b733b0109323770d9dfe7e166 (diff)
Merge pull request #1222 from MediaBrowser/dev
3.0.5768.7
Diffstat (limited to 'MediaBrowser.Common.Implementations')
-rw-r--r--MediaBrowser.Common.Implementations/Archiving/ZipClient.cs19
-rw-r--r--MediaBrowser.Common.Implementations/BaseApplicationHost.cs27
-rw-r--r--MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs36
-rw-r--r--MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs7
-rw-r--r--MediaBrowser.Common.Implementations/Devices/DeviceId.cs18
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs145
-rw-r--r--MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs433
-rw-r--r--MediaBrowser.Common.Implementations/Logging/NlogManager.cs4
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj18
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs22
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs55
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs11
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs3
-rw-r--r--MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs8
-rw-r--r--MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs68
-rw-r--r--MediaBrowser.Common.Implementations/Security/RegRecord.cs1
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs11
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs11
-rw-r--r--MediaBrowser.Common.Implementations/Updates/InstallationManager.cs9
-rw-r--r--MediaBrowser.Common.Implementations/packages.config6
20 files changed, 337 insertions, 575 deletions
diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs
index cdcbc311a1..0009c71937 100644
--- a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs
+++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs
@@ -7,6 +7,8 @@ using SharpCompress.Reader;
using SharpCompress.Reader.Zip;
using System;
using System.IO;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Common.Implementations.Archiving
{
@@ -15,7 +17,14 @@ namespace MediaBrowser.Common.Implementations.Archiving
/// </summary>
public class ZipClient : IZipClient
{
- /// <summary>
+ private IFileSystem _fileSystem;
+
+ public ZipClient(IFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
+ /// <summary>
/// Extracts all.
/// </summary>
/// <param name="sourceFile">The source file.</param>
@@ -23,7 +32,7 @@ namespace MediaBrowser.Common.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
- using (var fileStream = File.OpenRead(sourceFile))
+ using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
}
@@ -73,7 +82,7 @@ namespace MediaBrowser.Common.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
- using (var fileStream = File.OpenRead(sourceFile))
+ using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
}
@@ -112,7 +121,7 @@ namespace MediaBrowser.Common.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
- using (var fileStream = File.OpenRead(sourceFile))
+ using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
}
@@ -150,7 +159,7 @@ namespace MediaBrowser.Common.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
- using (var fileStream = File.OpenRead(sourceFile))
+ using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAllFromRar(fileStream, targetPath, overwriteExistingFiles);
}
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
index 70ed5c3191..6dc97100db 100644
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
@@ -30,6 +30,7 @@ using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations
{
@@ -93,7 +94,7 @@ namespace MediaBrowser.Common.Implementations
/// <summary>
/// The _XML serializer
/// </summary>
- protected readonly IXmlSerializer XmlSerializer = new XmlSerializer();
+ protected readonly IXmlSerializer XmlSerializer;
/// <summary>
/// Gets assemblies that failed to load
@@ -180,7 +181,7 @@ namespace MediaBrowser.Common.Implementations
{
if (_deviceId == null)
{
- _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"));
+ _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager);
}
return _deviceId.Value;
@@ -199,6 +200,7 @@ namespace MediaBrowser.Common.Implementations
ILogManager logManager,
IFileSystem fileSystem)
{
+ XmlSerializer = new MediaBrowser.Common.Implementations.Serialization.XmlSerializer (fileSystem);
FailedAssemblies = new List<string>();
ApplicationPaths = applicationPaths;
@@ -320,7 +322,7 @@ namespace MediaBrowser.Common.Implementations
protected virtual IJsonSerializer CreateJsonSerializer()
{
- return new JsonSerializer();
+ return new JsonSerializer(FileSystemManager);
}
private void SetHttpLimit()
@@ -414,6 +416,8 @@ namespace MediaBrowser.Common.Implementations
/// </summary>
protected virtual void FindParts()
{
+ RegisterModules();
+
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
Plugins = GetExports<IPlugin>();
}
@@ -449,7 +453,7 @@ namespace MediaBrowser.Common.Implementations
RegisterSingleInstance<IApplicationPaths>(ApplicationPaths);
- TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, Logger);
+ TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, Logger, FileSystemManager);
RegisterSingleInstance(JsonSerializer);
RegisterSingleInstance(XmlSerializer);
@@ -473,13 +477,12 @@ namespace MediaBrowser.Common.Implementations
InstallationManager = new InstallationManager(Logger, this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager);
RegisterSingleInstance(InstallationManager);
- ZipClient = new ZipClient();
+ ZipClient = new ZipClient(FileSystemManager);
RegisterSingleInstance(ZipClient);
IsoManager = new IsoManager();
RegisterSingleInstance(IsoManager);
- RegisterModules();
return Task.FromResult (true);
}
@@ -522,6 +525,14 @@ namespace MediaBrowser.Common.Implementations
}
catch (ReflectionTypeLoadException ex)
{
+ if (ex.LoaderExceptions != null)
+ {
+ foreach (var loaderException in ex.LoaderExceptions)
+ {
+ Logger.Error("LoaderException: " + loaderException.Message);
+ }
+ }
+
// If it fails we can still get a list of the Types it was able to resolve
return ex.Types.Where(t => t != null);
}
@@ -581,7 +592,7 @@ namespace MediaBrowser.Common.Implementations
protected void RegisterSingleInstance<T>(T obj, bool manageLifetime = true)
where T : class
{
- Container.RegisterSingle(obj);
+ Container.RegisterSingleton(obj);
if (manageLifetime)
{
@@ -607,7 +618,7 @@ namespace MediaBrowser.Common.Implementations
protected void RegisterSingleInstance<T>(Func<T> func)
where T : class
{
- Container.RegisterSingle(func);
+ Container.RegisterSingleton(func);
}
void IDependencyContainer.Register(Type typeInterface, Type typeImplementation)
diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
index 1b9146644a..7bbc1abd77 100644
--- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
+++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
@@ -9,6 +9,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
+using CommonIO;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Common.Implementations.Configuration
{
@@ -32,7 +34,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
/// Occurs when [configuration updating].
/// </summary>
public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdating;
-
+
/// <summary>
/// Occurs when [named configuration updated].
/// </summary>
@@ -54,6 +56,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
/// </summary>
/// <value>The application paths.</value>
public IApplicationPaths CommonApplicationPaths { get; private set; }
+ public readonly IFileSystem FileSystem;
/// <summary>
/// The _configuration loaded
@@ -87,8 +90,8 @@ namespace MediaBrowser.Common.Implementations.Configuration
}
}
- private ConfigurationStore[] _configurationStores = {};
- private IConfigurationFactory[] _configurationFactories = {};
+ private ConfigurationStore[] _configurationStores = { };
+ private IConfigurationFactory[] _configurationFactories = { };
/// <summary>
/// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class.
@@ -96,10 +99,11 @@ namespace MediaBrowser.Common.Implementations.Configuration
/// <param name="applicationPaths">The application paths.</param>
/// <param name="logManager">The log manager.</param>
/// <param name="xmlSerializer">The XML serializer.</param>
- protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer)
+ protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
{
CommonApplicationPaths = applicationPaths;
XmlSerializer = xmlSerializer;
+ FileSystem = fileSystem;
Logger = logManager.GetLogger(GetType().Name);
UpdateCachePath();
@@ -199,9 +203,19 @@ namespace MediaBrowser.Common.Implementations.Configuration
{
throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
}
+
+ EnsureWriteAccess(newPath);
}
}
+ protected void EnsureWriteAccess(string path)
+ {
+ var file = Path.Combine(path, Guid.NewGuid().ToString());
+
+ FileSystem.WriteAllText(file, string.Empty);
+ FileSystem.DeleteFile(file);
+ }
+
private readonly ConcurrentDictionary<string, object> _configurations = new ConcurrentDictionary<string, object>();
private string GetConfigurationFile(string key)
@@ -215,9 +229,15 @@ namespace MediaBrowser.Common.Implementations.Configuration
{
var file = GetConfigurationFile(key);
- var configurationType = _configurationStores
- .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase))
- .ConfigurationType;
+ var configurationInfo = _configurationStores
+ .FirstOrDefault(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
+
+ if (configurationInfo == null)
+ {
+ throw new ResourceNotFoundException("Configuration with key " + key + " not found.");
+ }
+
+ var configurationType = configurationInfo.ConfigurationType;
lock (_configurationSyncLock)
{
@@ -272,7 +292,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
NewConfiguration = configuration
}, Logger);
-
+
_configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
var path = GetConfigurationFile(key);
diff --git a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
index ff5b8bd599..276da58d4c 100644
--- a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
+++ b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
using System.Linq;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Common.Implementations.Configuration
{
@@ -27,7 +28,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
// Use try/catch to avoid the extra file system lookup using File.Exists
try
{
- buffer = File.ReadAllBytes(path);
+ buffer = File.ReadAllBytes(path);
configuration = xmlSerializer.DeserializeFromBytes(type, buffer);
}
@@ -46,10 +47,10 @@ namespace MediaBrowser.Common.Implementations.Configuration
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes))
{
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
// Save it after load in case we got new items
- File.WriteAllBytes(path, newBytes);
+ File.WriteAllBytes(path, newBytes);
}
return configuration;
diff --git a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs
index 2a1c8877d7..4cad3cd314 100644
--- a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs
+++ b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs
@@ -3,13 +3,16 @@ using MediaBrowser.Model.Logging;
using System;
using System.IO;
using System.Text;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Common.Implementations.Devices
{
public class DeviceId
{
private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
+ private readonly IFileSystem _fileSystem;
private readonly object _syncLock = new object();
@@ -24,7 +27,7 @@ namespace MediaBrowser.Common.Implementations.Devices
{
lock (_syncLock)
{
- var value = File.ReadAllText(CachePath, Encoding.UTF8);
+ var value = File.ReadAllText(CachePath, Encoding.UTF8);
Guid guid;
if (Guid.TryParse(value, out guid))
@@ -55,11 +58,11 @@ namespace MediaBrowser.Common.Implementations.Devices
{
var path = CachePath;
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
lock (_syncLock)
{
- File.WriteAllText(path, id, Encoding.UTF8);
+ _fileSystem.WriteAllText(path, id, Encoding.UTF8);
}
}
catch (Exception ex)
@@ -88,10 +91,15 @@ namespace MediaBrowser.Common.Implementations.Devices
private string _id;
- public DeviceId(IApplicationPaths appPaths, ILogger logger)
+ public DeviceId(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
{
+ if (fileSystem == null) {
+ throw new ArgumentNullException ("fileSystem");
+ }
+
_appPaths = appPaths;
_logger = logger;
+ _fileSystem = fileSystem;
}
public string Value
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 89f405e8a0..f4d4826ebf 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -17,6 +17,7 @@ using System.Net.Cache;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.HttpClientManager
{
@@ -282,8 +283,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
var url = options.Url;
var urlHash = url.ToLower().GetMD5().ToString("N");
- var semaphore = GetLock(url);
-
+
var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
@@ -292,6 +292,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
return response;
}
+ var semaphore = GetLock(url);
+
await semaphore.WaitAsync(options.CancellationToken).ConfigureAwait(false);
try
@@ -355,7 +357,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
private async Task CacheResponse(HttpResponseInfo response, string responseCachePath)
{
- Directory.CreateDirectory(Path.GetDirectoryName(responseCachePath));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(responseCachePath));
using (var responseStream = response.Content)
{
@@ -464,20 +466,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
catch (OperationCanceledException ex)
{
- var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
-
- var httpException = exception as HttpException;
-
- if (httpException != null && httpException.IsTimedOut)
- {
- client.LastTimeout = DateTime.UtcNow;
- }
-
- throw exception;
+ throw GetCancellationException(options, client, options.CancellationToken, ex);
}
catch (Exception ex)
{
- throw GetException(ex, options);
+ throw GetException(ex, options, client);
}
finally
{
@@ -488,27 +481,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
}
- /// <summary>
- /// Gets the exception.
- /// </summary>
- /// <param name="ex">The ex.</param>
- /// <param name="options">The options.</param>
- /// <returns>HttpException.</returns>
- private HttpException GetException(WebException ex, HttpRequestOptions options)
- {
- _logger.ErrorException("Error getting response from " + options.Url, ex);
-
- var exception = new HttpException(ex.Message, ex);
-
- var response = ex.Response as HttpWebResponse;
- if (response != null)
- {
- exception.StatusCode = response.StatusCode;
- }
-
- return exception;
- }
-
private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
{
return new HttpResponseInfo(disposable)
@@ -599,7 +571,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
{
ValidateParams(options);
- Directory.CreateDirectory(_appPaths.TempDirectory);
+ _fileSystem.CreateDirectory(_appPaths.TempDirectory);
var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
@@ -624,6 +596,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
_logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
}
+ var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
+
try
{
options.CancellationToken.ThrowIfCancellationRequested();
@@ -632,7 +606,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
{
var httpResponse = (HttpWebResponse)response;
- var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
EnsureSuccessStatusCode(client, httpResponse, options);
options.CancellationToken.ThrowIfCancellationRequested();
@@ -669,7 +642,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
catch (Exception ex)
{
DeleteTempFile(tempFile);
- throw GetException(ex, options);
+ throw GetException(ex, options, client);
}
finally
{
@@ -694,14 +667,37 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- private Exception GetException(Exception ex, HttpRequestOptions options)
+ private Exception GetException(Exception ex, HttpRequestOptions options, HttpClientInfo client)
{
+ if (ex is HttpException)
+ {
+ return ex;
+ }
+
var webException = ex as WebException
?? ex.InnerException as WebException;
if (webException != null)
{
- return GetException(webException, options);
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
+
+ var exception = new HttpException(ex.Message, ex);
+
+ var response = webException.Response as HttpWebResponse;
+ if (response != null)
+ {
+ exception.StatusCode = response.StatusCode;
+
+ if ((int)response.StatusCode == 429)
+ {
+ client.LastTimeout = DateTime.UtcNow;
+ }
+ }
+
+ return exception;
}
var operationCanceledException = ex as OperationCanceledException
@@ -709,10 +705,13 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
if (operationCanceledException != null)
{
- return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
+ return GetCancellationException(options, client, options.CancellationToken, operationCanceledException);
}
- _logger.ErrorException("Error getting response from " + options.Url, ex);
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
return ex;
}
@@ -784,18 +783,24 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
/// <summary>
/// Throws the cancellation exception.
/// </summary>
- /// <param name="url">The URL.</param>
+ /// <param name="options">The options.</param>
+ /// <param name="client">The client.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="exception">The exception.</param>
/// <returns>Exception.</returns>
- private Exception GetCancellationException(string url, CancellationToken cancellationToken, OperationCanceledException exception)
+ private Exception GetCancellationException(HttpRequestOptions options, HttpClientInfo client, CancellationToken cancellationToken, OperationCanceledException exception)
{
// If the HttpClient's timeout is reached, it will cancel the Task internally
if (!cancellationToken.IsCancellationRequested)
{
- var msg = string.Format("Connection to {0} timed out", url);
+ var msg = string.Format("Connection to {0} timed out", options.Url);
+
+ if (options.LogErrors)
+ {
+ _logger.Error(msg);
+ }
- _logger.Error(msg);
+ client.LastTimeout = DateTime.UtcNow;
// Throw an HttpException so that the caller doesn't think it was cancelled by user code
return new HttpException(msg, exception)
@@ -815,12 +820,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
if (!isSuccessful)
{
- if ((int) statusCode == 429)
- {
- client.LastTimeout = DateTime.UtcNow;
- }
-
- if (statusCode == HttpStatusCode.RequestEntityTooLarge)
if (options.LogErrorResponseBody)
{
try
@@ -869,25 +868,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
Task<WebResponse> asyncTask = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
ThreadPool.RegisterWaitForSingleObject((asyncTask as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, timeout, true);
- asyncTask.ContinueWith(task =>
- {
- taskCompletion.TrySetResult(task.Result);
-
- }, TaskContinuationOptions.NotOnFaulted);
+ var callback = new TaskCallback { taskCompletion = taskCompletion };
+ asyncTask.ContinueWith(callback.OnSuccess, TaskContinuationOptions.NotOnFaulted);
// Handle errors
- asyncTask.ContinueWith(task =>
- {
- if (task.Exception != null)
- {
- taskCompletion.TrySetException(task.Exception);
- }
- else
- {
- taskCompletion.TrySetException(new List<Exception>());
- }
-
- }, TaskContinuationOptions.OnlyOnFaulted);
+ asyncTask.ContinueWith(callback.OnError, TaskContinuationOptions.OnlyOnFaulted);
return taskCompletion.Task;
}
@@ -903,5 +888,27 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
}
}
+
+ private class TaskCallback
+ {
+ public TaskCompletionSource<WebResponse> taskCompletion;
+
+ public void OnSuccess(Task<WebResponse> task)
+ {
+ taskCompletion.TrySetResult(task.Result);
+ }
+
+ public void OnError(Task<WebResponse> task)
+ {
+ if (task.Exception != null)
+ {
+ taskCompletion.TrySetException(task.Exception);
+ }
+ else
+ {
+ taskCompletion.TrySetException(new List<Exception>());
+ }
+ }
+ }
}
}
diff --git a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs
deleted file mode 100644
index e9ef846634..0000000000
--- a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs
+++ /dev/null
@@ -1,433 +0,0 @@
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Logging;
-using System;
-using System.IO;
-using System.Text;
-
-namespace MediaBrowser.Common.Implementations.IO
-{
- /// <summary>
- /// Class CommonFileSystem
- /// </summary>
- public class CommonFileSystem : IFileSystem
- {
- protected ILogger Logger;
-
- private readonly bool _supportsAsyncFileStreams;
- private char[] _invalidFileNameChars;
-
- public CommonFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool usePresetInvalidFileNameChars)
- {
- Logger = logger;
- _supportsAsyncFileStreams = supportsAsyncFileStreams;
-
- SetInvalidFileNameChars(usePresetInvalidFileNameChars);
- }
-
- private void SetInvalidFileNameChars(bool usePresetInvalidFileNameChars)
- {
- // GetInvalidFileNameChars is less restrictive in Linux/Mac than Windows, this mimic Windows behavior for mono under Linux/Mac.
-
- if (usePresetInvalidFileNameChars)
- {
- _invalidFileNameChars = new char[41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
- '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12',
- '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D',
- '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C', ':', '*', '?', '\\', '/' };
- }
- else
- {
- _invalidFileNameChars = Path.GetInvalidFileNameChars();
- }
- }
-
- /// <summary>
- /// Determines whether the specified filename is shortcut.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public virtual bool IsShortcut(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var extension = Path.GetExtension(filename);
-
- return string.Equals(extension, ".mblink", StringComparison.OrdinalIgnoreCase);
- }
-
- /// <summary>
- /// Resolves the shortcut.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public virtual string ResolveShortcut(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- if (string.Equals(Path.GetExtension(filename), ".mblink", StringComparison.OrdinalIgnoreCase))
- {
- var path = File.ReadAllText(filename);
-
- return NormalizePath(path);
- }
-
- return null;
- }
-
- /// <summary>
- /// Creates the shortcut.
- /// </summary>
- /// <param name="shortcutPath">The shortcut path.</param>
- /// <param name="target">The target.</param>
- /// <exception cref="System.ArgumentNullException">
- /// shortcutPath
- /// or
- /// target
- /// </exception>
- public void CreateShortcut(string shortcutPath, string target)
- {
- if (string.IsNullOrEmpty(shortcutPath))
- {
- throw new ArgumentNullException("shortcutPath");
- }
-
- if (string.IsNullOrEmpty(target))
- {
- throw new ArgumentNullException("target");
- }
-
- File.WriteAllText(shortcutPath, target);
- }
-
- /// <summary>
- /// Gets the file system info.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>FileSystemInfo.</returns>
- public FileSystemInfo GetFileSystemInfo(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- // Take a guess to try and avoid two file system hits, but we'll double-check by calling Exists
- if (Path.HasExtension(path))
- {
- var fileInfo = new FileInfo(path);
-
- if (fileInfo.Exists)
- {
- return fileInfo;
- }
-
- return new DirectoryInfo(path);
- }
- else
- {
- var fileInfo = new DirectoryInfo(path);
-
- if (fileInfo.Exists)
- {
- return fileInfo;
- }
-
- return new FileInfo(path);
- }
- }
-
- /// <summary>
- /// The space char
- /// </summary>
- private const char SpaceChar = ' ';
-
- /// <summary>
- /// Takes a filename and removes invalid characters
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">filename</exception>
- public string GetValidFilename(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var builder = new StringBuilder(filename);
-
- foreach (var c in _invalidFileNameChars)
- {
- builder = builder.Replace(c, SpaceChar);
- }
-
- return builder.ToString();
- }
-
- /// <summary>
- /// Gets the creation time UTC.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetCreationTimeUtc(FileSystemInfo info)
- {
- // This could throw an error on some file systems that have dates out of range
- try
- {
- return info.CreationTimeUtc;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error determining CreationTimeUtc for {0}", ex, info.FullName);
- return DateTime.MinValue;
- }
- }
-
- /// <summary>
- /// Gets the creation time UTC.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetLastWriteTimeUtc(FileSystemInfo info)
- {
- // This could throw an error on some file systems that have dates out of range
- try
- {
- return info.LastWriteTimeUtc;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error determining LastAccessTimeUtc for {0}", ex, info.FullName);
- return DateTime.MinValue;
- }
- }
-
- /// <summary>
- /// Gets the last write time UTC.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>DateTime.</returns>
- public DateTime GetLastWriteTimeUtc(string path)
- {
- return GetLastWriteTimeUtc(GetFileSystemInfo(path));
- }
-
- /// <summary>
- /// Gets the file stream.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="mode">The mode.</param>
- /// <param name="access">The access.</param>
- /// <param name="share">The share.</param>
- /// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param>
- /// <returns>FileStream.</returns>
- public FileStream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false)
- {
- if (_supportsAsyncFileStreams && isAsync)
- {
- return new FileStream(path, mode, access, share, StreamDefaults.DefaultFileStreamBufferSize, true);
- }
-
- return new FileStream(path, mode, access, share, StreamDefaults.DefaultFileStreamBufferSize);
- }
-
- /// <summary>
- /// Swaps the files.
- /// </summary>
- /// <param name="file1">The file1.</param>
- /// <param name="file2">The file2.</param>
- public void SwapFiles(string file1, string file2)
- {
- if (string.IsNullOrEmpty(file1))
- {
- throw new ArgumentNullException("file1");
- }
-
- if (string.IsNullOrEmpty(file2))
- {
- throw new ArgumentNullException("file2");
- }
-
- var temp1 = Path.GetTempFileName();
- var temp2 = Path.GetTempFileName();
-
- // Copying over will fail against hidden files
- RemoveHiddenAttribute(file1);
- RemoveHiddenAttribute(file2);
-
- File.Copy(file1, temp1, true);
- File.Copy(file2, temp2, true);
-
- File.Copy(temp1, file2, true);
- File.Copy(temp2, file1, true);
-
- DeleteFile(temp1);
- DeleteFile(temp2);
- }
-
- /// <summary>
- /// Removes the hidden attribute.
- /// </summary>
- /// <param name="path">The path.</param>
- private void RemoveHiddenAttribute(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var currentFile = new FileInfo(path);
-
- // This will fail if the file is hidden
- if (currentFile.Exists)
- {
- if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
- {
- currentFile.Attributes &= ~FileAttributes.Hidden;
- }
- }
- }
-
- public bool ContainsSubPath(string parentPath, string path)
- {
- if (string.IsNullOrEmpty(parentPath))
- {
- throw new ArgumentNullException("parentPath");
- }
-
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- return path.IndexOf(parentPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1;
- }
-
- public bool IsRootPath(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var parent = Path.GetDirectoryName(path);
-
- if (!string.IsNullOrEmpty(parent))
- {
- return false;
- }
-
- return true;
- }
-
- public string NormalizePath(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase))
- {
- return path;
- }
-
- return path.TrimEnd(Path.DirectorySeparatorChar);
- }
-
- public string SubstitutePath(string path, string from, string to)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentNullException("path");
- }
- if (string.IsNullOrWhiteSpace(from))
- {
- throw new ArgumentNullException("from");
- }
- if (string.IsNullOrWhiteSpace(to))
- {
- throw new ArgumentNullException("to");
- }
-
- var newPath = path.Replace(from, to, StringComparison.OrdinalIgnoreCase);
-
- if (!string.Equals(newPath, path))
- {
- if (to.IndexOf('/') != -1)
- {
- newPath = newPath.Replace('\\', '/');
- }
- else
- {
- newPath = newPath.Replace('/', '\\');
- }
- }
-
- return newPath;
- }
-
- public string GetFileNameWithoutExtension(FileSystemInfo info)
- {
- if (info is DirectoryInfo)
- {
- return info.Name;
- }
-
- return Path.GetFileNameWithoutExtension(info.FullName);
- }
-
- public string GetFileNameWithoutExtension(string path)
- {
- return Path.GetFileNameWithoutExtension(path);
- }
-
- public bool IsPathFile(string path)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentNullException("path");
- }
-
- // Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
-
- if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
- !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- return true;
-
- //return Path.IsPathRooted(path);
- }
-
- public void DeleteFile(string path, bool sendToRecycleBin)
- {
- File.Delete(path);
- }
-
- public void DeleteDirectory(string path, bool recursive, bool sendToRecycleBin)
- {
- Directory.Delete(path, recursive);
- }
-
- public void DeleteFile(string path)
- {
- DeleteFile(path, false);
- }
-
- public void DeleteDirectory(string path, bool recursive)
- {
- DeleteDirectory(path, recursive, false);
- }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
index 6987928026..391e7c2128 100644
--- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
+++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
@@ -170,7 +170,7 @@ namespace MediaBrowser.Common.Implementations.Logging
/// </summary>
/// <param name="name">The name.</param>
/// <returns>ILogger.</returns>
- public ILogger GetLogger(string name)
+ public Model.Logging.ILogger GetLogger(string name)
{
return new NLogger(name, this);
}
@@ -208,7 +208,7 @@ namespace MediaBrowser.Common.Implementations.Logging
{
LogFilePath = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Round(DateTime.Now.Ticks / 10000000) + ".txt");
- Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
+ Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
AddFileTarget(LogFilePath, level);
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index e603ea3738..d857e58b68 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -14,7 +14,6 @@
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -48,18 +47,24 @@
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup>
- <Reference Include="NLog, Version=3.2.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\NLog.3.2.1\lib\net45\NLog.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath>
+ </Reference>
+ <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\NLog.4.1.1\lib\net45\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="Patterns.Logging">
+ <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
</Reference>
<Reference Include="SharpCompress, Version=0.10.2.0, Culture=neutral, PublicKeyToken=beaf6f427e128133, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
</Reference>
- <Reference Include="SimpleInjector, Version=2.7.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+ <Reference Include="SimpleInjector, Version=2.8.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\SimpleInjector.2.8.0\lib\net45\SimpleInjector.dll</HintPath>
- <Private>True</Private>
+ <HintPath>..\packages\SimpleInjector.3.0.5\lib\net45\SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -82,7 +87,6 @@
<Compile Include="Devices\DeviceId.cs" />
<Compile Include="HttpClientManager\HttpClientInfo.cs" />
<Compile Include="HttpClientManager\HttpClientManager.cs" />
- <Compile Include="IO\CommonFileSystem.cs" />
<Compile Include="IO\IsoManager.cs" />
<Compile Include="Logging\LogHelper.cs" />
<Compile Include="Logging\NLogger.cs" />
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index cbd1c1ac55..95f29915db 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -12,6 +12,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
@@ -51,6 +52,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// </summary>
/// <value>The task manager.</value>
private ITaskManager TaskManager { get; set; }
+ private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class.
@@ -71,7 +73,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// or
/// logger
/// </exception>
- public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger)
+ public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem)
{
if (scheduledTask == null)
{
@@ -99,6 +101,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
TaskManager = taskManager;
JsonSerializer = jsonSerializer;
Logger = logger;
+ _fileSystem = fileSystem;
ReloadTriggerEvents(true);
}
@@ -154,7 +157,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
_lastExecutionResult = value;
var path = GetHistoryFilePath();
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
lock (_lastExecutionResultSyncLock)
{
@@ -300,6 +303,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
}
}
+ public void ReloadTriggerEvents()
+ {
+ ReloadTriggerEvents(false);
+ }
+
/// <summary>
/// Reloads the trigger events.
/// </summary>
@@ -552,7 +560,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
var path = GetConfigurationFilePath();
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), path);
}
@@ -622,7 +630,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
try
{
- Logger.Debug(Name + ": Cancelling");
+ Logger.Info(Name + ": Cancelling");
token.Cancel();
}
catch (Exception ex)
@@ -635,16 +643,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
try
{
- Logger.Debug(Name + ": Waiting on Task");
+ Logger.Info(Name + ": Waiting on Task");
var exited = Task.WaitAll(new[] { task }, 2000);
if (exited)
{
- Logger.Debug(Name + ": Task exited");
+ Logger.Info(Name + ": Task exited");
}
else
{
- Logger.Debug(Name + ": Timed out waiting for task to stop");
+ Logger.Info(Name + ": Timed out waiting for task to stop");
}
}
catch (Exception ex)
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
index de7987bd22..845c984fb7 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
@@ -10,6 +10,9 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
+using Microsoft.Win32;
namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
@@ -50,6 +53,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// </summary>
/// <value>The logger.</value>
private ILogger Logger { get; set; }
+ private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="TaskManager" /> class.
@@ -58,13 +62,36 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentException">kernel</exception>
- public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger)
+ public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem)
{
ApplicationPaths = applicationPaths;
JsonSerializer = jsonSerializer;
Logger = logger;
+ _fileSystem = fileSystem;
ScheduledTasks = new IScheduledTaskWorker[] { };
+
+ BindToSystemEvent();
+ }
+
+ private void BindToSystemEvent()
+ {
+ try
+ {
+ SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ }
+ catch
+ {
+
+ }
+ }
+
+ void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+ {
+ foreach (var task in ScheduledTasks)
+ {
+ task.ReloadTriggerEvents();
+ }
}
/// <summary>
@@ -106,9 +133,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
public void QueueScheduledTask<T>(TaskExecutionOptions options)
where T : IScheduledTask
{
- var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
+ var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T));
- QueueScheduledTask(scheduledTask, options);
+ if (scheduledTask == null)
+ {
+ Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name);
+ }
+ else
+ {
+ QueueScheduledTask(scheduledTask, options);
+ }
}
public void QueueScheduledTask<T>()
@@ -116,7 +150,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
QueueScheduledTask<T>(new TaskExecutionOptions());
}
-
+
/// <summary>
/// Queues the scheduled task.
/// </summary>
@@ -124,9 +158,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <param name="options">The task options.</param>
public void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options)
{
- var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == task.GetType());
+ var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == task.GetType());
- QueueScheduledTask(scheduledTask, options);
+ if (scheduledTask == null)
+ {
+ Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name);
+ }
+ else
+ {
+ QueueScheduledTask(scheduledTask, options);
+ }
}
/// <summary>
@@ -161,7 +202,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
var myTasks = ScheduledTasks.ToList();
var list = tasks.ToList();
- myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger)));
+ myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, _fileSystem)));
ScheduledTasks = myTasks.ToArray();
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
index d9c178d8b5..0e50f93159 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
@@ -95,7 +96,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 = new DirectoryInfo(directory).EnumerateFiles("*", SearchOption.AllDirectories)
+ var filesToDelete = _fileSystem.GetFiles(directory, true)
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
.ToList();
@@ -120,14 +121,14 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
progress.Report(100);
}
- private static void DeleteEmptyFolders(string parent)
+ private void DeleteEmptyFolders(string parent)
{
- foreach (var directory in Directory.GetDirectories(parent))
+ foreach (var directory in _fileSystem.GetDirectoryPaths(parent))
{
DeleteEmptyFolders(directory);
- if (!Directory.EnumerateFileSystemEntries(directory).Any())
+ if (!_fileSystem.GetFileSystemEntryPaths(directory).Any())
{
- Directory.Delete(directory, false);
+ _fileSystem.DeleteDirectory(directory, false);
}
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index b2759c52a6..8507d31843 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
{
@@ -58,7 +59,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
// Delete log files more than n days old
var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays));
- var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
+ var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, true)
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
.ToList();
diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
index 63381efcdf..79e558794f 100644
--- a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
+++ b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
@@ -99,7 +99,7 @@ namespace MediaBrowser.Common.Implementations.Security
{
try
{
- contents = File.ReadAllLines(licenseFile);
+ contents = File.ReadAllLines(licenseFile);
}
catch (DirectoryNotFoundException)
{
@@ -107,7 +107,7 @@ namespace MediaBrowser.Common.Implementations.Security
}
catch (FileNotFoundException)
{
- (File.Create(licenseFile)).Close();
+ (File.Create(licenseFile)).Close();
}
}
if (contents != null && contents.Length > 0)
@@ -150,8 +150,8 @@ namespace MediaBrowser.Common.Implementations.Security
}
var licenseFile = Filename;
- Directory.CreateDirectory(Path.GetDirectoryName(licenseFile));
- lock (_fileLock) File.WriteAllLines(licenseFile, lines);
+ Directory.CreateDirectory(Path.GetDirectoryName(licenseFile));
+ lock (_fileLock) File.WriteAllLines(licenseFile, lines);
}
}
}
diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
index c2725e9bf6..c17a637fed 100644
--- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
+++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Configuration;
+using System.IO;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Security;
using MediaBrowser.Model.Entities;
@@ -18,6 +19,7 @@ namespace MediaBrowser.Common.Implementations.Security
public class PluginSecurityManager : ISecurityManager
{
private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate";
+ private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "http://mb3admin.com/admin/" + "service/appstore/register";
/// <summary>
/// The _is MB supporter
@@ -185,6 +187,70 @@ namespace MediaBrowser.Common.Implementations.Security
}
}
+ /// <summary>
+ /// Register an app store sale with our back-end. It will validate the transaction with the store
+ /// and then register the proper feature and then fill in the supporter key on success.
+ /// </summary>
+ /// <param name="parameters">Json parameters to send to admin server</param>
+ public async Task RegisterAppStoreSale(string parameters)
+ {
+ var options = new HttpRequestOptions()
+ {
+ Url = AppstoreRegUrl,
+ CancellationToken = CancellationToken.None
+ };
+ options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId);
+ options.RequestContent = parameters;
+ options.RequestContentType = "application/json";
+
+ try
+ {
+ using (var response = await _httpClient.Post(options).ConfigureAwait(false))
+ {
+ var reg = _jsonSerializer.DeserializeFromStream<RegRecord>(response.Content);
+
+ if (reg == null)
+ {
+ var msg = "Result from appstore registration was null.";
+ _logger.Error(msg);
+ throw new ApplicationException(msg);
+ }
+ if (!String.IsNullOrEmpty(reg.key))
+ {
+ SupporterKey = reg.key;
+ }
+ }
+
+ }
+ catch (ApplicationException)
+ {
+ SaveAppStoreInfo(parameters);
+ throw;
+ }
+ catch (Exception e)
+ {
+ _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT");
+ SaveAppStoreInfo(parameters);
+ //TODO - could create a re-try routine on start-up if this file is there. For now we can handle manually.
+ throw new ApplicationException("Error registering store sale");
+ }
+
+ }
+
+ private void SaveAppStoreInfo(string info)
+ {
+ // Save all transaction information to a file
+
+ try
+ {
+ File.WriteAllText(Path.Combine(_appPaths.ProgramDataPath, "apptrans-error.txt"), info);
+ }
+ catch (IOException)
+ {
+
+ }
+ }
+
private async Task<MBRegistrationRecord> GetRegistrationStatusInternal(string feature,
string mb2Equivalent = null,
string version = null)
diff --git a/MediaBrowser.Common.Implementations/Security/RegRecord.cs b/MediaBrowser.Common.Implementations/Security/RegRecord.cs
index f4e4337bfa..ece70b7726 100644
--- a/MediaBrowser.Common.Implementations/Security/RegRecord.cs
+++ b/MediaBrowser.Common.Implementations/Security/RegRecord.cs
@@ -7,5 +7,6 @@ namespace MediaBrowser.Common.Implementations.Security
public string featId { get; set; }
public bool registered { get; set; }
public DateTime expDate { get; set; }
+ public string key { get; set; }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
index f194b334a8..269294b36b 100644
--- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
@@ -1,6 +1,8 @@
-using MediaBrowser.Model.Serialization;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Model.Serialization;
using System;
using System.IO;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.Serialization
{
@@ -9,8 +11,11 @@ namespace MediaBrowser.Common.Implementations.Serialization
/// </summary>
public class JsonSerializer : IJsonSerializer
{
- public JsonSerializer()
+ private readonly IFileSystem _fileSystem;
+
+ public JsonSerializer(IFileSystem fileSystem)
{
+ _fileSystem = fileSystem;
Configure();
}
@@ -53,7 +58,7 @@ namespace MediaBrowser.Common.Implementations.Serialization
throw new ArgumentNullException("file");
}
- using (Stream stream = File.Open(file, FileMode.Create))
+ using (Stream stream = _fileSystem.GetFileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
{
SerializeToStream(obj, stream);
}
diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
index 04030522f3..449c23b2d3 100644
--- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
@@ -3,6 +3,8 @@ using System;
using System.Collections.Concurrent;
using System.IO;
using System.Xml;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Common.Implementations.Serialization
{
@@ -11,6 +13,13 @@ namespace MediaBrowser.Common.Implementations.Serialization
/// </summary>
public class XmlSerializer : IXmlSerializer
{
+ private IFileSystem _fileSystem;
+
+ public XmlSerializer(IFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
// Need to cache these
// http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html
private readonly ConcurrentDictionary<string, System.Xml.Serialization.XmlSerializer> _serializers =
@@ -83,7 +92,7 @@ namespace MediaBrowser.Common.Implementations.Serialization
/// <returns>System.Object.</returns>
public object DeserializeFromFile(Type type, string file)
{
- using (var stream = File.OpenRead(file))
+ using (var stream = _fileSystem.OpenRead(file))
{
return DeserializeFromStream(type, stream);
}
diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
index 5f205d69e7..dc642a0a8f 100644
--- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
+++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
@@ -19,6 +19,7 @@ using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.Updates
{
@@ -553,7 +554,7 @@ namespace MediaBrowser.Common.Implementations.Updates
if (packageChecksum != Guid.Empty) // support for legacy uploads for now
{
using (var crypto = new MD5CryptoServiceProvider())
- using (var stream = new BufferedStream(File.OpenRead(tempFile), 100000))
+ using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000))
{
var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty));
if (check != packageChecksum)
@@ -568,12 +569,12 @@ namespace MediaBrowser.Common.Implementations.Updates
// Success - move it to the real target
try
{
- Directory.CreateDirectory(Path.GetDirectoryName(target));
- File.Copy(tempFile, target, true);
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(target));
+ _fileSystem.CopyFile(tempFile, target, true);
//If it is an archive - write out a version file so we know what it is
if (isArchive)
{
- File.WriteAllText(target + ".ver", package.versionStr);
+ File.WriteAllText(target + ".ver", package.versionStr);
}
}
catch (IOException e)
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
index e57c874f2c..a0711a9c75 100644
--- a/MediaBrowser.Common.Implementations/packages.config
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="NLog" version="3.2.1" targetFramework="net45" />
- <package id="SimpleInjector" version="2.8.0" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.5" targetFramework="net45" />
+ <package id="NLog" version="4.1.0" targetFramework="net45" />
+ <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
+ <package id="SimpleInjector" version="3.0.5" targetFramework="net45" />
</packages>