Merge branch 'master' into namingtests
This commit is contained in:
commit
6b185119aa
|
@ -30,6 +30,7 @@
|
||||||
- [Khinenw](https://github.com/HelloWorld017)
|
- [Khinenw](https://github.com/HelloWorld017)
|
||||||
- [fhriley](https://github.com/fhriley)
|
- [fhriley](https://github.com/fhriley)
|
||||||
- [nevado](https://github.com/nevado)
|
- [nevado](https://github.com/nevado)
|
||||||
|
- [mark-monteiro](https://github.com/mark-monteiro)
|
||||||
|
|
||||||
# Emby Contributors
|
# Emby Contributors
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Dlna.Main;
|
using Emby.Dlna.Main;
|
||||||
|
@ -195,7 +193,7 @@ namespace Emby.Dlna.Api
|
||||||
|
|
||||||
private ControlResponse PostAsync(Stream requestStream, IUpnpService service)
|
private ControlResponse PostAsync(Stream requestStream, IUpnpService service)
|
||||||
{
|
{
|
||||||
var id = GetPathValue(2);
|
var id = GetPathValue(2).ToString();
|
||||||
|
|
||||||
return service.ProcessControlRequest(new ControlRequest
|
return service.ProcessControlRequest(new ControlRequest
|
||||||
{
|
{
|
||||||
|
@ -206,51 +204,99 @@ namespace Emby.Dlna.Api
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string GetPathValue(int index)
|
// Copied from MediaBrowser.Api/BaseApiService.cs
|
||||||
|
// TODO: Remove code duplication
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the path segment at the specified index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the path segment.</param>
|
||||||
|
/// <returns>The path segment at the specified index.</returns>
|
||||||
|
/// <exception cref="IndexOutOfRangeException" >Path doesn't contain enough segments.</exception>
|
||||||
|
/// <exception cref="InvalidDataException" >Path doesn't start with the base url.</exception>
|
||||||
|
protected internal ReadOnlySpan<char> GetPathValue(int index)
|
||||||
{
|
{
|
||||||
var pathInfo = Parse(Request.PathInfo);
|
static void ThrowIndexOutOfRangeException()
|
||||||
var first = pathInfo[0];
|
=> throw new IndexOutOfRangeException("Path doesn't contain enough segments.");
|
||||||
|
|
||||||
|
static void ThrowInvalidDataException()
|
||||||
|
=> throw new InvalidDataException("Path doesn't start with the base url.");
|
||||||
|
|
||||||
|
ReadOnlySpan<char> path = Request.PathInfo;
|
||||||
|
|
||||||
|
// Remove the protocol part from the url
|
||||||
|
int pos = path.LastIndexOf("://");
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
path = path.Slice(pos + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the query string
|
||||||
|
pos = path.LastIndexOf('?');
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
path = path.Slice(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the domain
|
||||||
|
pos = path.IndexOf('/');
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
path = path.Slice(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove base url
|
||||||
string baseUrl = _configurationManager.Configuration.BaseUrl;
|
string baseUrl = _configurationManager.Configuration.BaseUrl;
|
||||||
|
int baseUrlLen = baseUrl.Length;
|
||||||
// backwards compatibility
|
if (baseUrlLen != 0)
|
||||||
if (baseUrl.Length == 0)
|
|
||||||
{
|
{
|
||||||
if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase)
|
if (path.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase))
|
||||||
|| string.Equals(first, "emby", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
index++;
|
path = path.Slice(baseUrlLen);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (string.Equals(first, baseUrl.Remove(0, 1)))
|
|
||||||
{
|
|
||||||
index++;
|
|
||||||
var second = pathInfo[1];
|
|
||||||
if (string.Equals(second, "mediabrowser", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(second, "emby", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
index++;
|
// The path doesn't start with the base url,
|
||||||
|
// how did we get here?
|
||||||
|
ThrowInvalidDataException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pathInfo[index];
|
// Remove leading /
|
||||||
}
|
path = path.Slice(1);
|
||||||
|
|
||||||
private static string[] Parse(string pathUri)
|
// Backwards compatibility
|
||||||
{
|
const string Emby = "emby/";
|
||||||
var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
|
if (path.StartsWith(Emby, StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
||||||
var pathInfo = actionParts[actionParts.Length - 1];
|
|
||||||
|
|
||||||
var optionsPos = pathInfo.LastIndexOf('?');
|
|
||||||
if (optionsPos != -1)
|
|
||||||
{
|
{
|
||||||
pathInfo = pathInfo.Substring(0, optionsPos);
|
path = path.Slice(Emby.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = pathInfo.Split('/');
|
const string MediaBrowser = "mediabrowser/";
|
||||||
|
if (path.StartsWith(MediaBrowser, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
path = path.Slice(MediaBrowser.Length);
|
||||||
|
}
|
||||||
|
|
||||||
return args.Skip(1).ToArray();
|
// Skip segments until we are at the right index
|
||||||
|
for (int i = 0; i < index; i++)
|
||||||
|
{
|
||||||
|
pos = path.IndexOf('/');
|
||||||
|
if (pos == -1)
|
||||||
|
{
|
||||||
|
ThrowIndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
path = path.Slice(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the rest
|
||||||
|
pos = path.IndexOf('/');
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
path = path.Slice(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Get(GetIcon request)
|
public object Get(GetIcon request)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
@ -104,7 +103,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(profile.UserId))
|
if (!string.IsNullOrEmpty(profile.UserId))
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(profile.UserId);
|
var user = _userManager.GetUserById(Guid.Parse(profile.UserId));
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
|
@ -116,7 +115,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userId))
|
if (!string.IsNullOrEmpty(userId))
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId);
|
var user = _userManager.GetUserById(Guid.Parse(userId));
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -425,10 +425,10 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
{
|
{
|
||||||
var folder = (Folder)item;
|
var folder = (Folder)item;
|
||||||
|
|
||||||
var sortOrders = new List<string>();
|
var sortOrders = new List<(string, SortOrder)>();
|
||||||
if (!folder.IsPreSorted)
|
if (!folder.IsPreSorted)
|
||||||
{
|
{
|
||||||
sortOrders.Add(ItemSortBy.SortName);
|
sortOrders.Add((ItemSortBy.SortName, sort.SortOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaTypes = new List<string>();
|
var mediaTypes = new List<string>();
|
||||||
|
@ -464,7 +464,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
{
|
{
|
||||||
Limit = limit,
|
Limit = limit,
|
||||||
StartIndex = startIndex,
|
StartIndex = startIndex,
|
||||||
OrderBy = sortOrders.Select(i => new ValueTuple<string, SortOrder>(i, sort.SortOrder)).ToArray(),
|
OrderBy = sortOrders,
|
||||||
User = user,
|
User = user,
|
||||||
Recursive = true,
|
Recursive = true,
|
||||||
IsMissing = false,
|
IsMissing = false,
|
||||||
|
@ -872,10 +872,10 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
query.Parent = parent;
|
query.Parent = parent;
|
||||||
query.SetUser(user);
|
query.SetUser(user);
|
||||||
|
|
||||||
query.OrderBy = new ValueTuple<string, SortOrder>[]
|
query.OrderBy = new[]
|
||||||
{
|
{
|
||||||
new ValueTuple<string, SortOrder> (ItemSortBy.DatePlayed, SortOrder.Descending),
|
(ItemSortBy.DatePlayed, SortOrder.Descending),
|
||||||
new ValueTuple<string, SortOrder> (ItemSortBy.SortName, SortOrder.Ascending)
|
(ItemSortBy.SortName, SortOrder.Ascending)
|
||||||
};
|
};
|
||||||
|
|
||||||
query.IsResumable = true;
|
query.IsResumable = true;
|
||||||
|
@ -1121,7 +1121,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
private QueryResult<ServerItem> GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.OrderBy = new ValueTuple<string, SortOrder>[] { };
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
|
||||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
||||||
{
|
{
|
||||||
|
@ -1138,7 +1138,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.OrderBy = new ValueTuple<string, SortOrder>[] { };
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
|
||||||
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
|
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
|
||||||
{
|
{
|
||||||
|
@ -1153,7 +1153,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.OrderBy = new ValueTuple<string, SortOrder>[] { };
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
|
||||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
||||||
{
|
{
|
||||||
|
@ -1170,7 +1170,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.OrderBy = new ValueTuple<string, SortOrder>[] { };
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
|
||||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
||||||
{
|
{
|
||||||
|
@ -1274,13 +1274,14 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
|
|
||||||
private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted)
|
private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted)
|
||||||
{
|
{
|
||||||
var sortOrders = new List<string>();
|
if (isPreSorted)
|
||||||
if (!isPreSorted)
|
|
||||||
{
|
{
|
||||||
sortOrders.Add(ItemSortBy.SortName);
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query.OrderBy = new[] { (ItemSortBy.SortName, sort.SortOrder) };
|
||||||
}
|
}
|
||||||
|
|
||||||
query.OrderBy = sortOrders.Select(i => new ValueTuple<string, SortOrder>(i, sort.SortOrder)).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<ServerItem> ApplyPaging(QueryResult<ServerItem> result, int? startIndex, int? limit)
|
private QueryResult<ServerItem> ApplyPaging(QueryResult<ServerItem> result, int? startIndex, int? limit)
|
||||||
|
|
|
@ -315,7 +315,7 @@ namespace Emby.Naming.Common
|
||||||
// This isn't a Kodi naming rule, but the expression below causes false positives,
|
// This isn't a Kodi naming rule, but the expression below causes false positives,
|
||||||
// so we make sure this one gets tested first.
|
// so we make sure this one gets tested first.
|
||||||
// "Foo Bar 889"
|
// "Foo Bar 889"
|
||||||
new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>(\w+\s*?)*)\s(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$")
|
new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>[\w\s]+?)\s(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$")
|
||||||
{
|
{
|
||||||
IsNamed = true
|
IsNamed = true
|
||||||
},
|
},
|
||||||
|
@ -337,8 +337,8 @@ namespace Emby.Naming.Common
|
||||||
|
|
||||||
// *** End Kodi Standard Naming
|
// *** End Kodi Standard Naming
|
||||||
|
|
||||||
// [bar] Foo - 1 [baz]
|
// [bar] Foo - 1 [baz]
|
||||||
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>(\w+\s*?)+?)[-\s_]+(?<epnumber>\d+).*$")
|
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[-\s_]+(?<epnumber>\d+).*$")
|
||||||
{
|
{
|
||||||
IsNamed = true
|
IsNamed = true
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -39,6 +41,19 @@ namespace Emby.Server.Implementations.Activity
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly IDeviceManager _deviceManager;
|
private readonly IDeviceManager _deviceManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
/// <param name="sessionManager"></param>
|
||||||
|
/// <param name="deviceManager"></param>
|
||||||
|
/// <param name="taskManager"></param>
|
||||||
|
/// <param name="activityManager"></param>
|
||||||
|
/// <param name="localization"></param>
|
||||||
|
/// <param name="installationManager"></param>
|
||||||
|
/// <param name="subManager"></param>
|
||||||
|
/// <param name="userManager"></param>
|
||||||
|
/// <param name="appHost"></param>
|
||||||
public ActivityLogEntryPoint(
|
public ActivityLogEntryPoint(
|
||||||
ILogger<ActivityLogEntryPoint> logger,
|
ILogger<ActivityLogEntryPoint> logger,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -133,6 +133,10 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds parts.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factories">The configuration factories.</param>
|
||||||
public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
|
public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
|
||||||
{
|
{
|
||||||
_configurationFactories = factories.ToArray();
|
_configurationFactories = factories.ToArray();
|
||||||
|
@ -247,6 +251,10 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensures that we have write access to the path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
protected void EnsureWriteAccess(string path)
|
protected void EnsureWriteAccess(string path)
|
||||||
{
|
{
|
||||||
var file = Path.Combine(path, Guid.NewGuid().ToString());
|
var file = Path.Combine(path, Guid.NewGuid().ToString());
|
||||||
|
@ -259,6 +267,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
|
return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public object GetConfiguration(string key)
|
public object GetConfiguration(string key)
|
||||||
{
|
{
|
||||||
return _configurations.GetOrAdd(key, k =>
|
return _configurations.GetOrAdd(key, k =>
|
||||||
|
@ -305,6 +314,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void SaveConfiguration(string key, object configuration)
|
public void SaveConfiguration(string key, object configuration)
|
||||||
{
|
{
|
||||||
var configurationStore = GetConfigurationStore(key);
|
var configurationStore = GetConfigurationStore(key);
|
||||||
|
@ -341,6 +351,11 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
OnNamedConfigurationUpdated(key, configuration);
|
OnNamedConfigurationUpdated(key, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event handler for when a named configuration has been updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the configuration.</param>
|
||||||
|
/// <param name="configuration">The old configuration.</param>
|
||||||
protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
|
protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
|
||||||
{
|
{
|
||||||
NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
|
NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
|
||||||
|
@ -350,6 +365,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Type GetConfigurationType(string key)
|
public Type GetConfigurationType(string key)
|
||||||
{
|
{
|
||||||
return GetConfigurationStore(key)
|
return GetConfigurationStore(key)
|
||||||
|
|
|
@ -10,15 +10,10 @@ using SharpCompress.Readers.Zip;
|
||||||
namespace Emby.Server.Implementations.Archiving
|
namespace Emby.Server.Implementations.Archiving
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class DotNetZipClient
|
/// Class DotNetZipClient.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ZipClient : IZipClient
|
public class ZipClient : IZipClient
|
||||||
{
|
{
|
||||||
public ZipClient()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts all.
|
/// Extracts all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -144,7 +139,6 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts all from tar.
|
/// Extracts all from tar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Model.Branding;
|
using MediaBrowser.Model.Branding;
|
||||||
|
|
|
@ -4,7 +4,7 @@ using MediaBrowser.Controller;
|
||||||
namespace Emby.Server.Implementations.Browser
|
namespace Emby.Server.Implementations.Browser
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class BrowserLauncher
|
/// Class BrowserLauncher.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class BrowserLauncher
|
public static class BrowserLauncher
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.Browser
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the URL.
|
/// Opens the URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="appHost">The application host instance.</param>
|
||||||
/// <param name="url">The URL.</param>
|
/// <param name="url">The URL.</param>
|
||||||
private static void OpenUrl(IServerApplicationHost appHost, string url)
|
private static void OpenUrl(IServerApplicationHost appHost, string url)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -13,11 +15,16 @@ namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
private readonly ChannelManager _channelManager;
|
private readonly ChannelManager _channelManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ChannelDynamicMediaSourceProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelManager">The channel manager.</param>
|
||||||
public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
|
public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
|
||||||
{
|
{
|
||||||
_channelManager = (ChannelManager)channelManager;
|
_channelManager = (ChannelManager)channelManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
|
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (item.SourceType == SourceType.Channel)
|
if (item.SourceType == SourceType.Channel)
|
||||||
|
@ -28,6 +35,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
|
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
public Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -510,7 +512,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return _libraryManager.GetItemIds(new InternalItemsQuery
|
return _libraryManager.GetItemIds(new InternalItemsQuery
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(Channel).Name },
|
IncludeItemTypes = new[] { typeof(Channel).Name },
|
||||||
OrderBy = new ValueTuple<string, SortOrder>[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
|
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
|
||||||
|
|
||||||
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
|
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
|
||||||
}
|
}
|
||||||
|
@ -618,16 +620,16 @@ namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
query.OrderBy = new[]
|
query.OrderBy = new[]
|
||||||
{
|
{
|
||||||
new ValueTuple<string, SortOrder>(ItemSortBy.PremiereDate, SortOrder.Descending),
|
(ItemSortBy.PremiereDate, SortOrder.Descending),
|
||||||
new ValueTuple<string, SortOrder>(ItemSortBy.ProductionYear, SortOrder.Descending),
|
(ItemSortBy.ProductionYear, SortOrder.Descending),
|
||||||
new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
|
(ItemSortBy.DateCreated, SortOrder.Descending)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query.OrderBy = new[]
|
query.OrderBy = new[]
|
||||||
{
|
{
|
||||||
new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
|
(ItemSortBy.DateCreated, SortOrder.Descending)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -76,7 +78,6 @@ namespace Emby.Server.Implementations.Collections
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.GroupBy(x => x.Id)
|
.GroupBy(x => x.Id)
|
||||||
.Select(x => x.First())
|
.Select(x => x.First())
|
||||||
.OrderBy(i => Guid.NewGuid())
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Emby.Server.Implementations.AppBase;
|
using Emby.Server.Implementations.AppBase;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
@ -17,7 +19,6 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager
|
public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,6 +32,9 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
UpdateMetadataPath();
|
UpdateMetadataPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration updating event.
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
|
public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,7 +101,7 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
/// Validates the SSL certificate.
|
/// Validates the SSL certificate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newConfig">The new configuration.</param>
|
/// <param name="newConfig">The new configuration.</param>
|
||||||
/// <exception cref="DirectoryNotFoundException"></exception>
|
/// <exception cref="FileNotFoundException">The certificate path doesn't exist.</exception>
|
||||||
private void ValidateSslCertificate(BaseApplicationConfiguration newConfig)
|
private void ValidateSslCertificate(BaseApplicationConfiguration newConfig)
|
||||||
{
|
{
|
||||||
var serverConfig = (ServerConfiguration)newConfig;
|
var serverConfig = (ServerConfiguration)newConfig;
|
||||||
|
@ -105,12 +109,16 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
var newPath = serverConfig.CertificatePath;
|
var newPath = serverConfig.CertificatePath;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(newPath)
|
if (!string.IsNullOrWhiteSpace(newPath)
|
||||||
&& !string.Equals(Configuration.CertificatePath ?? string.Empty, newPath))
|
&& !string.Equals(Configuration.CertificatePath, newPath, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!File.Exists(newPath))
|
if (!File.Exists(newPath))
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException(string.Format("Certificate file '{0}' does not exist.", newPath));
|
throw new FileNotFoundException(
|
||||||
|
string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"Certificate file '{0}' does not exist.",
|
||||||
|
newPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,24 +127,32 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
/// Validates the metadata path.
|
/// Validates the metadata path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newConfig">The new configuration.</param>
|
/// <param name="newConfig">The new configuration.</param>
|
||||||
/// <exception cref="DirectoryNotFoundException"></exception>
|
/// <exception cref="DirectoryNotFoundException">The new config path doesn't exist.</exception>
|
||||||
private void ValidateMetadataPath(ServerConfiguration newConfig)
|
private void ValidateMetadataPath(ServerConfiguration newConfig)
|
||||||
{
|
{
|
||||||
var newPath = newConfig.MetadataPath;
|
var newPath = newConfig.MetadataPath;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(newPath)
|
if (!string.IsNullOrWhiteSpace(newPath)
|
||||||
&& !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
|
&& !string.Equals(Configuration.MetadataPath, newPath, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Directory.Exists(newPath))
|
if (!Directory.Exists(newPath))
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
|
throw new DirectoryNotFoundException(
|
||||||
|
string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} does not exist.",
|
||||||
|
newPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureWriteAccess(newPath);
|
EnsureWriteAccess(newPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets all configuration values to their optimal values.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>If the configuration changed.</returns>
|
||||||
public bool SetOptimalValues()
|
public bool SetOptimalValues()
|
||||||
{
|
{
|
||||||
var config = Configuration;
|
var config = Configuration;
|
||||||
|
|
|
@ -6,6 +6,9 @@ using static MediaBrowser.Common.Cryptography.Constants;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Cryptography
|
namespace Emby.Server.Implementations.Cryptography
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class providing abstractions over cryptographic functions.
|
||||||
|
/// </summary>
|
||||||
public class CryptographyProvider : ICryptoProvider, IDisposable
|
public class CryptographyProvider : ICryptoProvider, IDisposable
|
||||||
{
|
{
|
||||||
private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
|
private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
|
||||||
|
@ -42,8 +45,10 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
_randomNumberGenerator = RandomNumberGenerator.Create();
|
_randomNumberGenerator = RandomNumberGenerator.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string DefaultHashMethod => "PBKDF2";
|
public string DefaultHashMethod => "PBKDF2";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<string> GetSupportedHashMethods()
|
public IEnumerable<string> GetSupportedHashMethods()
|
||||||
=> _supportedHashMethods;
|
=> _supportedHashMethods;
|
||||||
|
|
||||||
|
@ -62,6 +67,7 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
|
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
|
public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
|
||||||
{
|
{
|
||||||
if (hashMethod == DefaultHashMethod)
|
if (hashMethod == DefaultHashMethod)
|
||||||
|
@ -89,12 +95,15 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
|
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
|
public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
|
||||||
=> PBKDF2(DefaultHashMethod, bytes, salt, DefaultIterations);
|
=> PBKDF2(DefaultHashMethod, bytes, salt, DefaultIterations);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public byte[] GenerateSalt()
|
public byte[] GenerateSalt()
|
||||||
=> GenerateSalt(DefaultSaltLength);
|
=> GenerateSalt(DefaultSaltLength);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public byte[] GenerateSalt(int length)
|
public byte[] GenerateSalt(int length)
|
||||||
{
|
{
|
||||||
byte[] salt = new byte[length];
|
byte[] salt = new byte[length];
|
||||||
|
@ -109,6 +118,10 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases unmanaged and - optionally - managed resources.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -11,6 +13,10 @@ namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
private bool _disposed = false;
|
private bool _disposed = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BaseSqliteRepository"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
protected BaseSqliteRepository(ILogger logger)
|
protected BaseSqliteRepository(ILogger logger)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Emby.Server.Implementations.Playlists;
|
using Emby.Server.Implementations.Playlists;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Json;
|
using MediaBrowser.Common.Json;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
|
@ -2831,8 +2832,8 @@ namespace Emby.Server.Implementations.Data
|
||||||
BindSimilarParams(query, statement);
|
BindSimilarParams(query, statement);
|
||||||
BindSearchParams(query, statement);
|
BindSearchParams(query, statement);
|
||||||
|
|
||||||
// Running this again will bind the params
|
// Running this again will bind the params
|
||||||
GetWhereClauses(query, statement);
|
GetWhereClauses(query, statement);
|
||||||
|
|
||||||
var hasEpisodeAttributes = HasEpisodeAttributes(query);
|
var hasEpisodeAttributes = HasEpisodeAttributes(query);
|
||||||
var hasServiceName = HasServiceName(query);
|
var hasServiceName = HasServiceName(query);
|
||||||
|
@ -2881,14 +2882,14 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
private string GetOrderByText(InternalItemsQuery query)
|
private string GetOrderByText(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
|
var orderBy = query.OrderBy;
|
||||||
if (string.IsNullOrEmpty(query.SearchTerm))
|
if (string.IsNullOrEmpty(query.SearchTerm))
|
||||||
{
|
{
|
||||||
int oldLen = query.OrderBy.Length;
|
int oldLen = orderBy.Count;
|
||||||
|
if (oldLen == 0 && query.SimilarTo != null)
|
||||||
if (query.SimilarTo != null && oldLen == 0)
|
|
||||||
{
|
{
|
||||||
var arr = new (string, SortOrder)[oldLen + 2];
|
var arr = new (string, SortOrder)[oldLen + 2];
|
||||||
query.OrderBy.CopyTo(arr, 0);
|
orderBy.CopyTo(arr, 0);
|
||||||
arr[oldLen] = ("SimilarityScore", SortOrder.Descending);
|
arr[oldLen] = ("SimilarityScore", SortOrder.Descending);
|
||||||
arr[oldLen + 1] = (ItemSortBy.Random, SortOrder.Ascending);
|
arr[oldLen + 1] = (ItemSortBy.Random, SortOrder.Ascending);
|
||||||
query.OrderBy = arr;
|
query.OrderBy = arr;
|
||||||
|
@ -2896,16 +2897,15 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query.OrderBy = new []
|
query.OrderBy = new[]
|
||||||
{
|
{
|
||||||
("SearchScore", SortOrder.Descending),
|
("SearchScore", SortOrder.Descending),
|
||||||
(ItemSortBy.SortName, SortOrder.Ascending)
|
(ItemSortBy.SortName, SortOrder.Ascending)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderBy = query.OrderBy;
|
|
||||||
|
|
||||||
if (orderBy.Length == 0)
|
if (orderBy.Count == 0)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
@ -2913,14 +2913,8 @@ namespace Emby.Server.Implementations.Data
|
||||||
return " ORDER BY " + string.Join(",", orderBy.Select(i =>
|
return " ORDER BY " + string.Join(",", orderBy.Select(i =>
|
||||||
{
|
{
|
||||||
var columnMap = MapOrderByField(i.Item1, query);
|
var columnMap = MapOrderByField(i.Item1, query);
|
||||||
var columnAscending = i.Item2 == SortOrder.Ascending;
|
|
||||||
const bool enableOrderInversion = false;
|
|
||||||
if (columnMap.Item2 && enableOrderInversion)
|
|
||||||
{
|
|
||||||
columnAscending = !columnAscending;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sortOrder = columnAscending ? "ASC" : "DESC";
|
var sortOrder = i.Item2 == SortOrder.Ascending ? "ASC" : "DESC";
|
||||||
|
|
||||||
return columnMap.Item1 + " " + sortOrder;
|
return columnMap.Item1 + " " + sortOrder;
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -5,25 +5,22 @@ using System.Linq;
|
||||||
namespace Emby.Server.Implementations.Data
|
namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class TypeMapper
|
/// Class TypeMapper.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TypeMapper
|
public class TypeMapper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This holds all the types in the running assemblies so that we can de-serialize properly when we don't have strong types
|
/// This holds all the types in the running assemblies
|
||||||
|
/// so that we can de-serialize properly when we don't have strong types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, Type> _typeMap = new ConcurrentDictionary<string, Type>();
|
private readonly ConcurrentDictionary<string, Type> _typeMap = new ConcurrentDictionary<string, Type>();
|
||||||
|
|
||||||
public TypeMapper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type.
|
/// Gets the type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <returns>Type.</returns>
|
/// <returns>Type.</returns>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <exception cref="ArgumentNullException"><c>typeName</c> is null.</exception>
|
||||||
public Type GetType(string typeName)
|
public Type GetType(string typeName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(typeName))
|
if (string.IsNullOrEmpty(typeName))
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using MediaBrowser.Model.Diagnostics;
|
using MediaBrowser.Model.Diagnostics;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Diagnostics
|
namespace Emby.Server.Implementations.Diagnostics
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
|
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
|
||||||
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
|
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
|
||||||
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj" />
|
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj" />
|
||||||
<ProjectReference Include="..\Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj" />
|
|
||||||
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
|
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IPNetwork2" Version="2.4.0.126" />
|
<PackageReference Include="IPNetwork2" Version="2.4.0.126" />
|
||||||
|
<PackageReference Include="Jellyfin.XmlTv" Version="10.4.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -12,32 +11,19 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class RefreshUsersMetadata
|
/// Class RefreshUsersMetadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _user manager
|
/// The user manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
private IFileSystem _fileSystem;
|
private IFileSystem _fileSystem;
|
||||||
|
|
||||||
public string Name => "Refresh Users";
|
|
||||||
|
|
||||||
public string Key => "RefreshUsers";
|
|
||||||
|
|
||||||
public string Description => "Refresh user infos";
|
|
||||||
|
|
||||||
public string Category => "Library";
|
|
||||||
|
|
||||||
public bool IsHidden => true;
|
|
||||||
|
|
||||||
public bool IsEnabled => true;
|
|
||||||
|
|
||||||
public bool IsLogged => true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -48,6 +34,28 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Name => "Refresh Users";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Key => "RefreshUsers";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Description => "Refresh user infos";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Category => "Library";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsHidden => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsEnabled => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsLogged => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
foreach (var user in _userManager.Users)
|
foreach (var user in _userManager.Users)
|
||||||
|
@ -58,9 +66,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
{
|
{
|
||||||
return new List<TaskTriggerInfo>
|
return new[]
|
||||||
{
|
{
|
||||||
new TaskTriggerInfo
|
new TaskTriggerInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,33 +16,46 @@ using MediaBrowser.Model.Tasks;
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class WebSocketEvents
|
/// Class WebSocketEvents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ServerEventNotifier : IServerEntryPoint
|
public class ServerEventNotifier : IServerEntryPoint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _user manager
|
/// The user manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _installation manager
|
/// The installation manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IInstallationManager _installationManager;
|
private readonly IInstallationManager _installationManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _kernel
|
/// The kernel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _task manager
|
/// The task manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ITaskManager _taskManager;
|
private readonly ITaskManager _taskManager;
|
||||||
|
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
|
|
||||||
public ServerEventNotifier(IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, ISessionManager sessionManager)
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ServerEventNotifier"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="appHost">The application host.</param>
|
||||||
|
/// <param name="userManager">The user manager.</param>
|
||||||
|
/// <param name="installationManager">The installation manager.</param>
|
||||||
|
/// <param name="taskManager">The task manager.</param>
|
||||||
|
/// <param name="sessionManager">The session manager.</param>
|
||||||
|
public ServerEventNotifier(
|
||||||
|
IServerApplicationHost appHost,
|
||||||
|
IUserManager userManager,
|
||||||
|
IInstallationManager installationManager,
|
||||||
|
ITaskManager taskManager,
|
||||||
|
ISessionManager sessionManager)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_installationManager = installationManager;
|
_installationManager = installationManager;
|
||||||
|
@ -51,47 +64,48 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task RunAsync()
|
public Task RunAsync()
|
||||||
{
|
{
|
||||||
_userManager.UserDeleted += userManager_UserDeleted;
|
_userManager.UserDeleted += OnUserDeleted;
|
||||||
_userManager.UserUpdated += userManager_UserUpdated;
|
_userManager.UserUpdated += OnUserUpdated;
|
||||||
_userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
|
_userManager.UserPolicyUpdated += OnUserPolicyUpdated;
|
||||||
_userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated;
|
_userManager.UserConfigurationUpdated += OnUserConfigurationUpdated;
|
||||||
|
|
||||||
_appHost.HasPendingRestartChanged += kernel_HasPendingRestartChanged;
|
_appHost.HasPendingRestartChanged += OnHasPendingRestartChanged;
|
||||||
|
|
||||||
_installationManager.PluginUninstalled += InstallationManager_PluginUninstalled;
|
_installationManager.PluginUninstalled += OnPluginUninstalled;
|
||||||
_installationManager.PackageInstalling += _installationManager_PackageInstalling;
|
_installationManager.PackageInstalling += OnPackageInstalling;
|
||||||
_installationManager.PackageInstallationCancelled += _installationManager_PackageInstallationCancelled;
|
_installationManager.PackageInstallationCancelled += OnPackageInstallationCancelled;
|
||||||
_installationManager.PackageInstallationCompleted += _installationManager_PackageInstallationCompleted;
|
_installationManager.PackageInstallationCompleted += OnPackageInstallationCompleted;
|
||||||
_installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
|
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
|
||||||
|
|
||||||
_taskManager.TaskCompleted += _taskManager_TaskCompleted;
|
_taskManager.TaskCompleted += OnTaskCompleted;
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _installationManager_PackageInstalling(object sender, InstallationEventArgs e)
|
private void OnPackageInstalling(object sender, InstallationEventArgs e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo);
|
SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _installationManager_PackageInstallationCancelled(object sender, InstallationEventArgs e)
|
private void OnPackageInstallationCancelled(object sender, InstallationEventArgs e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo);
|
SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _installationManager_PackageInstallationCompleted(object sender, InstallationEventArgs e)
|
private void OnPackageInstallationCompleted(object sender, InstallationEventArgs e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo);
|
SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
|
private void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo);
|
SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
|
private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("ScheduledTaskEnded", e.Result);
|
SendMessageToAdminSessions("ScheduledTaskEnded", e.Result);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +115,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="e">The e.</param>
|
/// <param name="e">The e.</param>
|
||||||
void InstallationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
|
private void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
|
||||||
{
|
{
|
||||||
SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo());
|
SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo());
|
||||||
}
|
}
|
||||||
|
@ -111,7 +125,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The source of the event.</param>
|
/// <param name="sender">The source of the event.</param>
|
||||||
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||||
void kernel_HasPendingRestartChanged(object sender, EventArgs e)
|
private void OnHasPendingRestartChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_sessionManager.SendRestartRequiredNotification(CancellationToken.None);
|
_sessionManager.SendRestartRequiredNotification(CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +135,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="e">The e.</param>
|
/// <param name="e">The e.</param>
|
||||||
void userManager_UserUpdated(object sender, GenericEventArgs<User> e)
|
private void OnUserUpdated(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
var dto = _userManager.GetUserDto(e.Argument);
|
var dto = _userManager.GetUserDto(e.Argument);
|
||||||
|
|
||||||
|
@ -133,19 +147,19 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="e">The e.</param>
|
/// <param name="e">The e.</param>
|
||||||
void userManager_UserDeleted(object sender, GenericEventArgs<User> e)
|
private void OnUserDeleted(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture));
|
SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
|
private void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
var dto = _userManager.GetUserDto(e.Argument);
|
var dto = _userManager.GetUserDto(e.Argument);
|
||||||
|
|
||||||
SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto);
|
SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs<User> e)
|
private void OnUserConfigurationUpdated(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
var dto = _userManager.GetUserDto(e.Argument);
|
var dto = _userManager.GetUserDto(e.Argument);
|
||||||
|
|
||||||
|
@ -168,7 +182,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _sessionManager.SendMessageToUserSessions(new List<Guid> { user.Id }, name, data, CancellationToken.None);
|
await _sessionManager.SendMessageToUserSessions(
|
||||||
|
new List<Guid> { user.Id },
|
||||||
|
name,
|
||||||
|
data,
|
||||||
|
CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
@ -176,12 +194,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -192,18 +209,20 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
if (dispose)
|
if (dispose)
|
||||||
{
|
{
|
||||||
_userManager.UserDeleted -= userManager_UserDeleted;
|
_userManager.UserDeleted -= OnUserDeleted;
|
||||||
_userManager.UserUpdated -= userManager_UserUpdated;
|
_userManager.UserUpdated -= OnUserUpdated;
|
||||||
_userManager.UserPolicyUpdated -= _userManager_UserPolicyUpdated;
|
_userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
|
||||||
_userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated;
|
_userManager.UserConfigurationUpdated -= OnUserConfigurationUpdated;
|
||||||
|
|
||||||
_installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled;
|
_installationManager.PluginUninstalled -= OnPluginUninstalled;
|
||||||
_installationManager.PackageInstalling -= _installationManager_PackageInstalling;
|
_installationManager.PackageInstalling -= OnPackageInstalling;
|
||||||
_installationManager.PackageInstallationCancelled -= _installationManager_PackageInstallationCancelled;
|
_installationManager.PackageInstallationCancelled -= OnPackageInstallationCancelled;
|
||||||
_installationManager.PackageInstallationCompleted -= _installationManager_PackageInstallationCompleted;
|
_installationManager.PackageInstallationCompleted -= OnPackageInstallationCompleted;
|
||||||
_installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed;
|
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
|
||||||
|
|
||||||
_appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged;
|
_appHost.HasPendingRestartChanged -= OnHasPendingRestartChanged;
|
||||||
|
|
||||||
|
_taskManager.TaskCompleted -= OnTaskCompleted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,28 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class StartupWizard
|
/// Class StartupWizard.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StartupWizard : IServerEntryPoint
|
public class StartupWizard : IServerEntryPoint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _app host
|
/// The app host.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _user manager
|
/// The user manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
private IServerConfigurationManager _config;
|
private IServerConfigurationManager _config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StartupWizard"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="appHost">The application host.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="config">The configuration manager.</param>
|
||||||
public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config)
|
public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
|
@ -30,9 +37,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Runs this instance.
|
|
||||||
/// </summary>
|
|
||||||
public Task RunAsync()
|
public Task RunAsync()
|
||||||
{
|
{
|
||||||
if (!_appHost.CanLaunchWebBrowser)
|
if (!_appHost.CanLaunchWebBrowser)
|
||||||
|
@ -57,9 +62,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,30 +10,36 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class UdpServerEntryPoint
|
/// Class UdpServerEntryPoint.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UdpServerEntryPoint : IServerEntryPoint
|
public class UdpServerEntryPoint : IServerEntryPoint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the UDP server.
|
/// The port of the UDP server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The UDP server.</value>
|
public const int PortNumber = 7359;
|
||||||
private UdpServer UdpServer { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ISocketFactory _socketFactory;
|
private readonly ISocketFactory _socketFactory;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly IJsonSerializer _json;
|
private readonly IJsonSerializer _json;
|
||||||
|
|
||||||
public const int PortNumber = 7359;
|
/// <summary>
|
||||||
|
/// The UDP server.
|
||||||
|
/// </summary>
|
||||||
|
private UdpServer _udpServer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UdpServerEntryPoint" /> class.
|
/// Initializes a new instance of the <see cref="UdpServerEntryPoint" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UdpServerEntryPoint(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
|
public UdpServerEntryPoint(
|
||||||
|
ILogger logger,
|
||||||
|
IServerApplicationHost appHost,
|
||||||
|
IJsonSerializer json,
|
||||||
|
ISocketFactory socketFactory)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
|
@ -41,9 +47,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
_socketFactory = socketFactory;
|
_socketFactory = socketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Runs this instance.
|
|
||||||
/// </summary>
|
|
||||||
public Task RunAsync()
|
public Task RunAsync()
|
||||||
{
|
{
|
||||||
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
|
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
|
||||||
|
@ -52,7 +56,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
udpServer.Start(PortNumber);
|
udpServer.Start(PortNumber);
|
||||||
|
|
||||||
UdpServer = udpServer;
|
_udpServer = udpServer;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -62,12 +66,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -78,9 +81,9 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
if (dispose)
|
if (dispose)
|
||||||
{
|
{
|
||||||
if (UdpServer != null)
|
if (_udpServer != null)
|
||||||
{
|
{
|
||||||
UdpServer.Dispose();
|
_udpServer.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -282,6 +282,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task<HttpResponseInfo> Post(HttpRequestOptions options)
|
public Task<HttpResponseInfo> Post(HttpRequestOptions options)
|
||||||
=> SendAsync(options, HttpMethod.Post);
|
=> SendAsync(options, HttpMethod.Post);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -5,12 +7,10 @@ using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Emby.Server.Implementations.Services;
|
using Emby.Server.Implementations.Services;
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
@ -24,12 +24,12 @@ using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
|
||||||
namespace Emby.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class HttpResultFactory
|
/// Class HttpResultFactory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpResultFactory : IHttpResultFactory
|
public class HttpResultFactory : IHttpResultFactory
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -8,11 +8,17 @@ using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class ResponseFilter.
|
||||||
|
/// </summary>
|
||||||
public class ResponseFilter
|
public class ResponseFilter
|
||||||
{
|
{
|
||||||
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ResponseFilter"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
public ResponseFilter(ILogger logger)
|
public ResponseFilter(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -37,7 +43,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(exception.Message))
|
if (!string.IsNullOrEmpty(exception.Message))
|
||||||
{
|
{
|
||||||
var error = exception.Message.Replace(Environment.NewLine, " ");
|
var error = exception.Message.Replace(Environment.NewLine, " ", StringComparison.Ordinal);
|
||||||
error = RemoveControlCharacters(error);
|
error = RemoveControlCharacters(error);
|
||||||
|
|
||||||
res.Headers.Add("X-Application-Error-Code", error);
|
res.Headers.Add("X-Application-Error-Code", error);
|
||||||
|
@ -55,7 +61,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength)
|
if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength)
|
||||||
&& !string.IsNullOrEmpty(contentLength))
|
&& !string.IsNullOrEmpty(contentLength))
|
||||||
{
|
{
|
||||||
var length = long.Parse(contentLength, _usCulture);
|
var length = long.Parse(contentLength, CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Emby.Server.Implementations.SocketSharp;
|
using Emby.Server.Implementations.SocketSharp;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
|
|
@ -10,37 +10,20 @@ using Microsoft.Net.Http.Headers;
|
||||||
namespace Emby.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class StreamWriter
|
/// Class StreamWriter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
|
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the source stream.
|
/// The options.
|
||||||
/// </summary>
|
|
||||||
/// <value>The source stream.</value>
|
|
||||||
private Stream SourceStream { get; set; }
|
|
||||||
|
|
||||||
private byte[] SourceBytes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _options
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
|
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
|
||||||
/// <summary>
|
|
||||||
/// Gets the options.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The options.</value>
|
|
||||||
public IDictionary<string, string> Headers => _options;
|
|
||||||
|
|
||||||
public Action OnComplete { get; set; }
|
|
||||||
public Action OnError { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
|
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The source.</param>
|
/// <param name="source">The source.</param>
|
||||||
/// <param name="contentType">Type of the content.</param>
|
/// <param name="contentType">Type of the content.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
public StreamWriter(Stream source, string contentType)
|
public StreamWriter(Stream source, string contentType)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(contentType))
|
if (string.IsNullOrEmpty(contentType))
|
||||||
|
@ -65,6 +48,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The source.</param>
|
/// <param name="source">The source.</param>
|
||||||
/// <param name="contentType">Type of the content.</param>
|
/// <param name="contentType">Type of the content.</param>
|
||||||
|
/// <param name="contentLength">The content length.</param>
|
||||||
public StreamWriter(byte[] source, string contentType, int contentLength)
|
public StreamWriter(byte[] source, string contentType, int contentLength)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(contentType))
|
if (string.IsNullOrEmpty(contentType))
|
||||||
|
@ -78,6 +62,31 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
Headers[HeaderNames.ContentType] = contentType;
|
Headers[HeaderNames.ContentType] = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the source stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The source stream.</value>
|
||||||
|
private Stream SourceStream { get; set; }
|
||||||
|
|
||||||
|
private byte[] SourceBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the options.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The options.</value>
|
||||||
|
public IDictionary<string, string> Headers => _options;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires when complete.
|
||||||
|
/// </summary>
|
||||||
|
public Action OnComplete { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires when an error occours.
|
||||||
|
/// </summary>
|
||||||
|
public Action OnError { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
|
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -98,19 +107,13 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
if (OnError != null)
|
OnError?.Invoke();
|
||||||
{
|
|
||||||
OnError();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (OnComplete != null)
|
OnComplete?.Invoke();
|
||||||
{
|
|
||||||
OnComplete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ using Emby.Server.Implementations.Net;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Services;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using UtfUnknown;
|
using UtfUnknown;
|
||||||
|
@ -15,32 +14,74 @@ using UtfUnknown;
|
||||||
namespace Emby.Server.Implementations.HttpServer
|
namespace Emby.Server.Implementations.HttpServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class WebSocketConnection
|
/// Class WebSocketConnection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class WebSocketConnection : IWebSocketConnection
|
public class WebSocketConnection : IWebSocketConnection
|
||||||
{
|
{
|
||||||
public event EventHandler<EventArgs> Closed;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _socket
|
/// The logger.
|
||||||
/// </summary>
|
|
||||||
private readonly IWebSocket _socket;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _remote end point
|
|
||||||
/// </summary>
|
|
||||||
public string RemoteEndPoint { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The logger
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _json serializer
|
/// The json serializer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IJsonSerializer _jsonSerializer;
|
private readonly IJsonSerializer _jsonSerializer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The socket.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IWebSocket _socket;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket">The socket.</param>
|
||||||
|
/// <param name="remoteEndPoint">The remote end point.</param>
|
||||||
|
/// <param name="jsonSerializer">The json serializer.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">socket</exception>
|
||||||
|
public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
|
||||||
|
{
|
||||||
|
if (socket == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(socket));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(remoteEndPoint))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(remoteEndPoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonSerializer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(jsonSerializer));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
Id = Guid.NewGuid();
|
||||||
|
_jsonSerializer = jsonSerializer;
|
||||||
|
_socket = socket;
|
||||||
|
_socket.OnReceiveBytes = OnReceiveInternal;
|
||||||
|
|
||||||
|
RemoteEndPoint = remoteEndPoint;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
socket.Closed += OnSocketClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler<EventArgs> Closed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the remote end point.
|
||||||
|
/// </summary>
|
||||||
|
public string RemoteEndPoint { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the receive action.
|
/// Gets or sets the receive action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -64,6 +105,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The URL.</value>
|
/// <value>The URL.</value>
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the query string.
|
/// Gets or sets the query string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -71,44 +113,12 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
public IQueryCollection QueryString { get; set; }
|
public IQueryCollection QueryString { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
|
/// Gets the state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="socket">The socket.</param>
|
/// <value>The state.</value>
|
||||||
/// <param name="remoteEndPoint">The remote end point.</param>
|
public WebSocketState State => _socket.State;
|
||||||
/// <param name="jsonSerializer">The json serializer.</param>
|
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
/// <exception cref="ArgumentNullException">socket</exception>
|
|
||||||
public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
|
|
||||||
{
|
|
||||||
if (socket == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(socket));
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(remoteEndPoint))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(remoteEndPoint));
|
|
||||||
}
|
|
||||||
if (jsonSerializer == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(jsonSerializer));
|
|
||||||
}
|
|
||||||
if (logger == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(logger));
|
|
||||||
}
|
|
||||||
|
|
||||||
Id = Guid.NewGuid();
|
void OnSocketClosed(object sender, EventArgs e)
|
||||||
_jsonSerializer = jsonSerializer;
|
|
||||||
_socket = socket;
|
|
||||||
_socket.OnReceiveBytes = OnReceiveInternal;
|
|
||||||
|
|
||||||
RemoteEndPoint = remoteEndPoint;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
socket.Closed += socket_Closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void socket_Closed(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
Closed?.Invoke(this, EventArgs.Empty);
|
Closed?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
@ -210,6 +220,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
return _socket.SendAsync(buffer, true, cancellationToken);
|
return _socket.SendAsync(buffer, true, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task SendAsync(string text, CancellationToken cancellationToken)
|
public Task SendAsync(string text, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text))
|
if (string.IsNullOrEmpty(text))
|
||||||
|
@ -222,18 +233,11 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
return _socket.SendAsync(text, true, cancellationToken);
|
return _socket.SendAsync(text, true, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Gets the state.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The state.</value>
|
|
||||||
public WebSocketState State => _socket.State;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.IO
|
namespace Emby.Server.Implementations.IO
|
||||||
{
|
{
|
||||||
public class ExtendedFileSystemInfo
|
public class ExtendedFileSystemInfo
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -16,22 +18,22 @@ namespace Emby.Server.Implementations.IO
|
||||||
public class LibraryMonitor : ILibraryMonitor
|
public class LibraryMonitor : ILibraryMonitor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The file system watchers
|
/// The file system watchers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, FileSystemWatcher> _fileSystemWatchers = new ConcurrentDictionary<string, FileSystemWatcher>(StringComparer.OrdinalIgnoreCase);
|
private readonly ConcurrentDictionary<string, FileSystemWatcher> _fileSystemWatchers = new ConcurrentDictionary<string, FileSystemWatcher>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The affected paths
|
/// The affected paths.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<FileRefresher> _activeRefreshers = new List<FileRefresher>();
|
private readonly List<FileRefresher> _activeRefreshers = new List<FileRefresher>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dynamic list of paths that should be ignored. Added to during our own file sytem modifications.
|
/// A dynamic list of paths that should be ignored. Added to during our own file system modifications.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Any file name ending in any of these will be ignored by the watchers
|
/// Any file name ending in any of these will be ignored by the watchers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly HashSet<string> _alwaysIgnoreFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
private static readonly HashSet<string> _alwaysIgnoreFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -42,6 +42,10 @@ namespace Emby.Server.Implementations.Library
|
||||||
".grab",
|
".grab",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CoreResolutionIgnoreRule"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public CoreResolutionIgnoreRule(ILibraryManager libraryManager)
|
public CoreResolutionIgnoreRule(ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
|
|
@ -10,10 +10,17 @@ using MediaBrowser.Model.Cryptography;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default authentication provider.
|
||||||
|
/// </summary>
|
||||||
public class DefaultAuthenticationProvider : IAuthenticationProvider, IRequiresResolvedUser
|
public class DefaultAuthenticationProvider : IAuthenticationProvider, IRequiresResolvedUser
|
||||||
{
|
{
|
||||||
private readonly ICryptoProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DefaultAuthenticationProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cryptographyProvider">The cryptography provider.</param>
|
||||||
public DefaultAuthenticationProvider(ICryptoProvider cryptographyProvider)
|
public DefaultAuthenticationProvider(ICryptoProvider cryptographyProvider)
|
||||||
{
|
{
|
||||||
_cryptographyProvider = cryptographyProvider;
|
_cryptographyProvider = cryptographyProvider;
|
||||||
|
@ -38,12 +45,13 @@ namespace Emby.Server.Implementations.Library
|
||||||
// This is the version that we need to use for local users. Because reasons.
|
// This is the version that we need to use for local users. Because reasons.
|
||||||
public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
|
public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
|
||||||
{
|
{
|
||||||
bool success = false;
|
|
||||||
if (resolvedUser == null)
|
if (resolvedUser == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(resolvedUser));
|
throw new ArgumentNullException(nameof(resolvedUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
// As long as jellyfin supports passwordless users, we need this little block here to accommodate
|
// As long as jellyfin supports passwordless users, we need this little block here to accommodate
|
||||||
if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
|
if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,9 @@ using MediaBrowser.Model.Users;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default password reset provider.
|
||||||
|
/// </summary>
|
||||||
public class DefaultPasswordResetProvider : IPasswordResetProvider
|
public class DefaultPasswordResetProvider : IPasswordResetProvider
|
||||||
{
|
{
|
||||||
private const string BaseResetFileName = "passwordreset";
|
private const string BaseResetFileName = "passwordreset";
|
||||||
|
@ -22,6 +25,12 @@ namespace Emby.Server.Implementations.Library
|
||||||
private readonly string _passwordResetFileBase;
|
private readonly string _passwordResetFileBase;
|
||||||
private readonly string _passwordResetFileBaseDir;
|
private readonly string _passwordResetFileBaseDir;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DefaultPasswordResetProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configurationManager">The configuration manager.</param>
|
||||||
|
/// <param name="jsonSerializer">The JSON serializer.</param>
|
||||||
|
/// <param name="userManager">The user manager.</param>
|
||||||
public DefaultPasswordResetProvider(
|
public DefaultPasswordResetProvider(
|
||||||
IServerConfigurationManager configurationManager,
|
IServerConfigurationManager configurationManager,
|
||||||
IJsonSerializer jsonSerializer,
|
IJsonSerializer jsonSerializer,
|
||||||
|
@ -56,8 +65,8 @@ namespace Emby.Server.Implementations.Library
|
||||||
File.Delete(resetfile);
|
File.Delete(resetfile);
|
||||||
}
|
}
|
||||||
else if (string.Equals(
|
else if (string.Equals(
|
||||||
spr.Pin.Replace("-", string.Empty),
|
spr.Pin.Replace("-", string.Empty, StringComparison.Ordinal),
|
||||||
pin.Replace("-", string.Empty),
|
pin.Replace("-", string.Empty, StringComparison.Ordinal),
|
||||||
StringComparison.InvariantCultureIgnoreCase))
|
StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
var resetUser = _userManager.GetUserByName(spr.UserName);
|
var resetUser = _userManager.GetUserByName(spr.UserName);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
@ -4,37 +4,48 @@ using MediaBrowser.Controller.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An invalid authentication provider.
|
||||||
|
/// </summary>
|
||||||
public class InvalidAuthProvider : IAuthenticationProvider
|
public class InvalidAuthProvider : IAuthenticationProvider
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
public string Name => "InvalidOrMissingAuthenticationProvider";
|
public string Name => "InvalidOrMissingAuthenticationProvider";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool IsEnabled => true;
|
public bool IsEnabled => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task<ProviderAuthenticationResult> Authenticate(string username, string password)
|
public Task<ProviderAuthenticationResult> Authenticate(string username, string password)
|
||||||
{
|
{
|
||||||
throw new AuthenticationException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
|
throw new AuthenticationException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool HasPassword(User user)
|
public bool HasPassword(User user)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task ChangePassword(User user, string newPassword)
|
public Task ChangePassword(User user, string newPassword)
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
|
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
|
||||||
{
|
{
|
||||||
// Nothing here
|
// Nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string GetPasswordHash(User user)
|
public string GetPasswordHash(User user)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string GetEasyPasswordHash(User user)
|
public string GetEasyPasswordHash(User user)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -829,7 +831,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
IsFolder = isFolder,
|
IsFolder = isFolder,
|
||||||
OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
|
OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
|
||||||
Limit = 1,
|
Limit = 1,
|
||||||
DtoOptions = new DtoOptions(true)
|
DtoOptions = new DtoOptions(true)
|
||||||
};
|
};
|
||||||
|
@ -1257,7 +1259,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
||||||
{
|
{
|
||||||
if (query.Recursive && !query.ParentId.Equals(Guid.Empty))
|
if (query.Recursive && query.ParentId != Guid.Empty)
|
||||||
{
|
{
|
||||||
var parent = GetItemById(query.ParentId);
|
var parent = GetItemById(query.ParentId);
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -89,10 +91,9 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
Limit = 200,
|
Limit = 200,
|
||||||
|
|
||||||
OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
|
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
|
||||||
|
|
||||||
DtoOptions = dtoOptions
|
DtoOptions = dtoOptions
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class providing extension methods for working with paths.
|
||||||
|
/// </summary>
|
||||||
public static class PathExtensions
|
public static class PathExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -32,6 +35,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
int end = str.IndexOf(']', start);
|
int end = str.IndexOf(']', start);
|
||||||
return str.Substring(start, end - start);
|
return str.Substring(start, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for imdbid we also accept pattern matching
|
// for imdbid we also accept pattern matching
|
||||||
if (string.Equals(attrib, "imdbid", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(attrib, "imdbid", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -13,7 +15,7 @@ using MediaBrowser.Model.IO;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class AudioResolver
|
/// Class AudioResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AudioResolver : ItemResolver<MediaBrowser.Controller.Entities.Audio.Audio>, IMultiItemResolver
|
public class AudioResolver : ItemResolver<MediaBrowser.Controller.Entities.Audio.Audio>, IMultiItemResolver
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class MusicAlbumResolver
|
/// Class MusicAlbumResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
|
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MusicAlbumResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="fileSystem">The file system.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
|
public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -50,16 +56,25 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.IsDirectory) return null;
|
if (!args.IsDirectory)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid mis-identifying top folders
|
// Avoid mis-identifying top folders
|
||||||
if (args.HasParent<MusicAlbum>()) return null;
|
if (args.HasParent<MusicAlbum>())
|
||||||
if (args.Parent.IsRoot) return null;
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Parent.IsRoot)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return IsMusicAlbum(args) ? new MusicAlbum() : null;
|
return IsMusicAlbum(args) ? new MusicAlbum() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determine if the supplied file data points to a music album
|
/// Determine if the supplied file data points to a music album
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -78,8 +93,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
// Args points to an album if parent is an Artist folder or it directly contains music
|
// Args points to an album if parent is an Artist folder or it directly contains music
|
||||||
if (args.IsDirectory)
|
if (args.IsDirectory)
|
||||||
{
|
{
|
||||||
//if (args.Parent is MusicArtist) return true; //saves us from testing children twice
|
// if (args.Parent is MusicArtist) return true; //saves us from testing children twice
|
||||||
if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager)) return true;
|
if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -88,7 +106,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determine if the supplied list contains what we should consider music
|
/// Determine if the supplied list contains what we should consider music
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool ContainsMusic(IEnumerable<FileSystemMetadata> list,
|
private bool ContainsMusic(
|
||||||
|
IEnumerable<FileSystemMetadata> list,
|
||||||
bool allowSubfolders,
|
bool allowSubfolders,
|
||||||
IDirectoryService directoryService,
|
IDirectoryService directoryService,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
|
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class MusicArtistResolver
|
/// Class MusicArtistResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MusicArtistResolver : ItemResolver<MusicArtist>
|
public class MusicArtistResolver : ItemResolver<MusicArtist>
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="fileSystem">The file system.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="config">The configuration manager.</param>
|
||||||
public MusicArtistResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager, IServerConfigurationManager config)
|
public MusicArtistResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager, IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -41,7 +48,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
/// <returns>MusicArtist.</returns>
|
/// <returns>MusicArtist.</returns>
|
||||||
protected override MusicArtist Resolve(ItemResolveArgs args)
|
protected override MusicArtist Resolve(ItemResolveArgs args)
|
||||||
{
|
{
|
||||||
if (!args.IsDirectory) return null;
|
if (!args.IsDirectory)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't allow nested artists
|
// Don't allow nested artists
|
||||||
if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
|
if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
|
||||||
|
@ -79,6 +89,5 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||||
// If we contain an album assume we are an artist folder
|
// If we contain an album assume we are an artist folder
|
||||||
return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
|
return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -10,7 +12,7 @@ using MediaBrowser.Model.Entities;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a Path into a Video or Video subclass
|
/// Resolves a Path into a Video or Video subclass.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
|
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -7,18 +9,10 @@ using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Books
|
namespace Emby.Server.Implementations.Library.Resolvers.Books
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class BookResolver : MediaBrowser.Controller.Resolvers.ItemResolver<Book>
|
public class BookResolver : MediaBrowser.Controller.Resolvers.ItemResolver<Book>
|
||||||
{
|
{
|
||||||
private readonly string[] _validExtensions = { ".pdf", ".epub", ".mobi", ".cbr", ".cbz", ".azw3" };
|
private readonly string[] _validExtensions = { ".pdf", ".epub", ".mobi", ".cbr", ".cbz", ".azw3" };
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected override Book Resolve(ItemResolveArgs args)
|
protected override Book Resolve(ItemResolveArgs args)
|
||||||
{
|
{
|
||||||
var collectionType = args.GetCollectionType();
|
var collectionType = args.GetCollectionType();
|
||||||
|
@ -47,11 +41,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private Book GetBook(ItemResolveArgs args)
|
private Book GetBook(ItemResolveArgs args)
|
||||||
{
|
{
|
||||||
var bookFiles = args.FileSystemChildren.Where(f =>
|
var bookFiles = args.FileSystemChildren.Where(f =>
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Resolvers;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class FolderResolver
|
/// Class FolderResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FolderResolver : FolderResolver<Folder>
|
public class FolderResolver : FolderResolver<Folder>
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class FolderResolver
|
/// Class FolderResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TItemType">The type of the T item type.</typeparam>
|
/// <typeparam name="TItemType">The type of the T item type.</typeparam>
|
||||||
public abstract class FolderResolver<TItemType> : ItemResolver<TItemType>
|
public abstract class FolderResolver<TItemType> : ItemResolver<TItemType>
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MediaBrowser.Controller.Resolvers;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class ItemResolver
|
/// Class ItemResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public abstract class ItemResolver<T> : IItemResolver
|
public abstract class ItemResolver<T> : IItemResolver
|
||||||
|
|
|
@ -4,12 +4,11 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class BoxSetResolver
|
/// Class BoxSetResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BoxSetResolver : FolderResolver<BoxSet>
|
public class BoxSetResolver : FolderResolver<BoxSet>
|
||||||
{
|
{
|
||||||
|
@ -63,7 +62,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
private static void SetProviderIdFromPath(BaseItem item)
|
private static void SetProviderIdFromPath(BaseItem item)
|
||||||
{
|
{
|
||||||
//we need to only look at the name of this actual item (not parents)
|
// we need to only look at the name of this actual item (not parents)
|
||||||
var justName = Path.GetFileName(item.Path);
|
var justName = Path.GetFileName(item.Path);
|
||||||
|
|
||||||
var id = justName.GetAttributeValue("tmdbid");
|
var id = justName.GetAttributeValue("tmdbid");
|
||||||
|
|
|
@ -17,7 +17,7 @@ using MediaBrowser.Model.IO;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class MovieResolver
|
/// Class MovieResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
|
public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
/// <value>The priority.</value>
|
/// <value>The priority.</value>
|
||||||
public override ResolverPriority Priority => ResolverPriority.Third;
|
public override ResolverPriority Priority => ResolverPriority.Third;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public MultiItemResolverResult ResolveMultiple(
|
public MultiItemResolverResult ResolveMultiple(
|
||||||
Folder parent,
|
Folder parent,
|
||||||
List<FileSystemMetadata> files,
|
List<FileSystemMetadata> files,
|
||||||
|
@ -522,7 +523,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
CollectionType.MusicVideos,
|
CollectionType.MusicVideos,
|
||||||
CollectionType.Movies,
|
CollectionType.Movies,
|
||||||
CollectionType.Photos
|
CollectionType.Photos
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool IsInvalid(Folder parent, string collectionType)
|
private bool IsInvalid(Folder parent, string collectionType)
|
||||||
{
|
{
|
||||||
|
@ -544,6 +545,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
|
|
||||||
private IImageProcessor _imageProcessor;
|
private IImageProcessor _imageProcessor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MovieResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="imageProcessor">The image processor.</param>
|
||||||
public MovieResolver(ILibraryManager libraryManager, IImageProcessor imageProcessor)
|
public MovieResolver(ILibraryManager libraryManager, IImageProcessor imageProcessor)
|
||||||
: base(libraryManager)
|
: base(libraryManager)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,11 +7,19 @@ using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class PhotoAlbumResolver.
|
||||||
|
/// </summary>
|
||||||
public class PhotoAlbumResolver : FolderResolver<PhotoAlbum>
|
public class PhotoAlbumResolver : FolderResolver<PhotoAlbum>
|
||||||
{
|
{
|
||||||
private readonly IImageProcessor _imageProcessor;
|
private readonly IImageProcessor _imageProcessor;
|
||||||
private ILibraryManager _libraryManager;
|
private ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PhotoAlbumResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="imageProcessor">The image processor.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public PhotoAlbumResolver(IImageProcessor imageProcessor, ILibraryManager libraryManager)
|
public PhotoAlbumResolver(IImageProcessor imageProcessor, ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_imageProcessor = imageProcessor;
|
_imageProcessor = imageProcessor;
|
||||||
|
@ -74,9 +82,11 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override ResolverPriority Priority => ResolverPriority.Second;
|
public override ResolverPriority Priority => ResolverPriority.Second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Extensions;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -7,7 +7,7 @@ using MediaBrowser.Model.Entities;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class EpisodeResolver
|
/// Class EpisodeResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EpisodeResolver : BaseVideoResolver<Episode>
|
public class EpisodeResolver : BaseVideoResolver<Episode>
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
}
|
}
|
||||||
|
|
||||||
var season = parent as Season;
|
var season = parent as Season;
|
||||||
|
|
||||||
// Just in case the user decided to nest episodes.
|
// Just in case the user decided to nest episodes.
|
||||||
// Not officially supported but in some cases we can handle it.
|
// Not officially supported but in some cases we can handle it.
|
||||||
if (season == null)
|
if (season == null)
|
||||||
|
@ -73,6 +74,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EpisodeResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public EpisodeResolver(ILibraryManager libraryManager)
|
public EpisodeResolver(ILibraryManager libraryManager)
|
||||||
: base(libraryManager)
|
: base(libraryManager)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -14,7 +16,7 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class SeriesResolver
|
/// Class SeriesResolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SeriesResolver : FolderResolver<Series>
|
public class SeriesResolver : FolderResolver<Series>
|
||||||
{
|
{
|
||||||
|
@ -22,6 +24,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SeriesResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileSystem">The file system.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
|
public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -13,8 +15,6 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
public class SearchEngine : ISearchEngine
|
public class SearchEngine : ISearchEngine
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
@ -162,7 +162,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
Limit = query.Limit,
|
Limit = query.Limit,
|
||||||
IncludeItemsByName = string.IsNullOrEmpty(query.ParentId),
|
IncludeItemsByName = string.IsNullOrEmpty(query.ParentId),
|
||||||
ParentId = string.IsNullOrEmpty(query.ParentId) ? Guid.Empty : new Guid(query.ParentId),
|
ParentId = string.IsNullOrEmpty(query.ParentId) ? Guid.Empty : new Guid(query.ParentId),
|
||||||
OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
|
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
|
||||||
Recursive = true,
|
Recursive = true,
|
||||||
|
|
||||||
IsKids = query.IsKids,
|
IsKids = query.IsKids,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -15,7 +17,7 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class UserDataManager
|
/// Class UserDataManager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UserDataManager : IUserDataManager
|
public class UserDataManager : IUserDataManager
|
||||||
{
|
{
|
||||||
|
@ -55,6 +57,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(userData));
|
throw new ArgumentNullException(nameof(userData));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(item));
|
throw new ArgumentNullException(nameof(item));
|
||||||
|
@ -160,11 +163,6 @@ namespace Emby.Server.Implementations.Library
|
||||||
return GetUserData(user, item.Id, item.GetUserDataKeys());
|
return GetUserData(user, item.Id, item.GetUserDataKeys());
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserItemData GetUserData(string userId, BaseItem item)
|
|
||||||
{
|
|
||||||
return GetUserData(new Guid(userId), item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserItemData GetUserData(Guid userId, BaseItem item)
|
public UserItemData GetUserData(Guid userId, BaseItem item)
|
||||||
{
|
{
|
||||||
return GetUserData(userId, item.Id, item.GetUserDataKeys());
|
return GetUserData(userId, item.Id, item.GetUserDataKeys());
|
||||||
|
@ -228,24 +226,21 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
var pctIn = decimal.Divide(positionTicks, runtimeTicks) * 100;
|
var pctIn = decimal.Divide(positionTicks, runtimeTicks) * 100;
|
||||||
|
|
||||||
// Don't track in very beginning
|
|
||||||
if (pctIn < _config.Configuration.MinResumePct)
|
if (pctIn < _config.Configuration.MinResumePct)
|
||||||
{
|
{
|
||||||
|
// ignore progress during the beginning
|
||||||
positionTicks = 0;
|
positionTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're at the end, assume completed
|
|
||||||
else if (pctIn > _config.Configuration.MaxResumePct || positionTicks >= runtimeTicks)
|
else if (pctIn > _config.Configuration.MaxResumePct || positionTicks >= runtimeTicks)
|
||||||
{
|
{
|
||||||
|
// mark as completed close to the end
|
||||||
positionTicks = 0;
|
positionTicks = 0;
|
||||||
data.Played = playedToCompletion = true;
|
data.Played = playedToCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Enforce MinResumeDuration
|
// Enforce MinResumeDuration
|
||||||
var durationSeconds = TimeSpan.FromTicks(runtimeTicks).TotalSeconds;
|
var durationSeconds = TimeSpan.FromTicks(runtimeTicks).TotalSeconds;
|
||||||
|
|
||||||
if (durationSeconds < _config.Configuration.MinResumeDurationSeconds)
|
if (durationSeconds < _config.Configuration.MinResumeDurationSeconds)
|
||||||
{
|
{
|
||||||
positionTicks = 0;
|
positionTicks = 0;
|
||||||
|
@ -265,6 +260,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
positionTicks = 0;
|
positionTicks = 0;
|
||||||
data.Played = false;
|
data.Played = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.SupportsPositionTicksResume)
|
if (!item.SupportsPositionTicksResume)
|
||||||
{
|
{
|
||||||
positionTicks = 0;
|
positionTicks = 0;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -36,19 +38,19 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class UserManager
|
/// Class UserManager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UserManager : IUserManager
|
public class UserManager : IUserManager
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
private readonly object _policySyncLock = new object();
|
private readonly object _policySyncLock = new object();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the active user repository
|
/// Gets the active user repository.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The user repository.</value>
|
/// <value>The user repository.</value>
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
|
@ -194,10 +196,6 @@ namespace Emby.Server.Implementations.Library
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public User GetUserById(string id)
|
|
||||||
=> GetUserById(new Guid(id));
|
|
||||||
|
|
||||||
public User GetUserByName(string name)
|
public User GetUserByName(string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
@ -358,6 +356,8 @@ namespace Emby.Server.Implementations.Library
|
||||||
return success ? user : null;
|
return success ? user : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
private static string GetAuthenticationProviderId(IAuthenticationProvider provider)
|
private static string GetAuthenticationProviderId(IAuthenticationProvider provider)
|
||||||
{
|
{
|
||||||
return provider.GetType().FullName;
|
return provider.GetType().FullName;
|
||||||
|
@ -378,7 +378,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
return GetPasswordResetProviders(user)[0];
|
return GetPasswordResetProviders(user)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private IAuthenticationProvider[] GetAuthenticationProviders(User user)
|
private IAuthenticationProvider[] GetAuthenticationProviders(User? user)
|
||||||
{
|
{
|
||||||
var authenticationProviderId = user?.Policy.AuthenticationProviderId;
|
var authenticationProviderId = user?.Policy.AuthenticationProviderId;
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPasswordResetProvider[] GetPasswordResetProviders(User user)
|
private IPasswordResetProvider[] GetPasswordResetProviders(User? user)
|
||||||
{
|
{
|
||||||
var passwordResetProviderId = user?.Policy.PasswordResetProviderId;
|
var passwordResetProviderId = user?.Policy.PasswordResetProviderId;
|
||||||
|
|
||||||
|
@ -418,7 +418,11 @@ namespace Emby.Server.Implementations.Library
|
||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<(string username, bool success)> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
|
private async Task<(string username, bool success)> AuthenticateWithProvider(
|
||||||
|
IAuthenticationProvider provider,
|
||||||
|
string username,
|
||||||
|
string password,
|
||||||
|
User? resolvedUser)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -442,15 +446,15 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<(IAuthenticationProvider authenticationProvider, string username, bool success)> AuthenticateLocalUser(
|
private async Task<(IAuthenticationProvider? authenticationProvider, string username, bool success)> AuthenticateLocalUser(
|
||||||
string username,
|
string username,
|
||||||
string password,
|
string password,
|
||||||
string hashedPassword,
|
string hashedPassword,
|
||||||
User user,
|
User? user,
|
||||||
string remoteEndPoint)
|
string remoteEndPoint)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
IAuthenticationProvider authenticationProvider = null;
|
IAuthenticationProvider? authenticationProvider = null;
|
||||||
|
|
||||||
foreach (var provider in GetAuthenticationProviders(user))
|
foreach (var provider in GetAuthenticationProviders(user))
|
||||||
{
|
{
|
||||||
|
@ -547,6 +551,8 @@ namespace Emby.Server.Implementations.Library
|
||||||
_users[user.Id] = user;
|
_users[user.Id] = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable restore
|
||||||
|
|
||||||
public UserDto GetUserDto(User user, string remoteEndPoint = null)
|
public UserDto GetUserDto(User user, string remoteEndPoint = null)
|
||||||
{
|
{
|
||||||
if (user == null)
|
if (user == null)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -340,7 +342,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
var query = new InternalItemsQuery(user)
|
var query = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = includeItemTypes,
|
IncludeItemTypes = includeItemTypes,
|
||||||
OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
|
OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
|
||||||
IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
|
IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
|
||||||
ExcludeItemTypes = excludeItemTypes,
|
ExcludeItemTypes = excludeItemTypes,
|
||||||
IsVirtualItem = false,
|
IsVirtualItem = false,
|
||||||
|
|
|
@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Validators
|
namespace Emby.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class ArtistsPostScanTask
|
/// Class ArtistsPostScanTask.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ArtistsPostScanTask : ILibraryPostScanTask
|
public class ArtistsPostScanTask : ILibraryPostScanTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _library manager
|
/// The _library manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
@ -23,6 +23,8 @@ namespace Emby.Server.Implementations.Library.Validators
|
||||||
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="itemRepo">The item repository.</param>
|
||||||
public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
|
|
@ -12,17 +12,17 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Validators
|
namespace Emby.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class ArtistsValidator
|
/// Class ArtistsValidator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ArtistsValidator
|
public class ArtistsValidator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _library manager
|
/// The library manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IItemRepository _itemRepo;
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
|
@ -7,6 +7,9 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Validators
|
namespace Emby.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class GenresPostScanTask.
|
||||||
|
/// </summary>
|
||||||
public class GenresPostScanTask : ILibraryPostScanTask
|
public class GenresPostScanTask : ILibraryPostScanTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -7,19 +7,28 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Validators
|
namespace Emby.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
class GenresValidator
|
/// <summary>
|
||||||
|
/// Class GenresValidator.
|
||||||
|
/// </summary>
|
||||||
|
public class GenresValidator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _library manager
|
/// The library manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IItemRepository _itemRepo;
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GenresValidator"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="itemRepo">The item repository.</param>
|
||||||
public GenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
public GenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
|
|
@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Emby.Server.Implementations.Library.Validators
|
namespace Emby.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class MusicGenresPostScanTask
|
/// Class MusicGenresPostScanTask.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MusicGenresPostScanTask : ILibraryPostScanTask
|
public class MusicGenresPostScanTask : ILibraryPostScanTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _library manager
|
/// The library manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user