diff options
| author | Luke <luke.pulverenti@gmail.com> | 2016-01-19 14:54:07 -0500 |
|---|---|---|
| committer | Luke <luke.pulverenti@gmail.com> | 2016-01-19 14:54:07 -0500 |
| commit | 236b5caee2797d4a8af857cea2f3859bc94d3948 (patch) | |
| tree | 210242ec629d84baa9811dacdad3931a4e5c7b35 | |
| parent | e951dd20d95c81da29d4f9d8a2cb927e7639518b (diff) | |
| parent | a5d54256ffb79dd1d0a06df0536f772bbeff9d3d (diff) | |
Merge pull request #1409 from MediaBrowser/beta
merge from beta
112 files changed, 2820 insertions, 1114 deletions
diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index e9911a12d..45ac97ecc 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -33,11 +33,11 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\ImageMagickSharp.1.0.0.16\lib\net45\ImageMagickSharp.dll</HintPath> + <HintPath>..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 64ddf7e88..6858c6d52 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -72,11 +72,16 @@ namespace Emby.Drawing.ImageMagick private void LogVersion() { - _logger.Info("ImageMagick version: " + Wand.VersionString); + _logger.Info("ImageMagick version: " + GetVersion()); TestWebp(); Wand.SetMagickThreadCount(1); } + public static string GetVersion() + { + return Wand.VersionString; + } + private bool _webpAvailable = true; private void TestWebp() { @@ -148,7 +153,7 @@ namespace Emby.Drawing.ImageMagick DrawIndicator(originalImage, width, height, options); originalImage.CurrentImage.CompressionQuality = quality; - //originalImage.CurrentImage.StripImage(); + originalImage.CurrentImage.StripImage(); originalImage.SaveImage(outputPath); } @@ -165,7 +170,7 @@ namespace Emby.Drawing.ImageMagick DrawIndicator(wand, width, height, options); wand.CurrentImage.CompressionQuality = quality; - //wand.CurrentImage.StripImage(); + wand.CurrentImage.StripImage(); wand.SaveImage(outputPath); } @@ -176,15 +181,16 @@ namespace Emby.Drawing.ImageMagick private void ScaleImage(MagickWand wand, int width, int height) { - wand.CurrentImage.ResizeImage(width, height); - //if (_config.Configuration.EnableHighQualityImageScaling) - //{ - // wand.CurrentImage.ResizeImage(width, height); - //} - //else - //{ - // wand.CurrentImage.ScaleImage(width, height); - //} + var highQuality = false; + + if (highQuality) + { + wand.CurrentImage.ResizeImage(width, height); + } + else + { + wand.CurrentImage.ScaleImage(width, height); + } } /// <summary> diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 0fcdc278e..51731c474 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> - <package id="ImageMagickSharp" version="1.0.0.16" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> + <package id="ImageMagickSharp" version="1.0.0.17" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index f453036d7..8e1abef14 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -17,6 +17,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Api { @@ -112,13 +113,15 @@ namespace MediaBrowser.Api private readonly IServerApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; private readonly ILibraryManager _libraryManager; + private readonly IJsonSerializer _json; - public ItemLookupService(IProviderManager providerManager, IServerApplicationPaths appPaths, IFileSystem fileSystem, ILibraryManager libraryManager) + public ItemLookupService(IProviderManager providerManager, IServerApplicationPaths appPaths, IFileSystem fileSystem, ILibraryManager libraryManager, IJsonSerializer json) { _providerManager = providerManager; _appPaths = appPaths; _fileSystem = fileSystem; _libraryManager = libraryManager; + _json = json; } public object Get(GetExternalIdInfos request) @@ -199,6 +202,7 @@ namespace MediaBrowser.Api // item.SetProviderId(key.Key, value); // } //} + Logger.Info("Setting provider id's to item {0}-{1}: {2}", item.Id, item.Name, _json.SerializeToString(request.ProviderIds)); item.ProviderIds = request.ProviderIds; var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem) diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 319bc13fd..b7066a36d 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -162,6 +162,14 @@ namespace MediaBrowser.Api.Library public string Id { get; set; } } + [Route("/Items", "DELETE", Summary = "Deletes an item from the library and file system")] + [Authenticated] + public class DeleteItems : IReturnVoid + { + [ApiMember(Name = "Ids", Description = "Ids", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Ids { get; set; } + } + [Route("/Items/Counts", "GET")] [Authenticated] public class GetItemCounts : IReturn<ItemCounts> @@ -715,27 +723,49 @@ namespace MediaBrowser.Api.Library /// Deletes the specified request. /// </summary> /// <param name="request">The request.</param> - public void Delete(DeleteItem request) + public void Delete(DeleteItems request) { - var item = _libraryManager.GetItemById(request.Id); - var auth = _authContext.GetAuthorizationInfo(Request); - var user = _userManager.GetUserById(auth.UserId); + var ids = string.IsNullOrWhiteSpace(request.Ids) + ? new string[] { } + : request.Ids.Split(','); - if (!item.CanDelete(user)) + var tasks = ids.Select(i => { - throw new SecurityException("Unauthorized access"); - } + var item = _libraryManager.GetItemById(i); + var auth = _authContext.GetAuthorizationInfo(Request); + var user = _userManager.GetUserById(auth.UserId); - if (item is ILiveTvRecording) - { - var task = _liveTv.DeleteRecording(request.Id); - Task.WaitAll(task); - } - else + if (!item.CanDelete(user)) + { + if (ids.Length > 1) + { + throw new SecurityException("Unauthorized access"); + } + + return Task.FromResult(true); + } + + if (item is ILiveTvRecording) + { + return _liveTv.DeleteRecording(i); + } + + return _libraryManager.DeleteItem(item); + }).ToArray(); + + Task.WaitAll(tasks); + } + + /// <summary> + /// Deletes the specified request. + /// </summary> + /// <param name="request">The request.</param> + public void Delete(DeleteItem request) + { + Delete(new DeleteItems { - var task = _libraryManager.DeleteItem(item); - Task.WaitAll(task); - } + Ids = request.Id + }); } /// <summary> diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 7be644bc8..7e55446ae 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -47,7 +47,10 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> + </Reference> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> @@ -63,9 +66,6 @@ <Reference Include="ServiceStack.Text"> <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath> </Reference> - <Reference Include="MoreLinq"> - <HintPath>..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll</HintPath> - </Reference> </ItemGroup> <ItemGroup> <Compile Include="..\SharedVersion.cs"> diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 4f9efad50..6d8378aae 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -233,7 +233,7 @@ namespace MediaBrowser.Api throw new ResourceNotFoundException(string.Format("Package not found: {0}", request.Name)); } - Task.Run(() => _installationManager.InstallPackage(package, new Progress<double>(), CancellationToken.None)); + Task.Run(() => _installationManager.InstallPackage(package, true, new Progress<double>(), CancellationToken.None)); } /// <summary> diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4de29b3f2..9e2e399d7 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1562,6 +1562,13 @@ namespace MediaBrowser.Api.Playback RequestedUrl = url }; + //if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 || + // (Request.UserAgent ?? string.Empty).IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 || + // (Request.UserAgent ?? string.Empty).IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1) + //{ + // state.SegmentLength = 6; + //} + if (!string.IsNullOrWhiteSpace(request.AudioCodec)) { state.SupportedAudioCodecs = request.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 60412159c..766e8a003 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -111,7 +111,8 @@ namespace MediaBrowser.Api.Playback.Hls throw; } - await WaitForMinimumSegmentCount(playlist, 3, cancellationTokenSource.Token).ConfigureAwait(false); + var waitForSegments = state.SegmentLength >= 10 ? 2 : 3; + await WaitForMinimumSegmentCount(playlist, waitForSegments, cancellationTokenSource.Token).ConfigureAwait(false); } } finally diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 302b8d834..602119d4f 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -179,6 +179,7 @@ namespace MediaBrowser.Api if (primaryImageTag != null) { result.PrimaryImageTag = primaryImageTag; + result.PrimaryImageAspectRatio = _dtoService.GetPrimaryImageAspectRatio(item); } SetThumbImageInfo(result, item); diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 3f2b3d66a..2661c245f 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -13,6 +13,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Net; namespace MediaBrowser.Api.System { @@ -32,6 +33,12 @@ namespace MediaBrowser.Api.System } + [Route("/System/Ping", "POST")] + public class PingSystem : IReturnVoid + { + + } + /// <summary> /// Class RestartApplication /// </summary> @@ -59,7 +66,7 @@ namespace MediaBrowser.Api.System [Route("/System/Endpoint", "GET", Summary = "Gets information about the request endpoint")] [Authenticated] - public class GetEndpointInfo : IReturn<EndpointInfo> + public class GetEndpointInfo : IReturn<EndPointInfo> { public string Endpoint { get; set; } } @@ -104,6 +111,11 @@ namespace MediaBrowser.Api.System _security = security; } + public object Post(PingSystem request) + { + return _appHost.Name; + } + public object Get(GetServerLogs request) { List<FileSystemMetadata> files; @@ -199,17 +211,11 @@ namespace MediaBrowser.Api.System public object Get(GetEndpointInfo request) { - return ToOptimizedResult(new EndpointInfo + return ToOptimizedResult(new EndPointInfo { IsLocal = Request.IsLocal, IsInNetwork = _network.IsInLocalNetwork(request.Endpoint ?? Request.RemoteIp) }); } } - - public class EndpointInfo - { - public bool IsLocal { get; set; } - public bool IsInNetwork { get; set; } - } } diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index d96012318..83890e697 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> - <package id="morelinq" version="1.1.1" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> + <package id="morelinq" version="1.4.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 6dc97100d..2a93efcde 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Common.Implementations /// Gets the HTTP client. /// </summary> /// <value>The HTTP client.</value> - protected IHttpClient HttpClient { get; private set; } + public IHttpClient HttpClient { get; private set; } /// <summary> /// Gets the network manager. /// </summary> diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 054c5aaaf..c30cdf1a7 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -150,7 +150,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager request.Method = method; request.Timeout = options.TimeoutMs; - + if (httpWebRequest != null) { if (!string.IsNullOrEmpty(options.Host)) diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index d857e58b6..cb3a284c1 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -49,11 +49,13 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> - <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\NLog.4.1.1\lib\net45\NLog.dll</HintPath> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> + </Reference> + <Reference Include="NLog"> + <HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> @@ -62,13 +64,14 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath> </Reference> - <Reference Include="SimpleInjector, Version=2.8.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\SimpleInjector.3.0.5\lib\net45\SimpleInjector.dll</HintPath> + <Reference Include="SimpleInjector"> + <HintPath>..\packages\SimpleInjector.3.1.2\lib\net45\SimpleInjector.dll</HintPath> </Reference> <Reference Include="System" /> + <Reference Include="System.Configuration" /> <Reference Include="System.Core" /> <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> <Reference Include="System.Net" /> <Reference Include="System.Xml" /> <Reference Include="ServiceStack.Text"> @@ -105,6 +108,7 @@ <Compile Include="Security\SuppporterInfoResponse.cs" /> <Compile Include="Serialization\JsonSerializer.cs" /> <Compile Include="Serialization\XmlSerializer.cs" /> + <Compile Include="Updates\GithubUpdater.cs" /> <Compile Include="Updates\InstallationManager.cs" /> </ItemGroup> <ItemGroup> diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index c27dfd68d..bc3dc360f 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -7,6 +7,7 @@ using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Threading; +using MoreLinq; namespace MediaBrowser.Common.Implementations.Networking { @@ -31,14 +32,14 @@ namespace MediaBrowser.Common.Implementations.Networking } } - private volatile List<string> _localIpAddresses; + private volatile List<IPAddress> _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); /// <summary> /// Gets the machine's local ip address /// </summary> /// <returns>IPAddress.</returns> - public IEnumerable<string> GetLocalIpAddresses() + public IEnumerable<IPAddress> GetLocalIpAddresses() { if (_localIpAddresses == null) { @@ -58,25 +59,24 @@ namespace MediaBrowser.Common.Implementations.Networking return _localIpAddresses; } - private IEnumerable<string> GetLocalIpAddressesInternal() + private IEnumerable<IPAddress> GetLocalIpAddressesInternal() { var list = GetIPsDefault() - .Where(i => !IPAddress.IsLoopback(i)) - .Select(i => i.ToString()) - .Where(FilterIpAddress) .ToList(); - if (list.Count > 0) + if (list.Count == 0) { - return list; + list.AddRange(GetLocalIpAddressesFallback()); } - return GetLocalIpAddressesFallback().Where(FilterIpAddress); + return list.Where(FilterIpAddress).DistinctBy(i => i.ToString()); } - private bool FilterIpAddress(string address) + private bool FilterIpAddress(IPAddress address) { - if (address.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + var addressString = address.ToString (); + + if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) { return false; } @@ -84,8 +84,16 @@ namespace MediaBrowser.Common.Implementations.Networking return true; } - private bool IsInPrivateAddressSpace(string endpoint) + public bool IsInPrivateAddressSpace(string endpoint) { + if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Handle ipv4 mapped to ipv6 + endpoint = endpoint.Replace("::ffff:", string.Empty); + // Private address space: // http://en.wikipedia.org/wiki/Private_network @@ -96,9 +104,6 @@ namespace MediaBrowser.Common.Implementations.Networking return - // If url was requested with computer name, we may see this - endpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 || - endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) || @@ -131,26 +136,41 @@ namespace MediaBrowser.Common.Implementations.Networking throw new ArgumentNullException("endpoint"); } - if (IsInPrivateAddressSpace(endpoint)) - { - return true; - } - - const int lengthMatch = 4; - - if (endpoint.Length >= lengthMatch) + IPAddress address; + if (IPAddress.TryParse(endpoint, out address)) { - var prefix = endpoint.Substring(0, lengthMatch); + var addressString = address.ToString(); - if (GetLocalIpAddresses() - .Any(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + int lengthMatch = 100; + if (address.AddressFamily == AddressFamily.InterNetwork) { - return true; + lengthMatch = 4; + if (IsInPrivateAddressSpace(addressString)) + { + return true; + } + } + else if (address.AddressFamily == AddressFamily.InterNetworkV6) + { + lengthMatch = 10; + if (IsInPrivateAddressSpace(endpoint)) + { + return true; + } } - } - IPAddress address; - if (resolveHost && !IPAddress.TryParse(endpoint, out address)) + // Should be even be doing this with ipv6? + if (addressString.Length >= lengthMatch) + { + var prefix = addressString.Substring(0, lengthMatch); + + if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + { + return true; + } + } + } + else if (resolveHost) { Uri uri; if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri)) @@ -188,33 +208,45 @@ namespace MediaBrowser.Common.Implementations.Networking return Dns.GetHostAddresses(hostName); } - private IEnumerable<IPAddress> GetIPsDefault() - { - foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) - { - var props = adapter.GetIPProperties(); - var gateways = from ga in props.GatewayAddresses - where !ga.Address.Equals(IPAddress.Any) - select true; - - if (!gateways.Any()) - { - continue; - } - - foreach (var uni in props.UnicastAddresses) - { - var address = uni.Address; - if (address.AddressFamily != AddressFamily.InterNetwork) - { - continue; - } - yield return address; - } - } - } - - private IEnumerable<string> GetLocalIpAddressesFallback() + private List<IPAddress> GetIPsDefault() + { + NetworkInterface[] interfaces; + + try + { + interfaces = NetworkInterface.GetAllNetworkInterfaces(); + } + catch (Exception ex) + { + Logger.ErrorException("Error in GetAllNetworkInterfaces", ex); + return new List<IPAddress>(); + } + + return interfaces.SelectMany(network => { + + try + { + Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); + + var properties = network.GetIPProperties(); + + return properties.UnicastAddresses + .Where(i => i.IsDnsEligible) + .Select(i => i.Address) + .Where(i => i.AddressFamily == AddressFamily.InterNetwork) + .ToList(); + } + catch (Exception ex) + { + Logger.ErrorException("Error querying network interface", ex); + return new List<IPAddress>(); + } + + }).DistinctBy(i => i.ToString()) + .ToList(); + } + + private IEnumerable<IPAddress> GetLocalIpAddressesFallback() { var host = Dns.GetHostEntry(Dns.GetHostName()); @@ -222,7 +254,6 @@ namespace MediaBrowser.Common.Implementations.Networking // It's not fool-proof so ultimately the consumer will have to examine them and decide return host.AddressList .Where(i => i.AddressFamily == AddressFamily.InterNetwork) - .Select(i => i.ToString()) .Reverse(); } diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs new file mode 100644 index 000000000..360428072 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Updates; + +namespace MediaBrowser.Common.Implementations.Updates +{ + public class GithubUpdater + { + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + private TimeSpan _cacheLength; + + public GithubUpdater(IHttpClient httpClient, IJsonSerializer jsonSerializer, TimeSpan cacheLength) + { + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + _cacheLength = cacheLength; + } + + public async Task<CheckForUpdateResult> CheckForUpdateResult(string organzation, string repository, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename, CancellationToken cancellationToken) + { + var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository); + + var options = new HttpRequestOptions + { + Url = url, + EnableKeepAlive = false, + CancellationToken = cancellationToken, + UserAgent = "Emby/3.0" + + }; + + if (_cacheLength.Ticks > 0) + { + options.CacheMode = CacheMode.Unconditional; + options.CacheLength = _cacheLength; + } + + using (var stream = await _httpClient.Get(options).ConfigureAwait(false)) + { + var obj = _jsonSerializer.DeserializeFromStream<RootObject[]>(stream); + + return CheckForUpdateResult(obj, minVersion, updateLevel, assetFilename, packageName, targetFilename); + } + } + + private CheckForUpdateResult CheckForUpdateResult(RootObject[] obj, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename) + { + if (updateLevel == PackageVersionClass.Release) + { + obj = obj.Where(i => !i.prerelease).ToArray(); + } + else if (updateLevel == PackageVersionClass.Beta) + { + obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray(); + } + else if (updateLevel == PackageVersionClass.Dev) + { + obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) || i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray(); + } + + var availableUpdate = obj + .Select(i => CheckForUpdateResult(i, minVersion, assetFilename, packageName, targetFilename)) + .Where(i => i != null) + .OrderByDescending(i => Version.Parse(i.AvailableVersion)) + .FirstOrDefault(); + + return availableUpdate ?? new CheckForUpdateResult + { + IsUpdateAvailable = false + }; + } + + private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename) + { + Version version; + if (!Version.TryParse(obj.tag_name, out version)) + { + return null; + } + + if (version < minVersion) + { + return null; + } + + var asset = (obj.assets ?? new List<Asset>()).FirstOrDefault(i => IsAsset(i, assetFilename)); + + if (asset == null) + { + return null; + } + + return new CheckForUpdateResult + { + AvailableVersion = version.ToString(), + IsUpdateAvailable = version > minVersion, + Package = new PackageVersionInfo + { + classification = obj.prerelease ? + (obj.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase) ? PackageVersionClass.Dev : PackageVersionClass.Beta) : + PackageVersionClass.Release, + name = packageName, + sourceUrl = asset.browser_download_url, + targetFilename = targetFilename, + versionStr = version.ToString(), + requiredVersionStr = "1.0.0", + description = obj.body + } + }; + } + + private bool IsAsset(Asset asset, string assetFilename) + { + var downloadFilename = Path.GetFileName(asset.browser_download_url) ?? string.Empty; + + if (downloadFilename.IndexOf(assetFilename, StringComparison.OrdinalIgnoreCase) != -1) + { + return true; + } + + return string.Equals(assetFilename, downloadFilename, StringComparison.OrdinalIgnoreCase); + } + + public class Uploader + { + public string login { get; set; } + public int id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class Asset + { + public string url { get; set; } + public int id { get; set; } + public string name { get; set; } + public object label { get; set; } + public Uploader uploader { get; set; } + public string content_type { get; set; } + public string state { get; set; } + public int size { get; set; } + public int download_count { get; set; } + public string created_at { get; set; } + public string updated_at { get; set; } + public string browser_download_url { get; set; } + } + + public class Author + { + public string login { get; set; } + public int id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class RootObject + { + public string url { get; set; } + public string assets_url { get; set; } + public string upload_url { get; set; } + public string html_url { get; set; } + public int id { get; set; } + public string tag_name { get; set; } + public string target_commitish { get; set; } + public string name { get; set; } + public bool draft { get; set; } + public Author author { get; set; } + public bool prerelease { get; set; } + public string created_at { get; set; } + public string published_at { get; set; } + public List<Asset> assets { get; set; } + public string tarball_url { get; set; } + public string zipball_url { get; set; } + public string body { get; set; } + } + } +} diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index 6d68b968b..8e0df9005 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -437,11 +437,12 @@ namespace MediaBrowser.Common.Implementations.Updates /// Installs the package. /// </summary> /// <param name="package">The package.</param> + /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">package</exception> - public async Task InstallPackage(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken) + public async Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken) { if (package == null) { @@ -494,7 +495,7 @@ namespace MediaBrowser.Common.Implementations.Updates try { - await InstallPackageInternal(package, innerProgress, linkedToken).ConfigureAwait(false); + await InstallPackageInternal(package, isPlugin, innerProgress, linkedToken).ConfigureAwait(false); lock (CurrentInstallations) { @@ -550,18 +551,17 @@ namespace MediaBrowser.Common.Implementations.Updates /// Installs the package internal. /// </summary> /// <param name="package">The package.</param> + /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - private async Task InstallPackageInternal(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken) + private async Task InstallPackageInternal(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken) { // Do the install await PerformPackageInstallation(progress, package, cancellationToken).ConfigureAwait(false); - var extension = Path.GetExtension(package.targetFilename) ?? ""; - // Do plugin-specific processing - if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".7z", StringComparison.OrdinalIgnoreCase)) + if (isPlugin) { // Set last update time if we were installed before var plugin = _applicationHost.Plugins.FirstOrDefault(p => string.Equals(p.Id.ToString(), package.guid, StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index a0711a9c7..14f0f4719 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> - <package id="NLog" version="4.1.0" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> + <package id="morelinq" version="1.4.0" targetFramework="net45" /> + <package id="NLog" version="4.2.3" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> - <package id="SimpleInjector" version="3.0.5" targetFramework="net45" /> + <package id="SimpleInjector" version="3.1.2" targetFramework="net45" /> </packages> diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 8fc947e8f..de63ddd51 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Common.Net /// Gets the machine's local ip address /// </summary> /// <returns>IPAddress.</returns> - IEnumerable<string> GetLocalIpAddresses(); + IEnumerable<IPAddress> GetLocalIpAddresses(); /// <summary> /// Gets a random port number that is currently available @@ -26,6 +26,13 @@ namespace MediaBrowser.Common.Net string GetMacAddress(); /// <summary> + /// Determines whether [is in private address space] [the specified endpoint]. + /// </summary> + /// <param name="endpoint">The endpoint.</param> + /// <returns><c>true</c> if [is in private address space] [the specified endpoint]; otherwise, <c>false</c>.</returns> + bool IsInPrivateAddressSpace(string endpoint); + + /// <summary> /// Gets the network shares. /// </summary> /// <param name="path">The path.</param> diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index 7d721da6f..68853f05e 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -105,11 +105,12 @@ namespace MediaBrowser.Common.Updates /// Installs the package. /// </summary> /// <param name="package">The package.</param> + /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">package</exception> - Task InstallPackage(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken); + Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken); /// <summary> /// Uninstalls a plugin diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index e4ab29102..77a81d0c8 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -22,8 +22,14 @@ namespace MediaBrowser.Controller.Dto /// </summary> /// <param name="dto">The dto.</param> /// <param name="item">The item.</param> - /// <param name="fields">The fields.</param> - void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List<ItemFields> fields); + void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item); + + /// <summary> + /// Gets the primary image aspect ratio. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>System.Nullable<System.Double>.</returns> + double? GetPrimaryImageAspectRatio(IHasImages item); /// <summary> /// Gets the base item dto. diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 1b842a5f6..fb843d191 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -1,6 +1,8 @@ using MediaBrowser.Common; using MediaBrowser.Model.System; using System; +using System.Collections.Generic; +using System.Net; namespace MediaBrowser.Controller { @@ -63,7 +65,7 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// </summary> /// <value>The local ip address.</value> - string LocalIpAddress { get; } + List<IPAddress> LocalIpAddresses { get; } /// <summary> /// Gets the local API URL. diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index bcf4de2a2..2227df3f0 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -46,11 +46,14 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Interfaces.IO"> <HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath> </Reference> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> + </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> </Reference> @@ -65,9 +68,6 @@ <Reference Include="ServiceStack.Interfaces"> <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath> </Reference> - <Reference Include="MoreLinq"> - <HintPath>..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll</HintPath> - </Reference> </ItemGroup> <ItemGroup> <Compile Include="..\SharedVersion.cs"> diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 91da5fab2..97c5dd31b 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -29,12 +29,6 @@ namespace MediaBrowser.Controller.Net void StartServer(IEnumerable<string> urlPrefixes, string certificatePath); /// <summary> - /// Gets the local end points. - /// </summary> - /// <value>The local end points.</value> - IEnumerable<string> LocalEndPoints { get; } - - /// <summary> /// Stops this instance. /// </summary> void Stop(); diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config index a0aacbc95..8439bee10 100644 --- a/MediaBrowser.Controller/packages.config +++ b/MediaBrowser.Controller/packages.config @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" /> - <package id="morelinq" version="1.1.1" targetFramework="net45" /> + <package id="morelinq" version="1.4.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 8c45757e7..d79ef9eaf 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -43,19 +43,19 @@ namespace MediaBrowser.Dlna.Main private readonly List<string> _registeredServerIds = new List<string>(); private bool _dlnaServerStarted; - public DlnaEntryPoint(IServerConfigurationManager config, - ILogManager logManager, - IServerApplicationHost appHost, - INetworkManager network, - ISessionManager sessionManager, - IHttpClient httpClient, - ILibraryManager libraryManager, - IUserManager userManager, - IDlnaManager dlnaManager, - IImageProcessor imageProcessor, - IUserDataManager userDataManager, - ILocalizationManager localization, - IMediaSourceManager mediaSourceManager, + public DlnaEntryPoint(IServerConfigurationManager config, + ILogManager logManager, + IServerApplicationHost appHost, + INetworkManager network, + ISessionManager sessionManager, + IHttpClient httpClient, + ILibraryManager libraryManager, + IUserManager userManager, + IDlnaManager dlnaManager, + IImageProcessor imageProcessor, + IUserDataManager userDataManager, + ILocalizationManager localization, + IMediaSourceManager mediaSourceManager, ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery) { _config = config; @@ -148,13 +148,20 @@ namespace MediaBrowser.Dlna.Main private void RegisterServerEndpoints() { - foreach (var address in _network.GetLocalIpAddresses()) + foreach (var address in _appHost.LocalIpAddresses) { - var guid = address.GetMD5(); + //if (IPAddress.IsLoopback(address)) + //{ + // // Should we allow this? + // continue; + //} + + var addressString = address.ToString(); + var guid = addressString.GetMD5(); var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml"; - var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorURI); + var uri = new Uri(_appHost.GetLocalApiUrl(addressString) + descriptorURI); var services = new List<string> { @@ -165,8 +172,8 @@ namespace MediaBrowser.Dlna.Main "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", "uuid:" + guid.ToString("N") }; - - _ssdpHandler.RegisterNotification(guid, uri, IPAddress.Parse(address), services); + + _ssdpHandler.RegisterNotification(guid, uri, address, services); _registeredServerIds.Add(guid.ToString("N")); } diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index b8ac60ef6..2d672ee87 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -42,7 +42,10 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> + </Reference> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index 18a595d5b..37ce0ce67 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -37,7 +37,6 @@ namespace MediaBrowser.Dlna.Profiles MusicSyncBitrate = 128000; EnableAlbumArtInDidl = false; - EnableDlnaProtocol = true; TranscodingProfiles = new[] { diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 431807aed..5a3e7b7c0 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "Xbox 360"; // Required according to above - ModelName = "Windows Media Connect"; + ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; @@ -25,13 +25,11 @@ namespace MediaBrowser.Dlna.Profiles ManufacturerUrl = "http://www.microsoft.com"; XDlnaDoc = "DMS-1.50"; ModelDescription = "Emby : UPnP Media Server"; - ModelNumber = "001"; TimelineOffsetSeconds = 40; RequiresPlainFolders = true; RequiresPlainVideoItems = true; EnableMSMediaReceiverRegistrar = true; - EnableDlnaProtocol = false; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs index b78b5df0c..e82f9b58c 100644 --- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs +++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Dlna.Profiles new DirectPlayProfile { Container = "mp4,mov,mkv", - VideoCodec = "h264,mpeg4", + VideoCodec = "h264,mpeg4,mpeg2video", AudioCodec = "aac,ac3", Type = DlnaProfileType.Video }, diff --git a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml index ca98f950b..29f7f7c75 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index 58c37a423..6559e8971 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -28,7 +28,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp3,wma" type="Audio" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml index 86be2d18b..da033f86e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml @@ -33,7 +33,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml index c553f9a06..d916f9984 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>true</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mpeg" audioCodec="mp2" videoCodec="mpeg2video" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml index bb14ea309..702f4ee6c 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml @@ -35,7 +35,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml index 5d30d141e..4a06c3122 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index 62da6dbf4..e2b42a77e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="ts" audioCodec="aac,ac3,mp3" videoCodec="h264" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml index 9d83164d8..3d37a9c9e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml @@ -32,7 +32,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml index b66ebfe9e..4249fd6ca 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml index 329c97fbd..b468391ef 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml @@ -35,7 +35,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:pv" value="http://www.pv.com/pvns/" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml index a53e731cf..ae9fc4de4 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml @@ -28,7 +28,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp4,mov" audioCodec="aac" videoCodec="h264,mpeg4" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index 642395ac8..2355fe7a4 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:sec" value="http://www.sec.co.kr/" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml index afcce2b07..f273fcae0 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml index 8dc221251..6132e19dc 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml index 69dae2806..fbd67262a 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml index 2292d634d..3f61b930b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml index 095fcb28e..0774d53f9 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml index c700c4bfb..c052cf85e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml index 96fa2861d..91cfc0db2 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes> <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" /> </XmlRootAttributes> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index ce34dd5f2..b0825c8f6 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi" audioCodec="mp2,mp3" videoCodec="mpeg4" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml index 939c8a813..670c8a6df 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml @@ -36,7 +36,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi" audioCodec="mp2,mp3" videoCodec="mpeg4" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml index 82b806f1a..03d39350f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index df2a746d0..10b642bba 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -35,7 +35,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index bfe1fceea..0724c2a83 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -11,9 +11,9 @@ <FriendlyName>${HostName}: 1</FriendlyName> <Manufacturer>Microsoft Corporation</Manufacturer> <ManufacturerUrl>http://www.microsoft.com</ManufacturerUrl> - <ModelName>Windows Media Connect</ModelName> + <ModelName>Windows Media Player Sharing</ModelName> <ModelDescription>Emby : UPnP Media Server</ModelDescription> - <ModelNumber>001</ModelNumber> + <ModelNumber>12.0</ModelNumber> <ModelUrl>http://go.microsoft.com/fwlink/?LinkId=105926</ModelUrl> <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit> @@ -35,7 +35,6 @@ <RequiresPlainFolders>true</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>true</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>false</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index bd315ac66..e4344f6ab 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -35,13 +35,12 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="ts" audioCodec="ac3" videoCodec="h264" type="Video" /> <DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" /> <DirectPlayProfile container="avi" audioCodec="aac" videoCodec="h264" type="Video" /> - <DirectPlayProfile container="mp4,mov,mkv" audioCodec="aac,ac3" videoCodec="h264,mpeg4" type="Video" /> + <DirectPlayProfile container="mp4,mov,mkv" audioCodec="aac,ac3" videoCodec="h264,mpeg4,mpeg2video" type="Video" /> <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro" videoCodec="wmv2,wmv3,vc1" type="Video" /> <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" /> <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" /> diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml index a282af655..8812118ea 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml @@ -34,7 +34,6 @@ <RequiresPlainFolders>false</RequiresPlainFolders> <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> - <EnableDlnaProtocol>true</EnableDlnaProtocol> <XmlRootAttributes /> <DirectPlayProfiles> <DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" /> diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index 649612e1e..386370596 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -54,14 +54,11 @@ namespace MediaBrowser.Dlna.Server var attributes = _profile.XmlRootAttributes.ToList(); - if (_profile.EnableDlnaProtocol) + attributes.Insert(0, new XmlAttribute { - attributes.Insert(0, new XmlAttribute - { - Name = "xmlns:dlna", - Value = "urn:schemas-dlna-org:device-1-0" - }); - } + Name = "xmlns:dlna", + Value = "urn:schemas-dlna-org:device-1-0" + }); attributes.Insert(0, new XmlAttribute { Name = "xmlns", @@ -92,10 +89,7 @@ namespace MediaBrowser.Dlna.Server builder.Append("<device>"); AppendDeviceProperties(builder); - if (_profile.EnableDlnaProtocol) - { - AppendIconList(builder); - } + AppendIconList(builder); AppendServiceList(builder); builder.Append("</device>"); } @@ -104,13 +98,10 @@ namespace MediaBrowser.Dlna.Server { builder.Append("<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>"); - if (_profile.EnableDlnaProtocol) - { - builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>"); + builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>"); - builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">M-DMS-1.50</dlna:X_DLNADOC>"); - builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + "</dlna:X_DLNADOC>"); - } + builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">M-DMS-1.50</dlna:X_DLNADOC>"); + builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + "</dlna:X_DLNADOC>"); builder.Append("<friendlyName>" + SecurityElement.Escape(GetFriendlyName()) + "</friendlyName>"); builder.Append("<manufacturer>" + SecurityElement.Escape(_profile.Manufacturer ?? string.Empty) + "</manufacturer>"); diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index c9b983bae..ed3698e43 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -11,6 +11,8 @@ using System.Net.NetworkInformation; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MoreLinq; namespace MediaBrowser.Dlna.Ssdp { @@ -26,50 +28,39 @@ namespace MediaBrowser.Dlna.Ssdp public event EventHandler<SsdpMessageEventArgs> DeviceDiscovered; public event EventHandler<SsdpMessageEventArgs> DeviceLeft; + private readonly INetworkManager _networkManager; - public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, IServerApplicationHost appHost) + public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, IServerApplicationHost appHost, INetworkManager networkManager) { _tokenSource = new CancellationTokenSource(); _logger = logger; _config = config; _appHost = appHost; + _networkManager = networkManager; } + private List<IPAddress> GetLocalIpAddresses() + { + return _networkManager.GetLocalIpAddresses().ToList(); + } + public void Start(SsdpHandler ssdpHandler) { _ssdpHandler = ssdpHandler; _ssdpHandler.MessageReceived += _ssdpHandler_MessageReceived; - foreach (var network in GetNetworkInterfaces()) - { - _logger.Debug("Found interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); - - if (!network.SupportsMulticast || OperationalStatus.Up != network.OperationalStatus || !network.GetIPProperties().MulticastAddresses.Any()) - continue; - - var properties = network.GetIPProperties(); - var ipV4 = properties.GetIPv4Properties(); - if (null == ipV4) - continue; - - var localIps = properties.UnicastAddresses - .Where(i => i.Address.AddressFamily == AddressFamily.InterNetwork) - .Select(i => i.Address) - .ToList(); - - foreach (var localIp in localIps) - { - try - { - CreateListener(localIp); - } - catch (Exception e) - { - _logger.ErrorException("Failed to Initilize Socket", e); - } - } - } + foreach (var localIp in GetLocalIpAddresses()) + { + try + { + CreateListener(localIp); + } + catch (Exception e) + { + _logger.ErrorException("Failed to Initilize Socket", e); + } + } } void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e) @@ -89,8 +80,11 @@ namespace MediaBrowser.Dlna.Ssdp { if (e.LocalEndPoint == null) { - var ip = _appHost.LocalIpAddress; - e.LocalEndPoint = new IPEndPoint(IPAddress.Parse(ip), 0); + var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i)); + if (ip != null) + { + e.LocalEndPoint = new IPEndPoint(ip, 0); + } } if (e.LocalEndPoint != null) @@ -107,29 +101,17 @@ namespace MediaBrowser.Dlna.Ssdp } } - private IEnumerable<NetworkInterface> GetNetworkInterfaces() - { - try - { - return NetworkInterface.GetAllNetworkInterfaces(); - } - catch (Exception ex) - { - _logger.ErrorException("Error in GetAllNetworkInterfaces", ex); - return new List<NetworkInterface>(); - } - } private void CreateListener(IPAddress localIp) { Task.Factory.StartNew(async (o) => { try { - var endPoint = new IPEndPoint(localIp, 1900); + _logger.Info("Creating SSDP listener on {0}", localIp); - var socket = GetMulticastSocket(localIp, endPoint); + var endPoint = new IPEndPoint(localIp, 1900); - _logger.Info("Creating SSDP listener on {0}", localIp); + var socket = GetMulticastSocket(localIp, endPoint); var receiveBuffer = new byte[64000]; diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 5dd05fd64..32c369a8f 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -15,6 +15,7 @@ using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Win32; namespace MediaBrowser.Dlna.Ssdp { @@ -112,7 +113,9 @@ namespace MediaBrowser.Dlna.Ssdp { get { - return _devices.Values.SelectMany(i => i).ToList(); + var devices = _devices.Values.ToList(); + + return devices.SelectMany(i => i).ToList(); } } @@ -121,6 +124,15 @@ namespace MediaBrowser.Dlna.Ssdp RestartSocketListener(); ReloadAliveNotifier(); + SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + } + + void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) + { + if (e.Mode == PowerModes.Resume) + { + NotifyAll(); + } } public void SendSearchMessage(EndPoint localIp) @@ -433,6 +445,7 @@ namespace MediaBrowser.Dlna.Ssdp public void Dispose() { _config.NamedConfigurationUpdated -= _config_ConfigurationUpdated; + SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; _isDisposed = true; while (_messageQueue.Count != 0) diff --git a/MediaBrowser.Dlna/packages.config b/MediaBrowser.Dlna/packages.config index fad6af08e..83890e697 100644 --- a/MediaBrowser.Dlna/packages.config +++ b/MediaBrowser.Dlna/packages.config @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> + <package id="morelinq" version="1.4.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index a74fe7e98..9a641776a 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -33,7 +33,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> diff --git a/MediaBrowser.LocalMetadata/packages.config b/MediaBrowser.LocalMetadata/packages.config index fad6af08e..28556744d 100644 --- a/MediaBrowser.LocalMetadata/packages.config +++ b/MediaBrowser.LocalMetadata/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index df5ab4651..69f6186c7 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -41,7 +41,7 @@ </Reference> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="DvdLib"> <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath> diff --git a/MediaBrowser.MediaEncoding/packages.config b/MediaBrowser.MediaEncoding/packages.config index e8a1767e3..d6a4fc90f 100644 --- a/MediaBrowser.MediaEncoding/packages.config +++ b/MediaBrowser.MediaEncoding/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 5554c0623..778db8fb5 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -78,7 +78,6 @@ namespace MediaBrowser.Model.Dlna public bool EnableMSMediaReceiverRegistrar { get; set; } public bool IgnoreTranscodeByteRangeRequests { get; set; } - public bool EnableDlnaProtocol { get; set; } public XmlAttribute[] XmlRootAttributes { get; set; } diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index d51c0325d..3a1d45cc4 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -144,5 +144,11 @@ namespace MediaBrowser.Model.Search /// </summary> /// <value>The name of the channel.</value> public string ChannelName { get; set; } + + /// <summary> + /// Gets or sets the primary image aspect ratio. + /// </summary> + /// <value>The primary image aspect ratio.</value> + public double? PrimaryImageAspectRatio { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index e8eece299..4542c9c42 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -133,6 +133,7 @@ namespace MediaBrowser.Providers.Manager source = memoryStream; var currentImage = GetCurrentImage(item, type, index); + var savedPaths = new List<string>(); using (source) { @@ -146,17 +147,17 @@ namespace MediaBrowser.Providers.Manager { retryPath = retryPaths[currentPathIndex]; } - await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); - + var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); + savedPaths.Add(savedPath); currentPathIndex++; } } // Set the path into the item - SetImagePath(item, type, imageIndex, paths[0]); + SetImagePath(item, type, imageIndex, savedPaths[0]); // Delete the current path - if (currentImage != null && currentImage.IsLocalFile && !paths.Contains(currentImage.Path, StringComparer.OrdinalIgnoreCase)) + if (currentImage != null && currentImage.IsLocalFile && !savedPaths.Contains(currentImage.Path, StringComparer.OrdinalIgnoreCase)) { var currentPath = currentImage.Path; @@ -184,11 +185,12 @@ namespace MediaBrowser.Providers.Manager } } - private async Task SaveImageToLocation(Stream source, string path, string retryPath, CancellationToken cancellationToken) + private async Task<string> SaveImageToLocation(Stream source, string path, string retryPath, CancellationToken cancellationToken) { try { await SaveImageToLocation(source, path, cancellationToken).ConfigureAwait(false); + return path; } catch (UnauthorizedAccessException) { @@ -207,6 +209,7 @@ namespace MediaBrowser.Providers.Manager source.Position = 0; await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false); + return retryPath; } /// <summary> diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 580e9c4ac..090509ed3 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -795,22 +795,6 @@ namespace MediaBrowser.Providers.Manager } } - // This is a workaround duplicate check for movies, where intersecting provider ids are not always available - if (typeof(TItemType) == typeof(Movie) || typeof(TItemType) == typeof(Series)) - { - var titleYearString = string.Format("{0} ({1})", result.Name, result.ProductionYear); - - if (foundTitleYearStrings.Contains(titleYearString)) - { - bFound = true; - } - else - { - foundTitleYearStrings.Add(titleYearString); - } - - } - if (!bFound && resultList.Count < maxResults) { resultList.Add(result); diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 731d30d84..8f6ef1d8f 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -50,15 +50,14 @@ </Reference> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="DvdLib, Version=1.0.5167.21152, Culture=neutral, PublicKeyToken=7a2f3f5ec8d93575, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath> </Reference> - <Reference Include="MoreLinq, Version=1.1.18418.0, Culture=neutral, PublicKeyToken=384d532d7e88985d, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll</HintPath> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index 3c6485fcc..e72378d5d 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -68,7 +68,14 @@ namespace MediaBrowser.Providers.Music var list = new List<RemoteImageInfo>(); - var artistMusicBrainzId = album.MusicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist); + var musicArtist = album.MusicArtist; + + if (musicArtist == null) + { + return list; + } + + var artistMusicBrainzId = musicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist); if (!string.IsNullOrEmpty(artistMusicBrainzId)) { diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs index 3f25f0f93..a6f346d48 100644 --- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs @@ -51,25 +51,15 @@ namespace MediaBrowser.Providers.Omdb return Task.FromResult<IEnumerable<RemoteImageInfo>>(list); } - public async Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) + public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) { - var response = await _httpClient.GetResponse(new HttpRequestOptions + return _httpClient.GetResponse(new HttpRequestOptions { CancellationToken = cancellationToken, Url = url, ResourcePool = OmdbProvider.ResourcePool - }).ConfigureAwait(false); - - if (response.ContentLength == 11059) - { - throw new HttpException("File not found") - { - StatusCode = HttpStatusCode.NotFound - }; - } - - return response; + }); } public string Name diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index efcc76e69..30bd4bed7 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -57,7 +57,12 @@ namespace MediaBrowser.Providers.Omdb return GetSearchResults(searchInfo, "movie", cancellationToken); } - public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + { + return GetSearchResultsInternal(searchInfo, type, true, cancellationToken); + } + + private async Task<IEnumerable<RemoteSearchResult>> GetSearchResultsInternal(ItemLookupInfo searchInfo, string type, bool enableMultipleResults, CancellationToken cancellationToken) { bool isSearch = false; @@ -86,7 +91,14 @@ namespace MediaBrowser.Providers.Omdb } // &s means search and returns a list of results as opposed to t - url += "&s=" + WebUtility.UrlEncode(name); + if (enableMultipleResults) + { + url += "&s=" + WebUtility.UrlEncode(name); + } + else + { + url += "&t=" + WebUtility.UrlEncode(name); + } url += "&type=" + type; isSearch = true; } @@ -239,14 +251,14 @@ namespace MediaBrowser.Providers.Omdb private async Task<string> GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) { - var results = await GetSearchResults(info, "movie", cancellationToken).ConfigureAwait(false); + var results = await GetSearchResultsInternal(info, "movie", false, cancellationToken).ConfigureAwait(false); var first = results.FirstOrDefault(); return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } private async Task<string> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) { - var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false); + var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false); var first = results.FirstOrDefault(); return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } diff --git a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs index 74296db8a..90b281e8a 100644 --- a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs +++ b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.Subtitles { @@ -30,15 +31,6 @@ namespace MediaBrowser.Providers.Subtitles private readonly IServerConfigurationManager _config; private readonly IEncryptionManager _encryption; - private Timer _dailyTimer; - - // This is limited to 200 per day - private int _dailyDownloadCount; - - // It's 200 but this will be in-exact so buffer a little - // And the user may restart the server - private const int MaxDownloadsPerDay = 150; - private readonly IJsonSerializer _json; public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption, IJsonSerializer json) @@ -51,9 +43,6 @@ namespace MediaBrowser.Providers.Subtitles _config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating; - // Reset the count every 24 hours - _dailyTimer = new Timer(state => _dailyDownloadCount = 0, null, TimeSpan.FromHours(24), TimeSpan.FromHours(24)); - Utilities.HttpClient = httpClient; OpenSubtitles.SetUserAgent("mediabrowser.tv"); } @@ -123,6 +112,7 @@ namespace MediaBrowser.Providers.Subtitles return GetSubtitlesInternal(id, GetOptions(), cancellationToken); } + private DateTime _lastRateLimitException; private async Task<SubtitleResponse> GetSubtitlesInternal(string id, SubtitleOptions options, CancellationToken cancellationToken) @@ -132,12 +122,6 @@ namespace MediaBrowser.Providers.Subtitles throw new ArgumentNullException("id"); } - if (_dailyDownloadCount >= MaxDownloadsPerDay && - !options.IsOpenSubtitleVipAccount) - { - throw new InvalidOperationException("Open Subtitle's daily download limit has been exceeded. Please try again tomorrow."); - } - var idParts = id.Split(new[] { '-' }, 3); var format = idParts[0]; @@ -148,8 +132,19 @@ namespace MediaBrowser.Providers.Subtitles await Login(cancellationToken).ConfigureAwait(false); + if ((DateTime.UtcNow - _lastRateLimitException).TotalHours < 1) + { + throw new ApplicationException("OpenSubtitles rate limit reached"); + } + var resultDownLoad = await OpenSubtitles.DownloadSubtitlesAsync(downloadsList, cancellationToken).ConfigureAwait(false); + if ((resultDownLoad.Status ?? string.Empty).IndexOf("407", StringComparison.OrdinalIgnoreCase) != -1) + { + _lastRateLimitException = DateTime.UtcNow; + throw new ApplicationException("OpenSubtitles rate limit reached"); + } + if (!(resultDownLoad is MethodResponseSubtitleDownload)) { throw new ApplicationException("Invalid response type"); @@ -157,13 +152,15 @@ namespace MediaBrowser.Providers.Subtitles var results = ((MethodResponseSubtitleDownload)resultDownLoad).Results; + _lastRateLimitException = DateTime.MinValue; + if (results.Count == 0) { var msg = string.Format("Subtitle with Id {0} was not found. Name: {1}. Status: {2}. Message: {3}", ossId, resultDownLoad.Name ?? string.Empty, - resultDownLoad.Message ?? string.Empty, - resultDownLoad.Status ?? string.Empty); + resultDownLoad.Status ?? string.Empty, + resultDownLoad.Message ?? string.Empty); throw new ResourceNotFoundException(msg); } @@ -339,12 +336,6 @@ namespace MediaBrowser.Providers.Subtitles public void Dispose() { _config.NamedConfigurationUpdating -= _config_NamedConfigurationUpdating; - - if (_dailyTimer != null) - { - _dailyTimer.Dispose(); - _dailyTimer = null; - } } } } diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 6b902ed8a..d03920742 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -112,6 +112,8 @@ namespace MediaBrowser.Providers.TV if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) && (searchInfo.IndexNumber.HasValue || searchInfo.PremiereDate.HasValue)) { + await TvdbSeriesProvider.Current.EnsureSeriesInfo(searchInfo.SeriesProviderIds, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, searchInfo.SeriesProviderIds); var searchNumbers = new EpisodeNumbers(); diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 7250dbee4..9452438cb 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -222,6 +222,11 @@ namespace MediaBrowser.Providers.TV seriesId = await GetSeriesByRemoteId(seriesId, idType, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); } + if (string.IsNullOrWhiteSpace(seriesId)) + { + throw new ArgumentNullException("seriesId"); + } + var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); using (var zipStream = await _httpClient.Get(new HttpRequestOptions @@ -324,38 +329,48 @@ namespace MediaBrowser.Providers.TV return false; } + private SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1,1); internal async Task<string> EnsureSeriesInfo(Dictionary<string, string> seriesProviderIds, string preferredMetadataLanguage, CancellationToken cancellationToken) { - string seriesId; - if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) - { - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + await _ensureSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - // Only download if not already there - // The post-scan task will take care of updates so we don't need to re-download here - if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + try + { + string seriesId; + if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) { - await DownloadSeriesZip(seriesId, MetadataProviders.Tvdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); - } + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); - return seriesDataPath; - } + // Only download if not already there + // The post-scan task will take care of updates so we don't need to re-download here + if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + { + await DownloadSeriesZip(seriesId, MetadataProviders.Tvdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + } - if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) - { - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + return seriesDataPath; + } - // Only download if not already there - // The post-scan task will take care of updates so we don't need to re-download here - if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) { - await DownloadSeriesZip(seriesId, MetadataProviders.Imdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + + // Only download if not already there + // The post-scan task will take care of updates so we don't need to re-download here + if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + { + await DownloadSeriesZip(seriesId, MetadataProviders.Imdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + } + + return seriesDataPath; } - return seriesDataPath; + return null; + } + finally + { + _ensureSemaphore.Release(); } - - return null; } private bool IsCacheValid(string seriesDataPath, string preferredMetadataLanguage) diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config index 9ff08e4f4..08f8ef3b0 100644 --- a/MediaBrowser.Providers/packages.config +++ b/MediaBrowser.Providers/packages.config @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" /> - <package id="morelinq" version="1.1.1" targetFramework="net45" /> + <package id="morelinq" version="1.4.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> <package id="taglib" version="2.1.0.0" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index bb7f818ba..b0071828e 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -310,7 +310,7 @@ namespace MediaBrowser.Server.Implementations.Dto { try { - AttachPrimaryImageAspectRatio(dto, item, fields); + AttachPrimaryImageAspectRatio(dto, item); } catch (Exception ex) { @@ -1742,15 +1742,19 @@ namespace MediaBrowser.Server.Implementations.Dto /// </summary> /// <param name="dto">The dto.</param> /// <param name="item">The item.</param> - /// <param name="fields">The fields.</param> /// <returns>Task.</returns> - public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List<ItemFields> fields) + public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item) + { + dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); + } + + public double? GetPrimaryImageAspectRatio(IHasImages item) { var imageInfo = item.GetImageInfo(ImageType.Primary, 0); if (imageInfo == null || !imageInfo.IsLocalFile) { - return; + return null; } ImageSize size; @@ -1762,7 +1766,7 @@ namespace MediaBrowser.Server.Implementations.Dto catch (Exception ex) { //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); - return; + return null; } var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList(); @@ -1781,8 +1785,9 @@ namespace MediaBrowser.Server.Implementations.Dto if (size.Width > 0 && size.Height > 0) { - dto.PrimaryImageAspectRatio = size.Width / size.Height; + return size.Width / size.Height; } + return null; } } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index ef226a934..26392f5a9 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -74,42 +74,52 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (!string.IsNullOrEmpty(seriesName)) { - var season = episodeInfo.SeasonNumber; - - result.ExtractedSeasonNumber = season; - - if (season.HasValue) - { - // Passing in true will include a few extra regex's - var episode = episodeInfo.EpisodeNumber; - - result.ExtractedEpisodeNumber = episode; - - if (episode.HasValue) - { - _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode); - - var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; - - result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; - - await OrganizeEpisode(path, seriesName, season.Value, episode.Value, endingEpisodeNumber, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false); - } - else - { - var msg = string.Format("Unable to determine episode number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } - } - else - { - var msg = string.Format("Unable to determine season number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } + var seasonNumber = episodeInfo.SeasonNumber; + + result.ExtractedSeasonNumber = seasonNumber; + + // Passing in true will include a few extra regex's + var episodeNumber = episodeInfo.EpisodeNumber; + + result.ExtractedEpisodeNumber = episodeNumber; + + var premiereDate = episodeInfo.IsByDate ? + new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : + (DateTime?)null; + + if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) + { + if (episodeInfo.IsByDate) + { + _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); + } + else + { + _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); + } + + var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; + + result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + + await OrganizeEpisode(path, + seriesName, + seasonNumber, + episodeNumber, + endingEpisodeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken).ConfigureAwait(false); + } + else + { + var msg = string.Format("Unable to determine episode number from {0}", path); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + } } else { @@ -141,14 +151,32 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); - await OrganizeEpisode(result.OriginalPath, series, request.SeasonNumber, request.EpisodeNumber, request.EndingEpisodeNumber, options, true, result, cancellationToken).ConfigureAwait(false); + await OrganizeEpisode(result.OriginalPath, + series, + request.SeasonNumber, + request.EpisodeNumber, + request.EndingEpisodeNumber, + null, + options, + true, + result, + cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return result; } - private Task OrganizeEpisode(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private Task OrganizeEpisode(string sourcePath, + string seriesName, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { var series = GetMatchingSeries(seriesName, result); @@ -161,15 +189,33 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - return OrganizeEpisode(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, overwriteExisting, result, cancellationToken); + return OrganizeEpisode(sourcePath, + series, + seasonNumber, + episodeNumber, + endingEpiosdeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken); } - private async Task OrganizeEpisode(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private async Task OrganizeEpisode(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -278,8 +324,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private List<string> GetOtherDuplicatePaths(string targetPath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber) + private List<string> GetOtherDuplicatePaths(string targetPath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber) { + // TODO: Support date-naming? + if (!seasonNumber.HasValue || episodeNumber.HasValue) + { + return new List<string> (); + } + var episodePaths = series.GetRecursiveChildren() .OfType<Episode>() .Where(i => @@ -408,7 +464,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// <param name="endingEpisodeNumber">The ending episode number.</param> /// <param name="options">The options.</param> /// <returns>System.String.</returns> - private async Task<string> GetNewPath(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, TvFileOrganizationOptions options, CancellationToken cancellationToken) + private async Task<string> GetNewPath(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + CancellationToken cancellationToken) { var episodeInfo = new EpisodeInfo { @@ -417,7 +480,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization MetadataCountryCode = series.GetPreferredMetadataCountryCode(), MetadataLanguage = series.GetPreferredMetadataLanguage(), ParentIndexNumber = seasonNumber, - SeriesProviderIds = series.ProviderIds + SeriesProviderIds = series.ProviderIds, + PremiereDate = premiereDate }; var searchResults = await _providerManager.GetRemoteSearchResults<Episode, EpisodeInfo>(new RemoteSearchQuery<EpisodeInfo> @@ -427,14 +491,24 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }, cancellationToken).ConfigureAwait(false); var episode = searchResults.FirstOrDefault(); + + string episodeName = string.Empty; if (episode == null) { - _logger.Warn("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); - return null; + var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + _logger.Warn(msg); + //throw new Exception(msg); } + else + { + episodeName = episode.Name; + } + + seasonNumber = seasonNumber ?? episode.ParentIndexNumber; + episodeNumber = episodeNumber ?? episode.IndexNumber; - var newPath = GetSeasonFolderPath(series, seasonNumber, options); + var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); // MAX_PATH - trailing <NULL> charachter - drive component: 260 - 1 - 3 = 256 // Usually newPath would include the drive component, but use 256 to be sure @@ -449,7 +523,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt) maxFilenameLength -= 4; - var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options, maxFilenameLength); + var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options, maxFilenameLength); if (string.IsNullOrEmpty(episodeFileName)) { @@ -505,7 +579,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - if (episodeTitle == null) + if (string.IsNullOrEmpty(episodeTitle)) { episodeTitle = string.Empty; } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 6ade9a8f6..0283c1f7a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -19,6 +19,7 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; namespace MediaBrowser.Server.Implementations.HttpServer @@ -39,40 +40,20 @@ namespace MediaBrowser.Server.Implementations.HttpServer public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected; public event EventHandler<WebSocketConnectingEventArgs> WebSocketConnecting; - private readonly List<string> _localEndpoints = new List<string>(); - - private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim(); - public string CertificatePath { get; private set; } private readonly IServerConfigurationManager _config; - - /// <summary> - /// Gets the local end points. - /// </summary> - /// <value>The local end points.</value> - public IEnumerable<string> LocalEndPoints - { - get - { - _localEndpointLock.EnterReadLock(); - - var list = _localEndpoints.ToList(); - - _localEndpointLock.ExitReadLock(); - - return list; - } - } + private readonly INetworkManager _networkManager; public HttpListenerHost(IApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, string serviceName, - string defaultRedirectPath, params Assembly[] assembliesWithServices) + string defaultRedirectPath, INetworkManager networkManager, params Assembly[] assembliesWithServices) : base(serviceName, assembliesWithServices) { DefaultRedirectPath = defaultRedirectPath; + _networkManager = networkManager; _config = config; _logger = logManager.GetLogger("HttpServer"); @@ -175,26 +156,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer private void OnRequestReceived(string localEndPoint) { - var ignore = localEndPoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 || - - localEndPoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || - localEndPoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || - localEndPoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase); - - if (ignore) - { - return; - } - - if (_localEndpointLock.TryEnterWriteLock(100)) - { - var list = _localEndpoints.ToList(); - - list.Remove(localEndPoint); - list.Insert(0, localEndPoint); - - _localEndpointLock.ExitWriteLock(); - } } /// <summary> diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs index 0da34efc6..4ef9d5277 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs @@ -58,7 +58,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (hasOptions != null) { - hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1"; + if (!hasOptions.Options.ContainsKey("Server")) + { + hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50"; + } // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy string contentLength; diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs index 4d81ec157..cc351f6b3 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; @@ -17,18 +18,20 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// <param name="applicationHost">The application host.</param> /// <param name="logManager">The log manager.</param> /// <param name="config">The configuration.</param> + /// <param name="_networkmanager">The _networkmanager.</param> /// <param name="serverName">Name of the server.</param> /// <param name="defaultRedirectpath">The default redirectpath.</param> /// <returns>IHttpServer.</returns> public static IHttpServer CreateServer(IApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, + INetworkManager _networkmanager, string serverName, string defaultRedirectpath) { LogManager.LogFactory = new ServerLogFactory(logManager); - return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath); + return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs new file mode 100644 index 000000000..3ef48d13a --- /dev/null +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs @@ -0,0 +1,941 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; + +namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +{ + public static class MyHttpUtility + { + sealed class HttpQSCollection : NameValueCollection + { + public override string ToString() + { + int count = Count; + if (count == 0) + return ""; + StringBuilder sb = new StringBuilder(); + string[] keys = AllKeys; + for (int i = 0; i < count; i++) + { + sb.AppendFormat("{0}={1}&", keys[i], this[keys[i]]); + } + if (sb.Length > 0) + sb.Length--; + return sb.ToString(); + } + } + + // Must be sorted + static readonly long[] entities = new long[] { + (long)'A' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'A' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'A' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24, + (long)'A' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24, + (long)'A' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'A' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'B' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'C' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'C' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'D' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16, + (long)'D' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'E' << 56 | (long)'T' << 48 | (long)'H' << 40, + (long)'E' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'E' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'E' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'E' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'E' << 56 | (long)'t' << 48 | (long)'a' << 40, + (long)'E' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'G' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'I' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'I' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'I' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'I' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'I' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'K' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24, + (long)'L' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16, + (long)'M' << 56 | (long)'u' << 48, + (long)'N' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'N' << 56 | (long)'u' << 48, + (long)'O' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'O' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'O' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24, + (long)'O' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'O' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16, + (long)'O' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'O' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'P' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'P' << 56 | (long)'i' << 48, + (long)'P' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24, + (long)'P' << 56 | (long)'s' << 48 | (long)'i' << 40, + (long)'R' << 56 | (long)'h' << 48 | (long)'o' << 40, + (long)'S' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16, + (long)'S' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'T' << 56 | (long)'H' << 48 | (long)'O' << 40 | (long)'R' << 32 | (long)'N' << 24, + (long)'T' << 56 | (long)'a' << 48 | (long)'u' << 40, + (long)'T' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'U' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'U' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'U' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'U' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'U' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'X' << 56 | (long)'i' << 48, + (long)'Y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'Y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'Z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'a' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'a' << 56 | (long)'c' << 48 | (long)'u' << 40 | (long)'t' << 32 | (long)'e' << 24, + (long)'a' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'a' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'l' << 48 | (long)'e' << 40 | (long)'f' << 32 | (long)'s' << 24 | (long)'y' << 16 | (long)'m' << 8, + (long)'a' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24, + (long)'a' << 56 | (long)'m' << 48 | (long)'p' << 40, + (long)'a' << 56 | (long)'n' << 48 | (long)'d' << 40, + (long)'a' << 56 | (long)'n' << 48 | (long)'g' << 40, + (long)'a' << 56 | (long)'p' << 48 | (long)'o' << 40 | (long)'s' << 32, + (long)'a' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24, + (long)'a' << 56 | (long)'s' << 48 | (long)'y' << 40 | (long)'m' << 32 | (long)'p' << 24, + (long)'a' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'a' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'b' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'b' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'b' << 56 | (long)'r' << 48 | (long)'v' << 40 | (long)'b' << 32 | (long)'a' << 24 | (long)'r' << 16, + (long)'b' << 56 | (long)'u' << 48 | (long)'l' << 40 | (long)'l' << 32, + (long)'c' << 56 | (long)'a' << 48 | (long)'p' << 40, + (long)'c' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'c' << 56 | (long)'e' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'c' << 56 | (long)'e' << 48 | (long)'n' << 40 | (long)'t' << 32, + (long)'c' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'c' << 56 | (long)'i' << 48 | (long)'r' << 40 | (long)'c' << 32, + (long)'c' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'b' << 32 | (long)'s' << 24, + (long)'c' << 56 | (long)'o' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'c' << 56 | (long)'o' << 48 | (long)'p' << 40 | (long)'y' << 32, + (long)'c' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'r' << 24, + (long)'c' << 56 | (long)'u' << 48 | (long)'p' << 40, + (long)'c' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'n' << 16, + (long)'d' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'d' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16, + (long)'d' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'d' << 56 | (long)'e' << 48 | (long)'g' << 40, + (long)'d' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'d' << 56 | (long)'i' << 48 | (long)'a' << 40 | (long)'m' << 32 | (long)'s' << 24, + (long)'d' << 56 | (long)'i' << 48 | (long)'v' << 40 | (long)'i' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'e' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'e' << 56 | (long)'m' << 48 | (long)'p' << 40 | (long)'t' << 32 | (long)'y' << 24, + (long)'e' << 56 | (long)'m' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'e' << 56 | (long)'n' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'e' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'e' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'i' << 32 | (long)'v' << 24, + (long)'e' << 56 | (long)'t' << 48 | (long)'a' << 40, + (long)'e' << 56 | (long)'t' << 48 | (long)'h' << 40, + (long)'e' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'e' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'o' << 32, + (long)'e' << 56 | (long)'x' << 48 | (long)'i' << 40 | (long)'s' << 32 | (long)'t' << 24, + (long)'f' << 56 | (long)'n' << 48 | (long)'o' << 40 | (long)'f' << 32, + (long)'f' << 56 | (long)'o' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'l' << 24 | (long)'l' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'2' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'4' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'3' << 24 | (long)'4' << 16, + (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'l' << 24, + (long)'g' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'g' << 56 | (long)'e' << 48, + (long)'g' << 56 | (long)'t' << 48, + (long)'h' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'h' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'h' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'t' << 24 | (long)'s' << 16, + (long)'h' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'l' << 32 | (long)'i' << 24 | (long)'p' << 16, + (long)'i' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'i' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'i' << 56 | (long)'e' << 48 | (long)'x' << 40 | (long)'c' << 32 | (long)'l' << 24, + (long)'i' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'i' << 56 | (long)'m' << 48 | (long)'a' << 40 | (long)'g' << 32 | (long)'e' << 24, + (long)'i' << 56 | (long)'n' << 48 | (long)'f' << 40 | (long)'i' << 32 | (long)'n' << 24, + (long)'i' << 56 | (long)'n' << 48 | (long)'t' << 40, + (long)'i' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'i' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'e' << 32 | (long)'s' << 24 | (long)'t' << 16, + (long)'i' << 56 | (long)'s' << 48 | (long)'i' << 40 | (long)'n' << 32, + (long)'i' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'k' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24, + (long)'l' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'l' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16, + (long)'l' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'l' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'l' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'l' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'e' << 48, + (long)'l' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16, + (long)'l' << 56 | (long)'o' << 48 | (long)'w' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'t' << 16, + (long)'l' << 56 | (long)'o' << 48 | (long)'z' << 40, + (long)'l' << 56 | (long)'r' << 48 | (long)'m' << 40, + (long)'l' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16, + (long)'l' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'l' << 56 | (long)'t' << 48, + (long)'m' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'r' << 32, + (long)'m' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24, + (long)'m' << 56 | (long)'i' << 48 | (long)'c' << 40 | (long)'r' << 32 | (long)'o' << 24, + (long)'m' << 56 | (long)'i' << 48 | (long)'d' << 40 | (long)'d' << 32 | (long)'o' << 24 | (long)'t' << 16, + (long)'m' << 56 | (long)'i' << 48 | (long)'n' << 40 | (long)'u' << 32 | (long)'s' << 24, + (long)'m' << 56 | (long)'u' << 48, + (long)'n' << 56 | (long)'a' << 48 | (long)'b' << 40 | (long)'l' << 32 | (long)'a' << 24, + (long)'n' << 56 | (long)'b' << 48 | (long)'s' << 40 | (long)'p' << 32, + (long)'n' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24, + (long)'n' << 56 | (long)'e' << 48, + (long)'n' << 56 | (long)'i' << 48, + (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40, + (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'i' << 32 | (long)'n' << 24, + (long)'n' << 56 | (long)'s' << 48 | (long)'u' << 40 | (long)'b' << 32, + (long)'n' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'n' << 56 | (long)'u' << 48, + (long)'o' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'o' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'o' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'l' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'e' << 24, + (long)'o' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24, + (long)'o' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'o' << 56 | (long)'p' << 48 | (long)'l' << 40 | (long)'u' << 32 | (long)'s' << 24, + (long)'o' << 56 | (long)'r' << 48, + (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'f' << 32, + (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'m' << 32, + (long)'o' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16, + (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16, + (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24 | (long)'s' << 16, + (long)'o' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'a' << 32, + (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'t' << 32, + (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'m' << 32 | (long)'i' << 24 | (long)'l' << 16, + (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'p' << 32, + (long)'p' << 56 | (long)'h' << 48 | (long)'i' << 40, + (long)'p' << 56 | (long)'i' << 48, + (long)'p' << 56 | (long)'i' << 48 | (long)'v' << 40, + (long)'p' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'s' << 32 | (long)'m' << 24 | (long)'n' << 16, + (long)'p' << 56 | (long)'o' << 48 | (long)'u' << 40 | (long)'n' << 32 | (long)'d' << 24, + (long)'p' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24, + (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'d' << 32, + (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'p' << 32, + (long)'p' << 56 | (long)'s' << 48 | (long)'i' << 40, + (long)'q' << 56 | (long)'u' << 48 | (long)'o' << 40 | (long)'t' << 32, + (long)'r' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'r' << 56 | (long)'a' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'c' << 24, + (long)'r' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32, + (long)'r' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'r' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'r' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24, + (long)'r' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'r' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'l' << 32, + (long)'r' << 56 | (long)'e' << 48 | (long)'g' << 40, + (long)'r' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16, + (long)'r' << 56 | (long)'h' << 48 | (long)'o' << 40, + (long)'r' << 56 | (long)'l' << 48 | (long)'m' << 40, + (long)'r' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16, + (long)'r' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'s' << 56 | (long)'b' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24, + (long)'s' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16, + (long)'s' << 56 | (long)'d' << 48 | (long)'o' << 40 | (long)'t' << 32, + (long)'s' << 56 | (long)'e' << 48 | (long)'c' << 40 | (long)'t' << 32, + (long)'s' << 56 | (long)'h' << 48 | (long)'y' << 40, + (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24, + (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24 | (long)'f' << 16, + (long)'s' << 56 | (long)'i' << 48 | (long)'m' << 40, + (long)'s' << 56 | (long)'p' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24 | (long)'s' << 16, + (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40 | (long)'e' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'m' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'1' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'2' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'3' << 32, + (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'e' << 32, + (long)'s' << 56 | (long)'z' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24, + (long)'t' << 56 | (long)'a' << 48 | (long)'u' << 40, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'4' << 16, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24, + (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24 | (long)'s' << 16 | (long)'y' << 8 | (long)'m' << 0, + (long)'t' << 56 | (long)'h' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'s' << 24 | (long)'p' << 16, + (long)'t' << 56 | (long)'h' << 48 | (long)'o' << 40 | (long)'r' << 32 | (long)'n' << 24, + (long)'t' << 56 | (long)'i' << 48 | (long)'l' << 40 | (long)'d' << 32 | (long)'e' << 24, + (long)'t' << 56 | (long)'i' << 48 | (long)'m' << 40 | (long)'e' << 32 | (long)'s' << 24, + (long)'t' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24, + (long)'u' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'u' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'u' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32, + (long)'u' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24, + (long)'u' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16, + (long)'u' << 56 | (long)'m' << 48 | (long)'l' << 40, + (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'h' << 24, + (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8, + (long)'u' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'w' << 56 | (long)'e' << 48 | (long)'i' << 40 | (long)'e' << 32 | (long)'r' << 24 | (long)'p' << 16, + (long)'x' << 56 | (long)'i' << 48, + (long)'y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16, + (long)'y' << 56 | (long)'e' << 48 | (long)'n' << 40, + (long)'y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32, + (long)'z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32, + (long)'z' << 56 | (long)'w' << 48 | (long)'j' << 40, + (long)'z' << 56 | (long)'w' << 48 | (long)'n' << 40 | (long)'j' << 32 + }; + + static readonly char[] entities_values = new char[] { + '\u00C6', + '\u00C1', + '\u00C2', + '\u00C0', + '\u0391', + '\u00C5', + '\u00C3', + '\u00C4', + '\u0392', + '\u00C7', + '\u03A7', + '\u2021', + '\u0394', + '\u00D0', + '\u00C9', + '\u00CA', + '\u00C8', + '\u0395', + '\u0397', + '\u00CB', + '\u0393', + '\u00CD', + '\u00CE', + '\u00CC', + '\u0399', + '\u00CF', + '\u039A', + '\u039B', + '\u039C', + '\u00D1', + '\u039D', + '\u0152', + '\u00D3', + '\u00D4', + '\u00D2', + '\u03A9', + '\u039F', + '\u00D8', + '\u00D5', + '\u00D6', + '\u03A6', + '\u03A0', + '\u2033', + '\u03A8', + '\u03A1', + '\u0160', + '\u03A3', + '\u00DE', + '\u03A4', + '\u0398', + '\u00DA', + '\u00DB', + '\u00D9', + '\u03A5', + '\u00DC', + '\u039E', + '\u00DD', + '\u0178', + '\u0396', + '\u00E1', + '\u00E2', + '\u00B4', + '\u00E6', + '\u00E0', + '\u2135', + '\u03B1', + '\u0026', + '\u2227', + '\u2220', + '\u0027', + '\u00E5', + '\u2248', + '\u00E3', + '\u00E4', + '\u201E', + '\u03B2', + '\u00A6', + '\u2022', + '\u2229', + '\u00E7', + '\u00B8', + '\u00A2', + '\u03C7', + '\u02C6', + '\u2663', + '\u2245', + '\u00A9', + '\u21B5', + '\u222A', + '\u00A4', + '\u21D3', + '\u2020', + '\u2193', + '\u00B0', + '\u03B4', + '\u2666', + '\u00F7', + '\u00E9', + '\u00EA', + '\u00E8', + '\u2205', + '\u2003', + '\u2002', + '\u03B5', + '\u2261', + '\u03B7', + '\u00F0', + '\u00EB', + '\u20AC', + '\u2203', + '\u0192', + '\u2200', + '\u00BD', + '\u00BC', + '\u00BE', + '\u2044', + '\u03B3', + '\u2265', + '\u003E', + '\u21D4', + '\u2194', + '\u2665', + '\u2026', + '\u00ED', + '\u00EE', + '\u00A1', + '\u00EC', + '\u2111', + '\u221E', + '\u222B', + '\u03B9', + '\u00BF', + '\u2208', + '\u00EF', + '\u03BA', + '\u21D0', + '\u03BB', + '\u2329', + '\u00AB', + '\u2190', + '\u2308', + '\u201C', + '\u2264', + '\u230A', + '\u2217', + '\u25CA', + '\u200E', + '\u2039', + '\u2018', + '\u003C', + '\u00AF', + '\u2014', + '\u00B5', + '\u00B7', + '\u2212', + '\u03BC', + '\u2207', + '\u00A0', + '\u2013', + '\u2260', + '\u220B', + '\u00AC', + '\u2209', + '\u2284', + '\u00F1', + '\u03BD', + '\u00F3', + '\u00F4', + '\u0153', + '\u00F2', + '\u203E', + '\u03C9', + '\u03BF', + '\u2295', + '\u2228', + '\u00AA', + '\u00BA', + '\u00F8', + '\u00F5', + '\u2297', + '\u00F6', + '\u00B6', + '\u2202', + '\u2030', + '\u22A5', + '\u03C6', + '\u03C0', + '\u03D6', + '\u00B1', + '\u00A3', + '\u2032', + '\u220F', + '\u221D', + '\u03C8', + '\u0022', + '\u21D2', + '\u221A', + '\u232A', + '\u00BB', + '\u2192', + '\u2309', + '\u201D', + '\u211C', + '\u00AE', + '\u230B', + '\u03C1', + '\u200F', + '\u203A', + '\u2019', + '\u201A', + '\u0161', + '\u22C5', + '\u00A7', + '\u00AD', + '\u03C3', + '\u03C2', + '\u223C', + '\u2660', + '\u2282', + '\u2286', + '\u2211', + '\u2283', + '\u00B9', + '\u00B2', + '\u00B3', + '\u2287', + '\u00DF', + '\u03C4', + '\u2234', + '\u03B8', + '\u03D1', + '\u2009', + '\u00FE', + '\u02DC', + '\u00D7', + '\u2122', + '\u21D1', + '\u00FA', + '\u2191', + '\u00FB', + '\u00F9', + '\u00A8', + '\u03D2', + '\u03C5', + '\u00FC', + '\u2118', + '\u03BE', + '\u00FD', + '\u00A5', + '\u00FF', + '\u03B6', + '\u200D', + '\u200C' + }; + + #region Methods + + static void WriteCharBytes(IList buf, char ch, Encoding e) + { + if (ch > 255) + { + foreach (byte b in e.GetBytes(new char[] { ch })) + buf.Add(b); + } + else + buf.Add((byte)ch); + } + + public static string UrlDecode(string s, Encoding e) + { + if (null == s) + return null; + + if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1) + return s; + + if (e == null) + e = Encoding.UTF8; + + long len = s.Length; + var bytes = new List<byte>(); + int xchar; + char ch; + + for (int i = 0; i < len; i++) + { + ch = s[i]; + if (ch == '%' && i + 2 < len && s[i + 1] != '%') + { + if (s[i + 1] == 'u' && i + 5 < len) + { + // unicode hex sequence + xchar = GetChar(s, i + 2, 4); + if (xchar != -1) + { + WriteCharBytes(bytes, (char)xchar, e); + i += 5; + } + else + WriteCharBytes(bytes, '%', e); + } + else if ((xchar = GetChar(s, i + 1, 2)) != -1) + { + WriteCharBytes(bytes, (char)xchar, e); + i += 2; + } + else + { + WriteCharBytes(bytes, '%', e); + } + continue; + } + + if (ch == '+') + WriteCharBytes(bytes, ' ', e); + else + WriteCharBytes(bytes, ch, e); + } + + byte[] buf = bytes.ToArray(); + bytes = null; + return e.GetString(buf); + + } + + static int GetInt(byte b) + { + char c = (char)b; + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -1; + } + + static int GetChar(string str, int offset, int length) + { + int val = 0; + int end = length + offset; + for (int i = offset; i < end; i++) + { + char c = str[i]; + if (c > 127) + return -1; + + int current = GetInt((byte)c); + if (current == -1) + return -1; + val = (val << 4) + current; + } + + return val; + } + + static bool TryConvertKeyToEntity(string key, out char value) + { + var token = CalculateKeyValue(key); + if (token == 0) + { + value = '\0'; + return false; + } + + var idx = Array.BinarySearch(entities, token); + if (idx < 0) + { + value = '\0'; + return false; + } + + value = entities_values[idx]; + return true; + } + + static long CalculateKeyValue(string s) + { + if (s.Length > 8) + return 0; + + long key = 0; + for (int i = 0; i < s.Length; ++i) + { + long ch = s[i]; + if (ch > 'z' || ch < '0') + return 0; + + key |= ch << ((7 - i) * 8); + } + + return key; + } + + /// <summary> + /// Decodes an HTML-encoded string and returns the decoded string. + /// </summary> + /// <param name="s">The HTML string to decode. </param> + /// <returns>The decoded text.</returns> + public static string HtmlDecode(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + if (s.IndexOf('&') == -1) + return s; + + StringBuilder entity = new StringBuilder(); + StringBuilder output = new StringBuilder(); + int len = s.Length; + // 0 -> nothing, + // 1 -> right after '&' + // 2 -> between '&' and ';' but no '#' + // 3 -> '#' found after '&' and getting numbers + int state = 0; + int number = 0; + int digit_start = 0; + bool hex_number = false; + + for (int i = 0; i < len; i++) + { + char c = s[i]; + if (state == 0) + { + if (c == '&') + { + entity.Append(c); + state = 1; + } + else + { + output.Append(c); + } + continue; + } + + if (c == '&') + { + state = 1; + if (digit_start > 0) + { + entity.Append(s, digit_start, i - digit_start); + digit_start = 0; + } + + output.Append(entity.ToString()); + entity.Length = 0; + entity.Append('&'); + continue; + } + + switch (state) + { + case 1: + if (c == ';') + { + state = 0; + output.Append(entity.ToString()); + output.Append(c); + entity.Length = 0; + break; + } + + number = 0; + hex_number = false; + if (c != '#') + { + state = 2; + } + else + { + state = 3; + } + entity.Append(c); + + break; + case 2: + entity.Append(c); + if (c == ';') + { + string key = entity.ToString(); + state = 0; + entity.Length = 0; + + if (key.Length > 1) + { + var skey = key.Substring(1, key.Length - 2); + if (TryConvertKeyToEntity(skey, out c)) + { + output.Append(c); + break; + } + } + + output.Append(key); + } + + break; + case 3: + if (c == ';') + { + if (number < 0x10000) + { + output.Append((char)number); + } + else + { + output.Append((char)(0xd800 + ((number - 0x10000) >> 10))); + output.Append((char)(0xdc00 + ((number - 0x10000) & 0x3ff))); + } + state = 0; + entity.Length = 0; + digit_start = 0; + break; + } + + if (c == 'x' || c == 'X' && !hex_number) + { + digit_start = i; + hex_number = true; + break; + } + + if (Char.IsDigit(c)) + { + if (digit_start == 0) + digit_start = i; + + number = number * (hex_number ? 16 : 10) + ((int)c - '0'); + break; + } + + if (hex_number) + { + if (c >= 'a' && c <= 'f') + { + number = number * 16 + 10 + ((int)c - 'a'); + break; + } + if (c >= 'A' && c <= 'F') + { + number = number * 16 + 10 + ((int)c - 'A'); + break; + } + } + + state = 2; + if (digit_start > 0) + { + entity.Append(s, digit_start, i - digit_start); + digit_start = 0; + } + + entity.Append(c); + break; + } + } + + if (entity.Length > 0) + { + output.Append(entity); + } + else if (digit_start > 0) + { + output.Append(s, digit_start, s.Length - digit_start); + } + return output.ToString(); + } + + public static NameValueCollection ParseQueryString(string query) + { + return ParseQueryString(query, Encoding.UTF8); + } + + public static NameValueCollection ParseQueryString(string query, Encoding encoding) + { + if (query == null) + throw new ArgumentNullException("query"); + if (encoding == null) + throw new ArgumentNullException("encoding"); + if (query.Length == 0 || (query.Length == 1 && query[0] == '?')) + return new NameValueCollection(); + if (query[0] == '?') + query = query.Substring(1); + + NameValueCollection result = new HttpQSCollection(); + ParseQueryString(query, encoding, result); + return result; + } + + internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result) + { + if (query.Length == 0) + return; + + string decoded = HtmlDecode(query); + int decodedLength = decoded.Length; + int namePos = 0; + bool first = true; + while (namePos <= decodedLength) + { + int valuePos = -1, valueEnd = -1; + for (int q = namePos; q < decodedLength; q++) + { + if (valuePos == -1 && decoded[q] == '=') + { + valuePos = q + 1; + } + else if (decoded[q] == '&') + { + valueEnd = q; + break; + } + } + + if (first) + { + first = false; + if (decoded[namePos] == '?') + namePos++; + } + + string name, value; + if (valuePos == -1) + { + name = null; + valuePos = namePos; + } + else + { + name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding); + } + if (valueEnd < 0) + { + namePos = -1; + valueEnd = decoded.Length; + } + else + { + namePos = valueEnd + 1; + } + value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding); + + result.Add(name, value); + if (namePos == -1) + break; + } + } + #endregion // Methods + } +} diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 54c27cf0a..b3fbd2d1d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using System.Web; using Funq; using MediaBrowser.Model.Logging; using ServiceStack; @@ -236,7 +237,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private NameValueCollectionWrapper queryString; public INameValueCollection QueryString { - get { return queryString ?? (queryString = new NameValueCollectionWrapper(HttpUtility.ParseQueryString(request.Url.Query))); } + get { return queryString ?? (queryString = new NameValueCollectionWrapper(MyHttpUtility.ParseQueryString(request.Url.Query))); } } private NameValueCollectionWrapper formData; diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 3c29cf15d..cf1853c5e 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -403,10 +403,7 @@ namespace MediaBrowser.Server.Implementations.Library try { - _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user, new List<ItemFields> - { - ItemFields.PrimaryImageAspectRatio - }); + _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs deleted file mode 100644 index ae441b44e..000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs +++ /dev/null @@ -1,59 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.LiveTv; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby -{ - public class EmbyGuide : IListingsProvider - { - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _jsonSerializer; - - public EmbyGuide(IHttpClient httpClient, IJsonSerializer jsonSerializer) - { - _httpClient = httpClient; - _jsonSerializer = jsonSerializer; - } - - public string Name - { - get { return "Emby Guide"; } - } - - public string Type - { - get { return "emby"; } - } - - public Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) - { - return GetListingsProvider(info.Country).GetProgramsAsync(info, channelNumber, startDateUtc, endDateUtc, cancellationToken); - } - - public Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken) - { - return GetListingsProvider(info.Country).AddMetadata(info, channels, cancellationToken); - } - - public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) - { - return GetListingsProvider(info.Country).Validate(info, validateLogin, validateListings); - } - - public Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location) - { - return GetListingsProvider(country).GetLineups(country, location); - } - - private IEmbyListingProvider GetListingsProvider(string country) - { - return new EmbyListingsNorthAmerica(_httpClient, _jsonSerializer); - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs deleted file mode 100644 index 2993740d6..000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ /dev/null @@ -1,366 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby -{ - public class EmbyListingsNorthAmerica : IEmbyListingProvider - { - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _jsonSerializer; - - public EmbyListingsNorthAmerica(IHttpClient httpClient, IJsonSerializer jsonSerializer) - { - _httpClient = httpClient; - _jsonSerializer = jsonSerializer; - } - - public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) - { - channelNumber = NormalizeNumber(channelNumber); - - var url = "https://data.emby.media/service/listings?id=" + info.ListingsId; - - // Normalize - startDateUtc = startDateUtc.Date; - endDateUtc = startDateUtc.AddDays(7); - - url += "&start=" + startDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z"; - url += "&end=" + endDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z"; - - var response = await GetResponse<ListingInfo[]>(url).ConfigureAwait(false); - - return response.Where(i => IncludeInResults(i, channelNumber)).Select(GetProgramInfo).OrderBy(i => i.StartDate); - } - - private ProgramInfo GetProgramInfo(ListingInfo info) - { - var showType = info.showType ?? string.Empty; - - var program = new ProgramInfo - { - Id = info.listingID.ToString(CultureInfo.InvariantCulture), - Name = GetStringValue(info.showName), - HomePageUrl = GetStringValue(info.webLink), - Overview = info.description, - IsHD = info.hd, - IsLive = info.live, - IsPremiere = info.seasonPremiere || info.seriesPremiere, - IsMovie = showType.IndexOf("Movie", StringComparison.OrdinalIgnoreCase) != -1, - IsKids = showType.IndexOf("Children", StringComparison.OrdinalIgnoreCase) != -1, - IsNews = showType.IndexOf("News", StringComparison.OrdinalIgnoreCase) != -1, - IsSports = showType.IndexOf("Sports", StringComparison.OrdinalIgnoreCase) != -1 - }; - - if (!string.IsNullOrWhiteSpace(info.listDateTime)) - { - program.StartDate = DateTime.ParseExact(info.listDateTime, "yyyy'-'MM'-'dd' 'HH':'mm':'ss", CultureInfo.InvariantCulture); - program.StartDate = DateTime.SpecifyKind(program.StartDate, DateTimeKind.Utc); - program.EndDate = program.StartDate.AddMinutes(info.duration); - } - - if (info.starRating > 0) - { - program.CommunityRating = info.starRating*2; - } - - if (!string.IsNullOrWhiteSpace(info.rating)) - { - // They don't have dashes so try to normalize - program.OfficialRating = info.rating.Replace("TV", "TV-").Replace("--", "-"); - - var invalid = new[] { "N/A", "Approved", "Not Rated" }; - if (invalid.Contains(program.OfficialRating, StringComparer.OrdinalIgnoreCase)) - { - program.OfficialRating = null; - } - } - - if (!string.IsNullOrWhiteSpace(info.year)) - { - program.ProductionYear = int.Parse(info.year, CultureInfo.InvariantCulture); - } - - if (info.showID > 0) - { - program.ShowId = info.showID.ToString(CultureInfo.InvariantCulture); - } - - if (info.seriesID > 0) - { - program.SeriesId = info.seriesID.ToString(CultureInfo.InvariantCulture); - program.IsSeries = true; - program.IsRepeat = info.repeat; - - program.EpisodeTitle = GetStringValue(info.episodeTitle); - - if (string.Equals(program.Name, program.EpisodeTitle, StringComparison.OrdinalIgnoreCase)) - { - program.EpisodeTitle = null; - } - } - - if (info.starRating > 0) - { - program.CommunityRating = info.starRating * 2; - } - - if (string.Equals(info.showName, "Movie", StringComparison.OrdinalIgnoreCase)) - { - // Sometimes the movie title will be in here - if (!string.IsNullOrWhiteSpace(info.episodeTitle)) - { - program.Name = info.episodeTitle; - } - } - - return program; - } - - private string GetStringValue(string s) - { - return string.IsNullOrWhiteSpace(s) ? null : s; - } - - private bool IncludeInResults(ListingInfo info, string itemNumber) - { - if (string.Equals(itemNumber, NormalizeNumber(info.number), StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - var channelNumber = info.channelNumber.ToString(CultureInfo.InvariantCulture); - if (info.subChannelNumber > 0) - { - channelNumber += "." + info.subChannelNumber.ToString(CultureInfo.InvariantCulture); - } - - return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase); - } - - public async Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken) - { - var response = await GetResponse<LineupDetailResponse>("https://data.emby.media/service/lineups?id=" + info.ListingsId).ConfigureAwait(false); - - foreach (var channel in channels) - { - var station = response.stations.FirstOrDefault(i => - { - var itemNumber = NormalizeNumber(channel.Number); - - if (string.Equals(itemNumber, NormalizeNumber(i.number), StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - var channelNumber = i.channelNumber.ToString(CultureInfo.InvariantCulture); - if (i.subChannelNumber > 0) - { - channelNumber += "." + i.subChannelNumber.ToString(CultureInfo.InvariantCulture); - } - - return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase); - }); - - if (station != null) - { - //channel.Name = station.name; - - if (!string.IsNullOrWhiteSpace(station.logoFilename)) - { - channel.HasImage = true; - channel.ImageUrl = "http://cdn.tvpassport.com/image/station/100x100/" + station.logoFilename; - } - } - } - } - - private string NormalizeNumber(string number) - { - return number.Replace('-', '.'); - } - - public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) - { - return Task.FromResult(true); - } - - public async Task<List<NameIdPair>> GetLineups(string country, string location) - { - // location = postal code - var response = await GetResponse<LineupInfo[]>("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); - - return response.Select(i => new NameIdPair - { - Name = GetName(i), - Id = i.lineupID - - }).OrderBy(i => i.Name).ToList(); - } - - private string GetName(LineupInfo info) - { - var name = info.lineupName; - - if (string.Equals(info.lineupType, "cab", StringComparison.OrdinalIgnoreCase)) - { - name += " - Cable"; - } - else if (string.Equals(info.lineupType, "sat", StringComparison.OrdinalIgnoreCase)) - { - name += " - SAT"; - } - else if (string.Equals(info.lineupType, "ota", StringComparison.OrdinalIgnoreCase)) - { - name += " - OTA"; - } - - return name; - } - - private async Task<T> GetResponse<T>(string url, Func<string, string> filter = null) - where T : class - { - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = url, - CacheLength = TimeSpan.FromDays(1), - CacheMode = CacheMode.Unconditional - - }).ConfigureAwait(false)) - { - using (var reader = new StreamReader(stream)) - { - var path = await reader.ReadToEndAsync().ConfigureAwait(false); - - using (var secondStream = await _httpClient.Get(new HttpRequestOptions - { - Url = "https://www.mb3admin.com" + path, - CacheLength = TimeSpan.FromDays(1), - CacheMode = CacheMode.Unconditional - - }).ConfigureAwait(false)) - { - return ParseResponse<T>(secondStream, filter); - } - } - } - } - - private T ParseResponse<T>(Stream response, Func<string,string> filter) - { - using (var reader = new StreamReader(response)) - { - var json = reader.ReadToEnd(); - - if (filter != null) - { - json = filter(json); - } - - return _jsonSerializer.DeserializeFromString<T>(json); - } - } - - private class LineupInfo - { - public string lineupID { get; set; } - public string lineupName { get; set; } - public string lineupType { get; set; } - public string providerID { get; set; } - public string providerName { get; set; } - public string serviceArea { get; set; } - public string country { get; set; } - } - - private class Station - { - public string number { get; set; } - public int channelNumber { get; set; } - public int subChannelNumber { get; set; } - public int stationID { get; set; } - public string name { get; set; } - public string callsign { get; set; } - public string network { get; set; } - public string stationType { get; set; } - public int NTSC_TSID { get; set; } - public int DTV_TSID { get; set; } - public string webLink { get; set; } - public string logoFilename { get; set; } - } - - private class LineupDetailResponse - { - public string lineupID { get; set; } - public string lineupName { get; set; } - public string lineupType { get; set; } - public string providerID { get; set; } - public string providerName { get; set; } - public string serviceArea { get; set; } - public string country { get; set; } - public List<Station> stations { get; set; } - } - - private class ListingInfo - { - public string number { get; set; } - public int channelNumber { get; set; } - public int subChannelNumber { get; set; } - public int stationID { get; set; } - public string name { get; set; } - public string callsign { get; set; } - public string network { get; set; } - public string stationType { get; set; } - public string webLink { get; set; } - public string logoFilename { get; set; } - public int listingID { get; set; } - public string listDateTime { get; set; } - public int duration { get; set; } - public int showID { get; set; } - public int seriesID { get; set; } - public string showName { get; set; } - public string episodeTitle { get; set; } - public string episodeNumber { get; set; } - public int parts { get; set; } - public int partNum { get; set; } - public bool seriesPremiere { get; set; } - public bool seasonPremiere { get; set; } - public bool seriesFinale { get; set; } - public bool seasonFinale { get; set; } - public bool repeat { get; set; } - public bool @new { get; set; } - public string rating { get; set; } - public bool captioned { get; set; } - public bool educational { get; set; } - public bool blackWhite { get; set; } - public bool subtitled { get; set; } - public bool live { get; set; } - public bool hd { get; set; } - public bool descriptiveVideo { get; set; } - public bool inProgress { get; set; } - public string showTypeID { get; set; } - public int breakoutLevel { get; set; } - public string showType { get; set; } - public string year { get; set; } - public string guest { get; set; } - public string cast { get; set; } - public string director { get; set; } - public int starRating { get; set; } - public string description { get; set; } - public string league { get; set; } - public string team1 { get; set; } - public string team2 { get; set; } - public string @event { get; set; } - public string location { get; set; } - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs deleted file mode 100644 index 95c22b986..000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs +++ /dev/null @@ -1,18 +0,0 @@ -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.LiveTv; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby -{ - public interface IEmbyListingProvider - { - Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); - Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken); - Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); - Task<List<NameIdPair>> GetLineups(string country, string location); - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 85d3ffdba..87d7ff3eb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -114,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestString = _jsonSerializer.SerializeToString(requestList); _logger.Debug("Request string for schedules is: " + requestString); httpOptions.RequestContent = requestString; - using (var response = await Post(httpOptions).ConfigureAwait(false)) + using (var response = await Post(httpOptions, true, info).ConfigureAwait(false)) { StreamReader reader = new StreamReader(response.Content); string responseString = reader.ReadToEnd(); @@ -138,7 +138,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; httpOptions.RequestContent = requestBody; - using (var innerResponse = await Post(httpOptions).ConfigureAwait(false)) + using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false)) { StreamReader innerReader = new StreamReader(innerResponse.Content); responseString = innerReader.ReadToEnd(); @@ -148,7 +148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings responseString); var programDict = programDetails.ToDictionary(p => p.programID, y => y); - var images = await GetImageForPrograms(programDetails.Where(p => p.hasImageArtwork).Select(p => p.programID).ToList(), cancellationToken); + var images = await GetImageForPrograms(info, programDetails.Where(p => p.hasImageArtwork).Select(p => p.programID).ToList(), cancellationToken); var schedules = dailySchedules.SelectMany(d => d.programs); foreach (ScheduleDirect.Program schedule in schedules) @@ -229,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - using (var response = await Get(httpOptions).ConfigureAwait(false)) + using (var response = await Get(httpOptions, true, info).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response); _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); @@ -447,7 +447,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return url; } - private async Task<List<ScheduleDirect.ShowImages>> GetImageForPrograms(List<string> programIds, + private async Task<List<ScheduleDirect.ShowImages>> GetImageForPrograms( + ListingsProviderInfo info, + List<string> programIds, CancellationToken cancellationToken) { var imageIdString = "["; @@ -472,7 +474,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings TimeoutMs = 60000 }; List<ScheduleDirect.ShowImages> images; - using (var innerResponse2 = await Post(httpOptions).ConfigureAwait(false)) + using (var innerResponse2 = await Post(httpOptions, true, info).ConfigureAwait(false)) { images = _jsonSerializer.DeserializeFromStream<List<ScheduleDirect.ShowImages>>( innerResponse2.Content); @@ -504,7 +506,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (Stream responce = await Get(options).ConfigureAwait(false)) + using (Stream responce = await Get(options, false, info).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<List<ScheduleDirect.Headends>>(responce); @@ -606,30 +608,58 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } - private async Task<HttpResponseInfo> Post(HttpRequestOptions options) + private async Task<HttpResponseInfo> Post(HttpRequestOptions options, + bool enableRetry, + ListingsProviderInfo providerInfo) { try { return await _httpClient.Post(options).ConfigureAwait(false); - } - catch - { - _tokens.Clear(); - throw; - } + } + catch (HttpException ex) + { + _tokens.Clear(); + + if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500) + { + enableRetry = false; + } + + if (!enableRetry) { + throw; + } + } + + var newToken = await GetToken (providerInfo, options.CancellationToken).ConfigureAwait (false); + options.RequestHeaders ["token"] = newToken; + return await Post (options, false, providerInfo).ConfigureAwait (false); } - private async Task<Stream> Get(HttpRequestOptions options) + private async Task<Stream> Get(HttpRequestOptions options, + bool enableRetry, + ListingsProviderInfo providerInfo) { try { return await _httpClient.Get(options).ConfigureAwait(false); - } - catch - { - _tokens.Clear(); - throw; - } + } + catch (HttpException ex) + { + _tokens.Clear(); + + if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500) + { + enableRetry = false; + } + + if (!enableRetry) { + throw; + } + } + + var newToken = await GetToken (providerInfo, options.CancellationToken).ConfigureAwait (false); + options.RequestHeaders ["token"] = newToken; + return await Get (options, false, providerInfo).ConfigureAwait (false); } private async Task<string> GetTokenInternal(string username, string password, @@ -646,7 +676,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings //_logger.Info("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " + // httpOptions.RequestContent); - using (var responce = await Post(httpOptions).ConfigureAwait(false)) + using (var responce = await Post(httpOptions, false, null).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Token>(responce.Content); if (root.message == "OK") @@ -728,7 +758,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (var response = await Get(options).ConfigureAwait(false)) + using (var response = await Get(options, false, null).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(response); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 9ffd8a500..04f99cdce 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -231,10 +231,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { dto.ImageTags[ImageType.Primary] = imageTag; - _dtoService.AttachPrimaryImageAspectRatio(dto, info, new List<ItemFields> - { - ItemFields.PrimaryImageAspectRatio - }); + _dtoService.AttachPrimaryImageAspectRatio(dto, info); } if (currentProgram != null) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs new file mode 100644 index 000000000..ecd2864c5 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts +{ + public class SatIp : BaseTunerHost + { + public SatIp(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder) + : base(config, logger, jsonSerializer, mediaEncoder) + { + } + + protected override Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public override string Type + { + get { return "SatIp"; } + } + + protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override Task<MediaSourceInfo> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override bool IsValidChannelId(string channelId) + { + throw new NotImplementedException(); + } + } +} diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 98039b994..40dfcd2c3 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -71,7 +71,7 @@ "ViewTypeTvShowSeries": "S\u00e8ries:", "ViewTypeTvGenres": "G\u00e8neres", "ViewTypeTvFavoriteSeries": "S\u00e8ries Preferides", - "ViewTypeTvFavoriteEpisodes": "Episodis preferits", + "ViewTypeTvFavoriteEpisodes": "Episodis Preferits", "ViewTypeMovieResume": "Resume", "ViewTypeMovieLatest": "Darrers", "ViewTypeMovieMovies": "Pel\u00b7l\u00edcules", @@ -173,5 +173,5 @@ "HeaderWriter": "Escriptors", "HeaderParentalRatings": "Parental Ratings", "HeaderCommunityRatings": "Qualificacions de la comunitat", - "StartupEmbyServerIsLoading": "El servidor d'Emby s'est\u00e0 carregant. Si us plau, torneu-ho a provar de nou en breu." + "StartupEmbyServerIsLoading": "El servidor d'Emby s'està carregant. Si et plau, tornau-ho a provar de nou en breu." }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index e52c91628..e5c94a01b 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -43,7 +43,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Interfaces.IO"> <HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath> @@ -52,15 +52,18 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\MediaBrowser.Naming.1.0.0.41\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath> </Reference> + <Reference Include="MoreLinq"> + <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> + </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> </Reference> <Reference Include="ServiceStack.Api.Swagger"> <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath> </Reference> - <Reference Include="SocketHttpListener, Version=1.0.5754.42244, Culture=neutral, processorArchitecture=MSIL"> + <Reference Include="SocketHttpListener, Version=1.0.5840.28948, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\SocketHttpListener.1.0.0.10\lib\net45\SocketHttpListener.dll</HintPath> + <HintPath>..\packages\SocketHttpListener.1.0.0.25\lib\net45\SocketHttpListener.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> @@ -70,6 +73,7 @@ <Reference Include="Microsoft.CSharp" /> <Reference Include="System.Data" /> <Reference Include="System.Net" /> + <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Security" /> <Reference Include="System.Web" /> <Reference Include="System.Xml" /> @@ -94,9 +98,6 @@ <Reference Include="Mono.Nat"> <HintPath>..\packages\Mono.Nat.1.2.24.0\lib\net40\Mono.Nat.dll</HintPath> </Reference> - <Reference Include="MoreLinq"> - <HintPath>..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll</HintPath> - </Reference> </ItemGroup> <ItemGroup> <Compile Include="..\SharedVersion.cs"> @@ -160,6 +161,7 @@ <Compile Include="HttpServer\ServerLogFactory.cs" /> <Compile Include="HttpServer\ServerLogger.cs" /> <Compile Include="HttpServer\Security\SessionContext.cs" /> + <Compile Include="HttpServer\SocketSharp\HttpUtility.cs" /> <Compile Include="HttpServer\SocketSharp\SharpWebSocket.cs" /> <Compile Include="HttpServer\StreamWriter.cs" /> <Compile Include="HttpServer\SwaggerService.cs" /> @@ -216,9 +218,6 @@ <Compile Include="LiveTv\EmbyTV\RecordingHelper.cs" /> <Compile Include="LiveTv\EmbyTV\SeriesTimerManager.cs" /> <Compile Include="LiveTv\EmbyTV\TimerManager.cs" /> - <Compile Include="LiveTv\Listings\Emby\EmbyListings.cs" /> - <Compile Include="LiveTv\Listings\Emby\EmbyListingsNorthAmerica.cs" /> - <Compile Include="LiveTv\Listings\Emby\IEmbyListingProvider.cs" /> <Compile Include="LiveTv\Listings\SchedulesDirect.cs" /> <Compile Include="LiveTv\Listings\XmlTv.cs" /> <Compile Include="LiveTv\LiveTvConfigurationFactory.cs" /> diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs index 96f469f69..457f5a33d 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks try { - await _installationManager.InstallPackage(i, new Progress<double>(), cancellationToken).ConfigureAwait(false); + await _installationManager.InstallPackage(i, true, new Progress<double>(), cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 7d9453822..5c04f2782 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.5" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
<package id="MediaBrowser.Naming" version="1.0.0.41" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
- <package id="morelinq" version="1.1.1" targetFramework="net45" />
+ <package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SocketHttpListener" version="1.0.0.10" targetFramework="net45" />
+ <package id="SocketHttpListener" version="1.0.0.25" targetFramework="net45" />
</packages>
\ No newline at end of file diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index e9f631bf3..9f36599fa 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -54,7 +54,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 69c8201af..bccf6487a 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Server.Mono var nativeApp = new NativeApp(options); - _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "MBServer.Mono", nativeApp); + _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "emby.mono.zip", nativeApp); if (options.ContainsOption("-v")) { diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config index 6a2a6c1e5..2956d69c6 100644 --- a/MediaBrowser.Server.Mono/packages.config +++ b/MediaBrowser.Server.Mono/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 99a7f0a15..21731a3a6 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -91,14 +91,17 @@ using MediaBrowser.Server.Startup.Common.Migrations; using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Reflection; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.Implementations.Updates; namespace MediaBrowser.Server.Startup.Common { @@ -204,9 +207,10 @@ namespace MediaBrowser.Server.Startup.Common private IPlaylistManager PlaylistManager { get; set; } private readonly StartupOptions _startupOptions; - private readonly string _remotePackageName; + private readonly string _releaseAssetFilename; internal INativeApp NativeApp { get; set; } + private Timer _ipAddressCacheTimer; /// <summary> /// Initializes a new instance of the <see cref="ApplicationHost" /> class. @@ -215,21 +219,23 @@ namespace MediaBrowser.Server.Startup.Common /// <param name="logManager">The log manager.</param> /// <param name="options">The options.</param> /// <param name="fileSystem">The file system.</param> - /// <param name="remotePackageName">Name of the remote package.</param> + /// <param name="releaseAssetFilename">The release asset filename.</param> /// <param name="nativeApp">The native application.</param> public ApplicationHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, - string remotePackageName, + string releaseAssetFilename, INativeApp nativeApp) : base(applicationPaths, logManager, fileSystem) { _startupOptions = options; - _remotePackageName = remotePackageName; + _releaseAssetFilename = releaseAssetFilename; NativeApp = nativeApp; SetBaseExceptionMessage(); + + _ipAddressCacheTimer = new Timer(OnCacheClearTimerFired, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3)); } private Version _version; @@ -316,6 +322,7 @@ namespace MediaBrowser.Server.Startup.Common { await base.RunStartupTasks().ConfigureAwait(false); + Logger.Info("ServerId: {0}", SystemId); Logger.Info("Core startup complete"); HttpServer.GlobalResponse = null; @@ -436,7 +443,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager)); - HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, "Emby", "web/index.html"); + HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, "Emby", "web/index.html"); HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); RegisterSingleInstance(HttpServer, false); progress.Report(10); @@ -515,7 +522,7 @@ namespace MediaBrowser.Server.Startup.Common SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, MediaSourceManager); RegisterSingleInstance(SubtitleManager); - RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LogManager.GetLogger("IDeviceDiscovery"), ServerConfigurationManager, this)); + RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LogManager.GetLogger("IDeviceDiscovery"), ServerConfigurationManager, this, NetworkManager)); ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository); RegisterSingleInstance(ChapterManager); @@ -963,6 +970,10 @@ namespace MediaBrowser.Server.Startup.Common { get { + if (!ServerConfigurationManager.Configuration.EnableAutoUpdate) + { + return false; + } #if DEBUG return false; #endif @@ -1108,14 +1119,14 @@ namespace MediaBrowser.Server.Startup.Common try { // Return the first matched address, if found, or the first known local address - var address = LocalIpAddress; + var address = LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i)); - if (!string.IsNullOrWhiteSpace(address)) + if (address != null) { - address = GetLocalApiUrl(address); + return GetLocalApiUrl(address.ToString()); } - return address; + return null; } catch (Exception ex) { @@ -1133,40 +1144,71 @@ namespace MediaBrowser.Server.Startup.Common HttpPort.ToString(CultureInfo.InvariantCulture)); } - public string LocalIpAddress + public List<IPAddress> LocalIpAddresses { get { - return HttpServerIpAddresses.FirstOrDefault(); + var localAddresses = NetworkManager.GetLocalIpAddresses() + .Where(IsIpAddressValid) + .ToList(); + + return localAddresses; } } - private IEnumerable<string> HttpServerIpAddresses + private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); + private bool IsIpAddressValid(IPAddress address) { - get + if (IPAddress.IsLoopback(address)) { - var localAddresses = NetworkManager.GetLocalIpAddresses() - .ToList(); + return true; + } - var httpServerAddresses = HttpServer.LocalEndPoints - .Select(i => i.Split(':').FirstOrDefault()) - .Where(i => !string.IsNullOrEmpty(i)) - .ToList(); + var apiUrl = GetLocalApiUrl(address.ToString()); + apiUrl += "/system/ping"; - // Cross-check the local ip addresses with addresses that have been received on with the http server - var matchedAddresses = httpServerAddresses - .Where(i => localAddresses.Contains(i, StringComparer.OrdinalIgnoreCase)) - .ToList(); + bool cachedResult; + if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) + { + return cachedResult; + } + + try + { + using (var response = HttpClient.SendAsync(new HttpRequestOptions + { + Url = apiUrl, + LogErrorResponseBody = false, + LogErrors = false, + LogRequest = false - if (matchedAddresses.Count == 0) + }, "POST").Result) { - return localAddresses; + using (var reader = new StreamReader(response.Content)) + { + var result = reader.ReadToEnd(); + var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); + + _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); + Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); + return valid; + } } + } + catch + { + Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); - return matchedAddresses; + _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false); + return false; } } + private void OnCacheClearTimerFired(object state) + { + _validAddressResults.Clear(); + } + public string FriendlyName { get @@ -1263,25 +1305,23 @@ namespace MediaBrowser.Server.Startup.Common /// <returns>Task{CheckForUpdateResult}.</returns> public override async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress) { - var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - - var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, _remotePackageName, null, ApplicationVersion, ConfigurationManager.CommonConfiguration.SystemUpdateLevel); + var cacheLength = TimeSpan.FromHours(3); + var updateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel; - var versionObject = version == null || string.IsNullOrWhiteSpace(version.versionStr) ? null : new Version(version.versionStr); - - var isUpdateAvailable = versionObject != null && versionObject > ApplicationVersion; + if (updateLevel == PackageVersionClass.Beta) + { + cacheLength = TimeSpan.FromHours(1); + } + else if (updateLevel == PackageVersionClass.Dev) + { + cacheLength = TimeSpan.FromMinutes(5); + } - var result = versionObject != null ? - new CheckForUpdateResult { AvailableVersion = versionObject.ToString(), IsUpdateAvailable = isUpdateAvailable, Package = version } : - new CheckForUpdateResult { AvailableVersion = ApplicationVersion.ToString(), IsUpdateAvailable = false }; + var result = await new GithubUpdater(HttpClient, JsonSerializer, cacheLength).CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, updateLevel, _releaseAssetFilename, + "MBServer", "Mbserver.zip", cancellationToken).ConfigureAwait(false); HasUpdateAvailable = result.IsUpdateAvailable; - if (result.IsUpdateAvailable) - { - Logger.Info("New application version is available: {0}", result.AvailableVersion); - } - return result; } @@ -1294,7 +1334,7 @@ namespace MediaBrowser.Server.Startup.Common /// <returns>Task.</returns> public override async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress) { - await InstallationManager.InstallPackage(package, progress, cancellationToken).ConfigureAwait(false); + await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false); HasUpdateAvailable = false; diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 13b782e40..6dd2066bb 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -33,7 +33,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config index 6a2a6c1e5..2956d69c6 100644 --- a/MediaBrowser.Server.Startup.Common/packages.config +++ b/MediaBrowser.Server.Startup.Common/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index b8af35fde..62cdbd05f 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -18,6 +18,9 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using CommonIO.Windows; +using Emby.Drawing.ImageMagick; +using ImageMagickSharp; +using MediaBrowser.Common.Net; using MediaBrowser.Server.Implementations.Logging; namespace MediaBrowser.ServerApplication @@ -29,6 +32,10 @@ namespace MediaBrowser.ServerApplication private static ILogger _logger; private static bool _isRunningAsService = false; + private static bool _appHostDisposed; + + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool SetDllDirectory(string lpPathName); /// <summary> /// Defines the entry point of the application. @@ -41,6 +48,11 @@ namespace MediaBrowser.ServerApplication var currentProcess = Process.GetCurrentProcess(); var applicationPath = currentProcess.MainModule.FileName; + var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86"); + + Wand.SetMagickCoderModulePath(architecturePath); + + var success = SetDllDirectory(architecturePath); var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService); @@ -136,7 +148,7 @@ namespace MediaBrowser.ServerApplication { _logger.Info("Found a duplicate process. Giving it time to exit."); - if (!duplicate.WaitForExit(10000)) + if (!duplicate.WaitForExit(12000)) { _logger.Info("The duplicate process did not exit."); return true; @@ -215,7 +227,7 @@ namespace MediaBrowser.ServerApplication logManager, options, fileSystem, - "MBServer", + "emby.windows.zip", nativeApp); var initProgress = new Progress<double>(); @@ -241,6 +253,9 @@ namespace MediaBrowser.ServerApplication { Task.WaitAll(task); + task = InstallVcredistIfNeeded(_appHost, _logger); + Task.WaitAll(task); + SystemEvents.SessionEnding += SystemEvents_SessionEnding; SystemEvents.SessionSwitch += SystemEvents_SessionSwitch; @@ -329,7 +344,7 @@ namespace MediaBrowser.ServerApplication { _logger.Info("Shutting down"); - _appHost.Dispose(); + DisposeAppHost(); } /// <summary> @@ -500,14 +515,15 @@ namespace MediaBrowser.ServerApplication } else { + DisposeAppHost(); + ShutdownWindowsApplication(); } } public static void Restart() { - _logger.Info("Disposing app host"); - _appHost.Dispose(); + DisposeAppHost(); if (!_isRunningAsService) { @@ -522,11 +538,24 @@ namespace MediaBrowser.ServerApplication } } + private static void DisposeAppHost() + { + if (!_appHostDisposed) + { + _logger.Info("Disposing app host"); + + _appHostDisposed = true; + _appHost.Dispose(); + } + } + private static void ShutdownWindowsApplication() { _logger.Info("Calling Application.Exit"); Application.Exit(); + Environment.Exit(0); + _logger.Info("Calling ApplicationTaskCompletionSource.SetResult"); ApplicationTaskCompletionSource.SetResult(true); } @@ -544,6 +573,72 @@ namespace MediaBrowser.ServerApplication } } + private static async Task InstallVcredistIfNeeded(ApplicationHost appHost, ILogger logger) + { + try + { + var version = ImageMagickEncoder.GetVersion(); + return; + } + catch (Exception ex) + { + logger.ErrorException("Error loading ImageMagick", ex); + } + + try + { + await InstallVcredist().ConfigureAwait(false); + } + catch (Exception ex) + { + logger.ErrorException("Error installing Visual Studio C++ runtime", ex); + } + } + + private async static Task InstallVcredist() + { + var httpClient = _appHost.HttpClient; + + var tmp = await httpClient.GetTempFile(new HttpRequestOptions + { + Url = GetVcredistUrl(), + Progress = new Progress<double>() + + }).ConfigureAwait(false); + + var exePath = Path.ChangeExtension(tmp, ".exe"); + File.Copy(tmp, exePath); + + var startInfo = new ProcessStartInfo + { + FileName = exePath, + + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden, + Verb = "runas", + ErrorDialog = false + }; + + _logger.Info("Running {0}", startInfo.FileName); + + using (var process = Process.Start(startInfo)) + { + process.WaitForExit(); + } + } + + private static string GetVcredistUrl() + { + if (Environment.Is64BitProcess) + { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x64.exe"; + } + + // TODO: ARM url - https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_arm.exe + + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x86.exe"; + } + /// <summary> /// Sets the error mode. /// </summary> diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 5813dcac5..3e62f4735 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -22,7 +22,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> - <Prefer32Bit>true</Prefer32Bit> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PlatformTarget>AnyCPU</PlatformTarget> @@ -32,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <PropertyGroup> <StartupObject>MediaBrowser.ServerApplication.MainStartup</StartupObject> @@ -62,10 +63,11 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> - <Reference Include="ImageMagickSharp"> - <HintPath>..\packages\ImageMagickSharp.1.0.0.16\lib\net45\ImageMagickSharp.dll</HintPath> + <Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll</HintPath> </Reference> <Reference Include="MediaBrowser.IsoMounter"> <HintPath>..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll</HintPath> @@ -156,255 +158,907 @@ </EmbeddedResource> </ItemGroup> <ItemGroup> - <Content Include="..\Installation\MediaBrowser.InstallUtil.dll"> + <Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x64\SQLite.Interop.dll"> + <Link>x64\SQLite.Interop.dll</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x86\SQLite.Interop.dll"> + <Link>x86\SQLite.Interop.dll</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="..\Tools\Installation\MediaBrowser.InstallUtil.dll"> <Link>MediaBrowser.InstallUtil.dll</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="..\Installation\MediaBrowser.Uninstaller.exe"> + <Content Include="..\Tools\Installation\MediaBrowser.Uninstaller.exe"> <Link>MediaBrowser.Uninstaller.exe</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="..\Installation\MediaBrowser.Updater.exe"> + <Content Include="..\Tools\Installation\MediaBrowser.Updater.exe"> <Link>MediaBrowser.Updater.exe</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x64\SQLite.Interop.dll"> - <Link>x64\SQLite.Interop.dll</Link> + <Content Include="x64\CORE_RL_bzlib_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x86\SQLite.Interop.dll"> - <Link>x86\SQLite.Interop.dll</Link> + <Content Include="x64\CORE_RL_cairo_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_exr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_glib_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_jp2_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_jpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_lcms_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_librsvg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_libxml_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_lqr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_Magick++_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_magick_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_openjpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_pango_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_png_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_tiff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_ttf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_wand_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_webp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\CORE_RL_zlib_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_aai_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_art_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_avs_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_bgr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_bmp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_braille_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_cals_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_caption_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_cin_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_cip_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_clipboard_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_clip_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_cmyk_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_cut_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dcm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dds_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_debug_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dib_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_djvu_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dng_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dot_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dps_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_dpx_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_emf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ept_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_exr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_fax_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_fd_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_fits_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_fpx_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_gif_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_gradient_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_gray_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_hald_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_hdr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_histogram_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_hrz_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_html_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_icon_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_info_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_inline_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ipl_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_jbig_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_jnx_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_jp2_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_jpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_json_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_label_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mac_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_magick_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_map_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mask_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_matte_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mat_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_meta_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_miff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mono_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mpc_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mpr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_msl_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mtv_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_mvg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_null_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_otb_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_palm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pango_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pattern_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pcd_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pcl_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pcx_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pdb_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pdf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pes_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pict_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pix_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_plasma_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_png_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pnm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_preview_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ps2_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ps3_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_psd_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ps_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_pwp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_raw_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_bzlib_.dll"> + <Content Include="x64\IM_MOD_RL_rgb_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_cairo_.dll"> + <Content Include="x64\IM_MOD_RL_rgf_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_exr_.dll"> + <Content Include="x64\IM_MOD_RL_rla_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_glib_.dll"> + <Content Include="x64\IM_MOD_RL_rle_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_jbig_.dll"> + <Content Include="x64\IM_MOD_RL_screenshot_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_jp2_.dll"> + <Content Include="x64\IM_MOD_RL_scr_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_jpeg_.dll"> + <Content Include="x64\IM_MOD_RL_sct_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_lcms_.dll"> + <Content Include="x64\IM_MOD_RL_sfw_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_librsvg_.dll"> + <Content Include="x64\IM_MOD_RL_sgi_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_libxml_.dll"> + <Content Include="x64\IM_MOD_RL_sixel_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_lqr_.dll"> + <Content Include="x64\IM_MOD_RL_stegano_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_Magick++_.dll"> + <Content Include="x64\IM_MOD_RL_sun_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_magick_.dll"> + <Content Include="x64\IM_MOD_RL_svg_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_openjpeg_.dll"> + <Content Include="x64\IM_MOD_RL_tga_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_pango_.dll"> + <Content Include="x64\IM_MOD_RL_thumbnail_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_png_.dll"> + <Content Include="x64\IM_MOD_RL_tiff_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_tiff_.dll"> + <Content Include="x64\IM_MOD_RL_tile_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_ttf_.dll"> + <Content Include="x64\IM_MOD_RL_tim_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_wand_.dll"> + <Content Include="x64\IM_MOD_RL_ttf_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_webp_.dll"> + <Content Include="x64\IM_MOD_RL_txt_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="CORE_RL_zlib_.dll"> + <Content Include="x64\IM_MOD_RL_uil_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_url_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_uyvy_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_vicar_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_vid_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_viff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_vips_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_wbmp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_webp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_wmf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_wpg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xbm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xcf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xc_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xpm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xps_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_xtrn_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_ycbcr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x64\IM_MOD_RL_yuv_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_bzlib_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_cairo_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_exr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_glib_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_jbig_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_jp2_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_jpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_lcms_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_librsvg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_libxml_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_lqr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_Magick++_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_magick_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_openjpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_pango_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_png_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_tiff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_ttf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_wand_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_webp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\CORE_RL_zlib_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> <Content Include="Icon.ico" /> - <Content Include="IM_MOD_RL_bgr_.dll"> + <Content Include="x86\IM_MOD_RL_aai_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_art_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_avs_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_bgr_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_bmp_.dll"> + <Content Include="x86\IM_MOD_RL_bmp_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_caption_.dll"> + <Content Include="x86\IM_MOD_RL_braille_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_clipboard_.dll"> + <Content Include="x86\IM_MOD_RL_cals_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_clip_.dll"> + <Content Include="x86\IM_MOD_RL_caption_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_cmyk_.dll"> + <Content Include="x86\IM_MOD_RL_cin_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_cut_.dll"> + <Content Include="x86\IM_MOD_RL_cip_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_dib_.dll"> + <Content Include="x86\IM_MOD_RL_clipboard_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_emf_.dll"> + <Content Include="x86\IM_MOD_RL_clip_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_gif_.dll"> + <Content Include="x86\IM_MOD_RL_cmyk_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_gradient_.dll"> + <Content Include="x86\IM_MOD_RL_cut_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_gray_.dll"> + <Content Include="x86\IM_MOD_RL_dcm_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_hdr_.dll"> + <Content Include="x86\IM_MOD_RL_dds_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_histogram_.dll"> + <Content Include="x86\IM_MOD_RL_debug_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_html_.dll"> + <Content Include="x86\IM_MOD_RL_dib_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_icon_.dll"> + <Content Include="x86\IM_MOD_RL_djvu_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_info_.dll"> + <Content Include="x86\IM_MOD_RL_dng_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_jpeg_.dll"> + <Content Include="x86\IM_MOD_RL_dot_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_json_.dll"> + <Content Include="x86\IM_MOD_RL_dps_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_label_.dll"> + <Content Include="x86\IM_MOD_RL_dpx_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_magick_.dll"> + <Content Include="x86\IM_MOD_RL_emf_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_map_.dll"> + <Content Include="x86\IM_MOD_RL_ept_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_mask_.dll"> + <Content Include="x86\IM_MOD_RL_exr_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_matte_.dll"> + <Content Include="x86\IM_MOD_RL_fax_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_mat_.dll"> + <Content Include="x86\IM_MOD_RL_fd_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_meta_.dll"> + <Content Include="x86\IM_MOD_RL_fits_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_miff_.dll"> + <Content Include="x86\IM_MOD_RL_fpx_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_mono_.dll"> + <Content Include="x86\IM_MOD_RL_gif_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_mpeg_.dll"> + <Content Include="x86\IM_MOD_RL_gradient_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_null_.dll"> + <Content Include="x86\IM_MOD_RL_gray_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_pattern_.dll"> + <Content Include="x86\IM_MOD_RL_hald_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_pdf_.dll"> + <Content Include="x86\IM_MOD_RL_hdr_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_png_.dll"> + <Content Include="x86\IM_MOD_RL_histogram_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_preview_.dll"> + <Content Include="x86\IM_MOD_RL_hrz_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_ps2_.dll"> + <Content Include="x86\IM_MOD_RL_html_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_ps3_.dll"> + <Content Include="x86\IM_MOD_RL_icon_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_psd_.dll"> + <Content Include="x86\IM_MOD_RL_info_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_ps_.dll"> + <Content Include="x86\IM_MOD_RL_inline_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_raw_.dll"> + <Content Include="x86\IM_MOD_RL_ipl_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_rgb_.dll"> + <Content Include="x86\IM_MOD_RL_jbig_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_screenshot_.dll"> + <Content Include="x86\IM_MOD_RL_jnx_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_thumbnail_.dll"> + <Content Include="x86\IM_MOD_RL_jp2_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_tiff_.dll"> + <Content Include="x86\IM_MOD_RL_jpeg_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_tile_.dll"> + <Content Include="x86\IM_MOD_RL_json_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_ttf_.dll"> + <Content Include="x86\IM_MOD_RL_label_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_txt_.dll"> + <Content Include="x86\IM_MOD_RL_mac_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_url_.dll"> + <Content Include="x86\IM_MOD_RL_magick_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_uyvy_.dll"> + <Content Include="x86\IM_MOD_RL_map_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_wbmp_.dll"> + <Content Include="x86\IM_MOD_RL_mask_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_webp_.dll"> + <Content Include="x86\IM_MOD_RL_matte_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_wmf_.dll"> + <Content Include="x86\IM_MOD_RL_mat_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_xc_.dll"> + <Content Include="x86\IM_MOD_RL_meta_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_xps_.dll"> + <Content Include="x86\IM_MOD_RL_miff_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="IM_MOD_RL_yuv_.dll"> + <Content Include="x86\IM_MOD_RL_mono_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_mpc_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_mpeg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_mpr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_msl_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_mtv_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_mvg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_null_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_otb_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_palm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pango_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pattern_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pcd_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pcl_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pcx_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pdb_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pdf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pes_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pict_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pix_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_plasma_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_png_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pnm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_preview_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_ps2_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_ps3_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_psd_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_ps_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_pwp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_raw_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_rgb_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_rgf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_rla_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_rle_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_screenshot_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_scr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_sct_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_sfw_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_sgi_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_sixel_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_stegano_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_sun_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_svg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_tga_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_thumbnail_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_tiff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_tile_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_tim_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_ttf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_txt_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_uil_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_url_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_uyvy_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_vicar_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_vid_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_viff_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_vips_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_wbmp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_webp_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_wmf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_wpg_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xbm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xcf_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xc_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xpm_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xps_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_xtrn_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_ycbcr_.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="x86\IM_MOD_RL_yuv_.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> <Content Include="Resources\Images\mb3logo800.png" /> </ItemGroup> <ItemGroup> + <ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj"> + <Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project> + <Name>Emby.Drawing</Name> + </ProjectReference> <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj"> <Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project> <Name>MediaBrowser.Api</Name> diff --git a/MediaBrowser.ServerApplication/Native/Autorun.cs b/MediaBrowser.ServerApplication/Native/Autorun.cs index 2cacaae8e..c384d0460 100644 --- a/MediaBrowser.ServerApplication/Native/Autorun.cs +++ b/MediaBrowser.ServerApplication/Native/Autorun.cs @@ -17,25 +17,10 @@ namespace MediaBrowser.ServerApplication.Native /// <param name="fileSystem">The file system.</param> public static void Configure(bool autorun, IFileSystem fileSystem) { - var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk"); - - if (!Directory.Exists(Path.GetDirectoryName(shortcutPath))) - { - shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk"); - } + var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk"); var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup); - // Remove lnk from old name - try - { - fileSystem.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Media Browser Server.lnk")); - } - catch - { - - } - if (autorun) { //Copy our shortut into the startup folder for this user diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index bff342d01..ceab5379d 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.ServerApplication.Native if (!System.Environment.Is64BitProcess) { - list.Add(typeof(PismoIsoManager).Assembly); + //list.Add(typeof(PismoIsoManager).Assembly); } list.Add(GetType().Assembly); diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index e9a7d5985..673c6cddd 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -133,9 +133,22 @@ namespace MediaBrowser.ServerApplication LocalizeText(); notifyIcon1.DoubleClick += notifyIcon1_DoubleClick; + Application.ThreadExit += Application_ThreadExit; Application.ApplicationExit += Application_ApplicationExit; } + void Application_ThreadExit(object sender, EventArgs e) + { + try + { + notifyIcon1.Visible = false; + } + catch + { + + } + } + void Application_ApplicationExit(object sender, EventArgs e) { try diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index dec8199cc..db2bb5476 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> - <package id="ImageMagickSharp" version="1.0.0.16" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> + <package id="ImageMagickSharp" version="1.0.0.17" targetFramework="net45" /> <package id="MediaBrowser.IsoMounting" version="3.0.69" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> <package id="System.Data.SQLite.Core" version="1.0.94.0" targetFramework="net45" /> diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 4da1f42c4..48a8bf253 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -49,7 +49,7 @@ <ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
@@ -122,9 +122,6 @@ <Content Include="dashboard-ui\components\humanedate.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\components\imagestore.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\components\itemidentifier\itemidentifier.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 24a8a5316..128a2f162 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="MediaBrowser.ApiClient.Javascript" version="3.0.249" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> <package id="WebMarkupMin.Core" version="1.0.1" targetFramework="net45" /> diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj index 353fe31ca..16b6ca995 100644 --- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj +++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj @@ -33,7 +33,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="Patterns.Logging"> <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index fa58b67da..0da53f575 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -305,8 +305,19 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(stream.Codec)) { - writer.WriteElementString("codec", stream.Codec); - writer.WriteElementString("micodec", stream.Codec); + var codec = stream.Codec; + + if ((stream.CodecTag ?? string.Empty).IndexOf("xvid", StringComparison.OrdinalIgnoreCase) != -1) + { + codec = "xvid;"; + } + else if ((stream.CodecTag ?? string.Empty).IndexOf("divx", StringComparison.OrdinalIgnoreCase) != -1) + { + codec = "divx;"; + } + + writer.WriteElementString("codec", codec); + writer.WriteElementString("micodec", codec); } if (stream.BitRate.HasValue) diff --git a/MediaBrowser.XbmcMetadata/packages.config b/MediaBrowser.XbmcMetadata/packages.config index fad6af08e..28556744d 100644 --- a/MediaBrowser.XbmcMetadata/packages.config +++ b/MediaBrowser.XbmcMetadata/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.7" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file |
