From 6146b57e7c908d301f5aee3a8cdd996b395db363 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Sep 2013 12:49:55 -0400 Subject: [PATCH 1/9] update to servicestack 3.9.62 --- MediaBrowser.Api/GamesService.cs | 3 ++- MediaBrowser.Api/MediaBrowser.Api.csproj | 10 +++++----- MediaBrowser.Api/UserLibrary/ItemsService.cs | 1 - MediaBrowser.Api/packages.config | 4 ++-- .../MediaBrowser.Common.Implementations.csproj | 2 +- .../packages.config | 2 +- MediaBrowser.Common/MediaBrowser.Common.csproj | 10 +++++----- MediaBrowser.Common/packages.config | 4 ++-- MediaBrowser.Controller/Entities/GameSystem.cs | 6 ++++++ MediaBrowser.Model/Dto/GameSystemSummary.cs | 6 ++++++ .../Savers/XmlSaverHelpers.cs | 2 +- .../MediaBrowser.Server.Implementations.csproj | 18 +++++++++--------- .../packages.config | 6 +++--- .../swagger-ui/index.html | 2 +- .../MediaBrowser.ServerApplication.csproj | 18 +++++++++--------- MediaBrowser.ServerApplication/packages.config | 6 +++--- .../MediaBrowser.WebDashboard.csproj | 10 +++++----- MediaBrowser.WebDashboard/packages.config | 4 ++-- 18 files changed, 63 insertions(+), 51 deletions(-) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 7f0521b535..a34f68f35a 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -110,7 +110,8 @@ namespace MediaBrowser.Api { var summary = new GameSystemSummary { - Name = system.Name + Name = system.GameSystemName, + DisplayName = system.Name }; var items = user == null ? system.RecursiveChildren : system.GetRecursiveChildren(user); diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 70e4e8a9a7..c7cca812fa 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -40,17 +40,17 @@ False ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 65ece13acb..b69dbaa67c 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -12,7 +12,6 @@ using ServiceStack.ServiceHost; using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; namespace MediaBrowser.Api.UserLibrary { diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index 49090efc62..c9fec81005 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index ea76984530..a96f2c354b 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -41,7 +41,7 @@ False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll False diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 9ca0ca8a63..4be861cceb 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 874020dd58..1611c55da0 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -37,17 +37,17 @@ - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll diff --git a/MediaBrowser.Common/packages.config b/MediaBrowser.Common/packages.config index 9e97b9e92c..6969b43c54 100644 --- a/MediaBrowser.Common/packages.config +++ b/MediaBrowser.Common/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index 39e95b91de..644405b4d4 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -19,5 +19,11 @@ namespace MediaBrowser.Controller.Entities return Id; } } + + /// + /// Gets or sets the game system. + /// + /// The game system. + public string GameSystemName { get; set; } } } diff --git a/MediaBrowser.Model/Dto/GameSystemSummary.cs b/MediaBrowser.Model/Dto/GameSystemSummary.cs index 79f4e73d52..a9931417ae 100644 --- a/MediaBrowser.Model/Dto/GameSystemSummary.cs +++ b/MediaBrowser.Model/Dto/GameSystemSummary.cs @@ -13,6 +13,12 @@ namespace MediaBrowser.Model.Dto /// The name. public string Name { get; set; } + /// + /// Gets or sets the name. + /// + /// The name. + public string DisplayName { get; set; } + /// /// Gets or sets the game count. /// diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index 990e791fe0..cea7cf9268 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -563,7 +563,7 @@ namespace MediaBrowser.Providers.Savers if (video != null) { - AddChapters(video, builder, itemRepository); + //AddChapters(video, builder, itemRepository); } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index f84c02c1f8..423f27c4a3 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -49,21 +49,21 @@ False ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - + False - ..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.dll + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.dll False ..\packages\ServiceStack.Api.Swagger.3.9.59\lib\net35\ServiceStack.Api.Swagger.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll False @@ -73,13 +73,13 @@ False ..\packages\ServiceStack.Redis.3.9.43\lib\net35\ServiceStack.Redis.dll - + False - ..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.ServiceInterface.dll + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.ServiceInterface.dll False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 14e7ed2f4a..5d94634084 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -7,12 +7,12 @@ - + - + - + \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/swagger-ui/index.html b/MediaBrowser.Server.Implementations/swagger-ui/index.html index 49f983a723..0fcc069596 100644 --- a/MediaBrowser.Server.Implementations/swagger-ui/index.html +++ b/MediaBrowser.Server.Implementations/swagger-ui/index.html @@ -20,7 +20,7 @@ $(function () { window.swaggerUi = new SwaggerUi({ discoveryUrl: "../resources", - apiKey: "special-key", + apiKey:"special-key", dom_id:"swagger-ui-container", supportHeaderParams: false, supportedSubmitMethods: ['get', 'post', 'put'], diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 3dc4faee6e..f19ffe5b01 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -142,17 +142,17 @@ False ..\packages\MediaBrowser.IsoMounting.3.0.56\lib\net45\pfmclrapi.dll - + False - ..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.dll + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll ..\packages\ServiceStack.OrmLite.SqlServer.3.9.44\lib\ServiceStack.OrmLite.SqlServer.dll @@ -160,13 +160,13 @@ ..\packages\ServiceStack.Redis.3.9.44\lib\net35\ServiceStack.Redis.dll - + False - ..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.ServiceInterface.dll + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.ServiceInterface.dll False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll False diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 24f768a9b7..8c1821ca5f 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -6,11 +6,11 @@ - - + + - + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 16cece7597..06f9302382 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -35,17 +35,17 @@ Always - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - + False - ..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll False - ..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 08255ca2f0..25b4f7b47c 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file From 5d837309e43e288fce513d0217c4e62f4ef6c2b4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Sep 2013 13:00:42 -0400 Subject: [PATCH 2/9] added AllGenres filter --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 40 ++++++++++---------- MediaBrowser.Model/Querying/ItemQuery.cs | 6 +++ Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index b69dbaa67c..3437cdd5ab 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -63,6 +63,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Genres { get; set; } + [ApiMember(Name = "AllGenres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string AllGenres { get; set; } + /// /// Limit results to items containing specific studios /// @@ -608,43 +611,42 @@ namespace MediaBrowser.Api.UserLibrary items = items.Where(item => imageTypes.Any(imageType => HasImage(item, imageType))); } - var genres = request.Genres; - // Apply genre filter - if (!string.IsNullOrEmpty(genres)) + if (!string.IsNullOrEmpty(request.Genres)) { - var vals = genres.Split(','); - items = items.Where(f => f.Genres != null && vals.Any(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))); + var vals = request.Genres.Split(','); + items = items.Where(f => vals.Any(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))); } - var studios = request.Studios; - + // Apply genre filter + if (!string.IsNullOrEmpty(request.AllGenres)) + { + var vals = request.AllGenres.Split(','); + items = items.Where(f => vals.All(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))); + } + // Apply studio filter - if (!string.IsNullOrEmpty(studios)) + if (!string.IsNullOrEmpty(request.Studios)) { - var vals = studios.Split(','); - items = items.Where(f => f.Studios != null && vals.Any(v => f.Studios.Contains(v, StringComparer.OrdinalIgnoreCase))); + var vals = request.Studios.Split(','); + items = items.Where(f => vals.Any(v => f.Studios.Contains(v, StringComparer.OrdinalIgnoreCase))); } - var years = request.Years; - // Apply year filter - if (!string.IsNullOrEmpty(years)) + if (!string.IsNullOrEmpty(request.Years)) { - var vals = years.Split(',').Select(int.Parse); + var vals = request.Years.Split(',').Select(int.Parse).ToList(); items = items.Where(f => f.ProductionYear.HasValue && vals.Contains(f.ProductionYear.Value)); } - var personName = request.Person; - // Apply person filter - if (!string.IsNullOrEmpty(personName)) + if (!string.IsNullOrEmpty(request.Person)) { var personTypes = request.PersonTypes; if (string.IsNullOrEmpty(personTypes)) { - items = items.Where(item => item.People != null && item.People.Any(p => string.Equals(p.Name, personName, StringComparison.OrdinalIgnoreCase))); + items = items.Where(item => item.People != null && item.People.Any(p => string.Equals(p.Name, request.Person, StringComparison.OrdinalIgnoreCase))); } else { @@ -653,7 +655,7 @@ namespace MediaBrowser.Api.UserLibrary items = items.Where(item => item.People != null && item.People.Any(p => - p.Name.Equals(personName, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase)))); + p.Name.Equals(request.Person, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase)))); } } diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index 45af17b0f2..69c79104a4 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -92,6 +92,12 @@ namespace MediaBrowser.Model.Querying /// The genres. public string[] Genres { get; set; } + /// + /// Limit results to items containing specific genres + /// + /// The genres. + public string[] AllGenres { get; set; } + /// /// Limit results to items containing specific studios /// diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index fc0650d5ef..1d104c45bc 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.205 + 3.0.206 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 64342cef9a..0670bcacf4 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.205 + 3.0.206 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 40919486ce..f5aa2d4609 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.205 + 3.0.206 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + From 1c7c71075af5f87a00047a56e3cef80fc9791828 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Sep 2013 14:21:55 -0400 Subject: [PATCH 3/9] pass current server version into installation manager to get update list --- MediaBrowser.Api/PackageService.cs | 4 +-- .../Updates/InstallationManager.cs | 25 +++++++++---------- .../Updates/IInstallationManager.cs | 9 ++++--- MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../ScheduledTasks/PluginUpdateTask.cs | 15 ++++++----- .../ApplicationHost.cs | 3 +-- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 563625a544..0c6ee20f79 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Api if (request.PackageType == PackageType.UserInstalled || request.PackageType == PackageType.All) { - result.AddRange(_installationManager.GetAvailablePluginUpdates(false, CancellationToken.None).Result.ToList()); + result.AddRange(_installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToList()); } else if (request.PackageType == PackageType.System || request.PackageType == PackageType.All) @@ -194,7 +194,7 @@ namespace MediaBrowser.Api public void Post(InstallPackage request) { var package = string.IsNullOrEmpty(request.Version) ? - _installationManager.GetLatestCompatibleVersion(request.Name, request.UpdateClass).Result : + _installationManager.GetLatestCompatibleVersion(request.Name, _appHost.ApplicationVersion, request.UpdateClass).Result : _installationManager.GetPackage(request.Name, request.UpdateClass, Version.Parse(request.Version)).Result; if (package == null) diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index 732a108934..e1757afd5a 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -225,9 +225,9 @@ namespace MediaBrowser.Common.Implementations.Updates /// Determines whether [is package version up to date] [the specified package version info]. /// /// The package version info. - /// The application version. + /// The current server version. /// true if [is package version up to date] [the specified package version info]; otherwise, false. - private bool IsPackageVersionUpToDate(PackageVersionInfo packageVersionInfo, Version applicationVersion) + private bool IsPackageVersionUpToDate(PackageVersionInfo packageVersionInfo, Version currentServerVersion) { if (string.IsNullOrEmpty(packageVersionInfo.requiredVersionStr)) { @@ -236,7 +236,7 @@ namespace MediaBrowser.Common.Implementations.Updates Version requiredVersion; - return Version.TryParse(packageVersionInfo.requiredVersionStr, out requiredVersion) && applicationVersion >= requiredVersion; + return Version.TryParse(packageVersionInfo.requiredVersionStr, out requiredVersion) && currentServerVersion >= requiredVersion; } /// @@ -264,13 +264,14 @@ namespace MediaBrowser.Common.Implementations.Updates /// Gets the latest compatible version. /// /// The name. + /// The current server version. /// The classification. /// Task{PackageVersionInfo}. - public async Task GetLatestCompatibleVersion(string name, PackageVersionClass classification = PackageVersionClass.Release) + public async Task GetLatestCompatibleVersion(string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release) { var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false); - return GetLatestCompatibleVersion(packages, name, classification); + return GetLatestCompatibleVersion(packages, name, currentServerVersion, classification); } /// @@ -278,9 +279,10 @@ namespace MediaBrowser.Common.Implementations.Updates /// /// The available packages. /// The name. + /// The current server version. /// The classification. /// PackageVersionInfo. - public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable availablePackages, string name, PackageVersionClass classification = PackageVersionClass.Release) + public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable availablePackages, string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release) { var package = availablePackages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase)); @@ -291,23 +293,20 @@ namespace MediaBrowser.Common.Implementations.Updates return package.versions .OrderByDescending(v => v.version) - .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, _applicationHost.ApplicationVersion)); + .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, currentServerVersion)); } /// /// Gets the available plugin updates. /// + /// The current server version. /// if set to true [with auto update enabled]. /// The cancellation token. /// Task{IEnumerable{PackageVersionInfo}}. - public async Task> GetAvailablePluginUpdates(bool withAutoUpdateEnabled, CancellationToken cancellationToken) + public async Task> GetAvailablePluginUpdates(Version currentServerVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken) { var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - return FilterCatalog(catalog, withAutoUpdateEnabled); - } - protected IEnumerable FilterCatalog(IEnumerable catalog, bool withAutoUpdateEnabled) - { var plugins = _applicationHost.Plugins.ToList(); if (withAutoUpdateEnabled) @@ -320,7 +319,7 @@ namespace MediaBrowser.Common.Implementations.Updates // Figure out what needs to be installed var packages = plugins.Select(p => { - var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Configuration.UpdateClass); + var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, currentServerVersion, p.Configuration.UpdateClass); return latestPluginInfo != null && latestPluginInfo.version != null && latestPluginInfo.version > p.Version ? latestPluginInfo : null; diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index 95eca6e29f..143a90b856 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -76,26 +76,29 @@ namespace MediaBrowser.Common.Updates /// Gets the latest compatible version. /// /// The name. + /// The current server version. /// The classification. /// Task{PackageVersionInfo}. - Task GetLatestCompatibleVersion(string name, PackageVersionClass classification = PackageVersionClass.Release); + Task GetLatestCompatibleVersion(string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release); /// /// Gets the latest compatible version. /// /// The available packages. /// The name. + /// The current server version. /// The classification. /// PackageVersionInfo. - PackageVersionInfo GetLatestCompatibleVersion(IEnumerable availablePackages, string name, PackageVersionClass classification = PackageVersionClass.Release); + PackageVersionInfo GetLatestCompatibleVersion(IEnumerable availablePackages, string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release); /// /// Gets the available plugin updates. /// + /// The current server version. /// if set to true [with auto update enabled]. /// The cancellation token. /// Task{IEnumerable{PackageVersionInfo}}. - Task> GetAvailablePluginUpdates(bool withAutoUpdateEnabled, CancellationToken cancellationToken); + Task> GetAvailablePluginUpdates(Version currentServerVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken); /// /// Installs the package. diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index a724067d5b..e68d4be8e6 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1004,7 +1004,7 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException(); } - var list = new List(10000); + var list = new List(_children.Count); AddRecursiveChildrenInternal(user, includeLinkedChildren, list); diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs index 2936520075..e4f7134d7e 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Common; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.Updates; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; @@ -23,15 +24,13 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks private readonly IInstallationManager _installationManager; - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// The installation manager. - public PluginUpdateTask(ILogger logger, IInstallationManager installationManager) + private readonly IApplicationHost _appHost; + + public PluginUpdateTask(ILogger logger, IInstallationManager installationManager, IApplicationHost appHost) { _logger = logger; _installationManager = installationManager; + _appHost = appHost; } /// @@ -60,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks { progress.Report(0); - var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(true, cancellationToken).ConfigureAwait(false)).ToList(); + var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, true, cancellationToken).ConfigureAwait(false)).ToList(); progress.Report(10); diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 4715258167..2d19260dc2 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -60,7 +60,6 @@ using System.Net.Http; using System.Reflection; using System.Threading; using System.Threading.Tasks; -using System.Windows; namespace MediaBrowser.ServerApplication { @@ -708,7 +707,7 @@ namespace MediaBrowser.ServerApplication { var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, Constants.MbServerPkgName, ConfigurationManager.CommonConfiguration.SystemUpdateLevel); + var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, Constants.MbServerPkgName, ApplicationVersion, ConfigurationManager.CommonConfiguration.SystemUpdateLevel); return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } : new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false }; From 02b34c6393b7cbff9085042f5b1f8e08c38c398e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Sep 2013 14:29:07 -0400 Subject: [PATCH 4/9] fix children null reference --- MediaBrowser.Controller/Entities/Folder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e68d4be8e6..0d91a2e868 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1004,7 +1004,8 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException(); } - var list = new List(_children.Count); + var initialCount = _children == null ? 100 : _children.Count; + var list = new List(initialCount); AddRecursiveChildrenInternal(user, includeLinkedChildren, list); From 831c412ecf8ad5e259f1293ed4655b3a1b2997db Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 Sep 2013 18:42:21 -0400 Subject: [PATCH 5/9] Added IsInstalledOnClient to Game --- MediaBrowser.Api/GamesService.cs | 4 ++- MediaBrowser.Controller/Entities/Game.cs | 6 ++++ .../Providers/BaseItemXmlParser.cs | 36 +++++++++++++++++++ MediaBrowser.Model/Dto/GameSystemSummary.cs | 6 ++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index a34f68f35a..14f5ba3da9 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -118,9 +118,11 @@ namespace MediaBrowser.Api var games = items.OfType().ToList(); + summary.ClientInstalledGameCount = games.Count(i => !i.IsInstalledOnClient); + summary.GameCount = games.Count; - summary.GameFileExtensions = games.Select(i => Path.GetExtension(i.Path)) + summary.GameFileExtensions = games.Where(i => !i.IsInstalledOnClient).Select(i => Path.GetExtension(i.Path)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index ef115c691b..6c15e73038 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -24,6 +24,12 @@ namespace MediaBrowser.Controller.Entities /// The players supported. public int? PlayersSupported { get; set; } + /// + /// Gets or sets a value indicating whether this instance is installed on client. + /// + /// true if this instance is installed on client; otherwise, false. + public bool IsInstalledOnClient { get; set; } + /// /// Gets or sets the game system. /// diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index a7c38408fc..d7336e6a1d 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -139,6 +139,7 @@ namespace MediaBrowser.Controller.Providers break; } + case "CriticRating": { var text = reader.ReadElementContentAsString(); @@ -150,6 +151,7 @@ namespace MediaBrowser.Controller.Providers break; } + case "Budget": { var text = reader.ReadElementContentAsString(); @@ -161,6 +163,7 @@ namespace MediaBrowser.Controller.Providers break; } + case "Revenue": { var text = reader.ReadElementContentAsString(); @@ -172,6 +175,7 @@ namespace MediaBrowser.Controller.Providers break; } + case "SortTitle": { var val = reader.ReadElementContentAsString(); @@ -466,6 +470,7 @@ namespace MediaBrowser.Controller.Providers break; } + case "ReleaseYear": case "ProductionYear": { var val = reader.ReadElementContentAsString(); @@ -555,6 +560,37 @@ namespace MediaBrowser.Controller.Providers } break; + case "Players": + { + var val = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(val)) + { + int num; + // All external meta is saving this as '.' for decimal I believe...but just to be sure + if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num)) + { + var game = item as Game; + if (game != null) + { + game.PlayersSupported = num; + } + } + } + break; + } + case "GameSystem": + { + var val = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(val)) + { + var game = item as Game; + if (game != null) + { + game.GameSystem = val; + } + } + break; + } case "MusicbrainzId": { var mbz = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.Model/Dto/GameSystemSummary.cs b/MediaBrowser.Model/Dto/GameSystemSummary.cs index a9931417ae..1da3bb0acd 100644 --- a/MediaBrowser.Model/Dto/GameSystemSummary.cs +++ b/MediaBrowser.Model/Dto/GameSystemSummary.cs @@ -31,6 +31,12 @@ namespace MediaBrowser.Model.Dto /// The game extensions. public List GameFileExtensions { get; set; } + /// + /// Gets or sets the client installed game count. + /// + /// The client installed game count. + public int ClientInstalledGameCount { get; set; } + /// /// Initializes a new instance of the class. /// From b54240f6798d463d30b1465e376cea748f2d8655 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Sep 2013 10:02:56 -0400 Subject: [PATCH 6/9] fixes #553 - Support locking OfficialRating field --- .../Providers/BaseMetadataProvider.cs | 12 +++++++++ MediaBrowser.Model/Entities/MetadataFields.cs | 6 ++++- .../MediaInfo/FFProbeVideoInfoProvider.cs | 5 +++- .../Movies/MovieDbProvider.cs | 26 +++++++++++-------- .../TV/RemoteSeriesProvider.cs | 14 +++++++++- .../Providers/ProviderManager.cs | 2 +- 6 files changed, 50 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index 39c999e82a..a8dc8788f1 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -202,6 +202,18 @@ namespace MediaBrowser.Controller.Providers return NeedsRefreshInternal(item, data); } + /// + /// Gets a value indicating whether [enforce dont fetch metadata]. + /// + /// true if [enforce dont fetch metadata]; otherwise, false. + public virtual bool EnforceDontFetchMetadata + { + get + { + return true; + } + } + /// /// Needses the refresh internal. /// diff --git a/MediaBrowser.Model/Entities/MetadataFields.cs b/MediaBrowser.Model/Entities/MetadataFields.cs index a432e11248..85f2da31e0 100644 --- a/MediaBrowser.Model/Entities/MetadataFields.cs +++ b/MediaBrowser.Model/Entities/MetadataFields.cs @@ -37,6 +37,10 @@ namespace MediaBrowser.Model.Entities /// /// The runtime /// - Runtime + Runtime, + /// + /// The official rating + /// + OfficialRating } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs index 59c3d75e52..690c9b3ffe 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs @@ -384,7 +384,10 @@ namespace MediaBrowser.Providers.MediaInfo if (!string.IsNullOrWhiteSpace(officialRating)) { - video.OfficialRating = officialRating; + if (!video.LockedFields.Contains(MetadataFields.OfficialRating)) + { + video.OfficialRating = officialRating; + } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 751712c71e..4741008555 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -317,7 +317,7 @@ namespace MediaBrowser.Providers.Movies var boxset = item as BoxSet; if (boxset != null) { - // See if any movies have a collection id already + // See if any movies have a collection id already var collId = boxset.Children.Concat(boxset.GetLinkedChildren()).OfType /// The fields. - [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } /// diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index e62959bee3..fcddd2ca65 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Api /// Fields to return within the items, in addition to basic information /// /// The fields. - [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } /// diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index f92b7da450..eba36d8568 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Api.UserLibrary /// Fields to return within the items, in addition to basic information /// /// The fields. - [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } /// diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 8b0910acc8..71c3d59cd9 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -51,11 +51,6 @@ namespace MediaBrowser.Model.Querying /// HomePageUrl, - /// - /// Child count, recursive child count, etc - /// - ItemCounts, - /// /// The fields that the server supports indexing on /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 99878e2ec4..e5260004a6 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -107,13 +107,10 @@ namespace MediaBrowser.Server.Implementations.Dto .ToArray(); } - if (fields.Contains(ItemFields.ItemCounts)) + var itemByName = item as IItemByName; + if (itemByName != null) { - var itemByName = item as IItemByName; - if (itemByName != null) - { - AttachItemByNameCounts(dto, itemByName, user); - } + AttachItemByNameCounts(dto, itemByName, user); } return dto; @@ -166,18 +163,13 @@ namespace MediaBrowser.Server.Implementations.Dto { if (item.IsFolder) { - var hasItemCounts = fields.Contains(ItemFields.ItemCounts); + var folder = (Folder)item; - if (hasItemCounts || fields.Contains(ItemFields.CumulativeRunTimeTicks)) - { - var folder = (Folder)item; + dto.ChildCount = folder.GetChildren(user, true).Count(); - if (hasItemCounts) - { - dto.ChildCount = folder.GetChildren(user, true).Count(); - } - - SetSpecialCounts(folder, user, dto); + if (!(folder is UserRootFolder)) + { + SetSpecialCounts(folder, user, dto, fields); } } @@ -1068,8 +1060,9 @@ namespace MediaBrowser.Server.Implementations.Dto /// The folder. /// The user. /// The dto. + /// The fields. /// Task. - private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto) + private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields) { var rcentlyAddedItemCount = 0; var recursiveItemCount = 0; @@ -1127,7 +1120,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount; } - if (runtime > 0) + if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks)) { dto.CumulativeRunTimeTicks = runtime; } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs index aa30cee26f..035c0e9dce 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs @@ -356,6 +356,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer try { ProcessRequest(context); + + var url = context.Request.Url.ToString(); + var endPoint = context.Request.RemoteEndPoint; + + LogResponse(context, url, endPoint); + } catch (Exception ex) { @@ -433,9 +439,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer var httpRes = new HttpListenerResponseWrapper(context.Response); var handler = ServiceStackHttpHandlerFactory.GetHandler(httpReq); - var url = context.Request.Url.ToString(); - var endPoint = context.Request.RemoteEndPoint; - var serviceStackHandler = handler as IServiceStackHttpHandler; if (serviceStackHandler != null) @@ -446,7 +449,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer httpReq.OperationName = operationName = restHandler.RestPath.RequestType.Name; } serviceStackHandler.ProcessRequest(httpReq, httpRes, operationName); - LogResponse(context, url, endPoint); return; } @@ -529,7 +531,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { new ClientWebSocket(); - _supportsNativeWebSocket = true; + _supportsNativeWebSocket = false; } catch (PlatformNotSupportedException) { From 946a5c49d060c818cb333095f8f488635a7f5e86 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Sep 2013 11:37:50 -0400 Subject: [PATCH 8/9] #429 - Extract ffmpeg from core product --- ...MediaBrowser.Server.Implementations.csproj | 2 - .../MediaEncoder/MediaEncoder.cs | 232 +----------------- .../ApplicationHost.cs | 15 +- .../Implementations/FFMpegDownloader.cs | 205 ++++++++++++++++ .../ffmpeg20130904.zip.REMOVED.git-id | 0 .../Implementations}/readme.txt | 0 .../MediaBrowser.ServerApplication.csproj | 5 + 7 files changed, 233 insertions(+), 226 deletions(-) create mode 100644 MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs rename {MediaBrowser.Server.Implementations/MediaEncoder => MediaBrowser.ServerApplication/Implementations}/ffmpeg20130904.zip.REMOVED.git-id (100%) rename {MediaBrowser.Server.Implementations/MediaEncoder => MediaBrowser.ServerApplication/Implementations}/readme.txt (100%) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 423f27c4a3..9d2fc8c6b3 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -254,10 +254,8 @@ - - diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs index 5792806d84..b24c9a5cae 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs @@ -1,9 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.MediaInfo; -using MediaBrowser.Common.Net; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; @@ -13,7 +11,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -26,12 +23,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// public class MediaEncoder : IMediaEncoder, IDisposable { - /// - /// Gets or sets the zip client. - /// - /// The zip client. - private readonly IZipClient _zipClient; - /// /// The _logger /// @@ -48,8 +39,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// The json serializer. private readonly IJsonSerializer _jsonSerializer; - private readonly IHttpClient _httpClient; - /// /// The video image resource pool /// @@ -70,50 +59,25 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2); - /// - /// Gets or sets the versioned directory path. - /// - /// The versioned directory path. - private string VersionedDirectoryPath { get; set; } + public string FFMpegPath { get; private set; } - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// The zip client. - /// The app paths. - /// The json serializer. - public MediaEncoder(ILogger logger, IZipClient zipClient, IApplicationPaths appPaths, - IJsonSerializer jsonSerializer, IHttpClient httpClient) + public string FFProbePath { get; private set; } + + public string Version { get; private set; } + + public MediaEncoder(ILogger logger, IApplicationPaths appPaths, + IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version) { _logger = logger; - _zipClient = zipClient; _appPaths = appPaths; _jsonSerializer = jsonSerializer; - _httpClient = httpClient; + Version = version; + FFProbePath = ffProbePath; + FFMpegPath = ffMpegPath; // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); - - Task.Run(() => VersionedDirectoryPath = GetVersionedDirectoryPath()); - } - - /// - /// Gets the media tools path. - /// - /// if set to true [create]. - /// System.String. - private string GetMediaToolsPath(bool create) - { - var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg"); - - if (create && !Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - - return path; } /// @@ -125,182 +89,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder get { return FFMpegPath; } } - /// - /// The _ FF MPEG path - /// - private string _FFMpegPath; - - /// - /// Gets the path to ffmpeg.exe - /// - /// The FF MPEG path. - public string FFMpegPath - { - get { return _FFMpegPath ?? (_FFMpegPath = Path.Combine(VersionedDirectoryPath, "ffmpeg.exe")); } - } - - /// - /// The _ FF probe path - /// - private string _FFProbePath; - - /// - /// Gets the path to ffprobe.exe - /// - /// The FF probe path. - private string FFProbePath - { - get { return _FFProbePath ?? (_FFProbePath = Path.Combine(VersionedDirectoryPath, "ffprobe.exe")); } - } - - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get { return Path.GetFileNameWithoutExtension(VersionedDirectoryPath); } - } - - /// - /// Gets the versioned directory path. - /// - /// System.String. - private string GetVersionedDirectoryPath() - { - var assembly = GetType().Assembly; - - var prefix = GetType().Namespace + "."; - - var srch = prefix + "ffmpeg"; - - var resource = assembly.GetManifestResourceNames().First(r => r.StartsWith(srch)); - - var filename = - resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length); - - var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), - Path.GetFileNameWithoutExtension(filename)); - - if (!Directory.Exists(versionedDirectoryPath)) - { - Directory.CreateDirectory(versionedDirectoryPath); - } - - ExtractTools(assembly, resource, versionedDirectoryPath); - - return versionedDirectoryPath; - } - - /// - /// Extracts the tools. - /// - /// The assembly. - /// The zip file resource path. - /// The target path. - private async void ExtractTools(Assembly assembly, string zipFileResourcePath, string targetPath) - { - using (var resourceStream = assembly.GetManifestResourceStream(zipFileResourcePath)) - { - _zipClient.ExtractAll(resourceStream, targetPath, false); - } - - try - { - await DownloadFonts(targetPath).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting ffmpeg font files", ex); - } - } - - private const string FontUrl = "https://www.dropbox.com/s/9nb76tybcsw5xrk/ARIALUNI.zip?dl=1"; - - /// - /// Extracts the fonts. - /// - /// The target path. - private async Task DownloadFonts(string targetPath) - { - var fontsDirectory = Path.Combine(targetPath, "fonts"); - - if (!Directory.Exists(fontsDirectory)) - { - Directory.CreateDirectory(fontsDirectory); - } - - const string fontFilename = "ARIALUNI.TTF"; - - var fontFile = Path.Combine(fontsDirectory, fontFilename); - - if (!File.Exists(fontFile)) - { - await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false); - } - - await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); - } - - private async Task DownloadFontFile(string fontsDirectory, string fontFilename) - { - var existingFile = Directory - .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories) - .FirstOrDefault(); - - if (existingFile != null) - { - try - { - File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true); - return; - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error copying file", ex); - } - } - - var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions - { - Url = FontUrl, - Progress = new Progress() - }); - - _zipClient.ExtractAll(tempFile, fontsDirectory, true); - - try - { - File.Delete(tempFile); - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error deleting temp file {0}", ex, tempFile); - } - } - - private async Task WriteFontConfigFile(string fontsDirectory) - { - const string fontConfigFilename = "fonts.conf"; - var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); - - if (!File.Exists(fontConfigFile)) - { - var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); - - var bytes = Encoding.UTF8.GetBytes(contents); - - using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write, - FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, - FileOptions.Asynchronous)) - { - await fileStream.WriteAsync(bytes, 0, bytes.Length); - } - } - } - /// /// Gets the media info. /// diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 2d19260dc2..5cae997850 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -284,8 +284,7 @@ namespace MediaBrowser.ServerApplication RegisterSingleInstance(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager)); - MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ZipClient, ApplicationPaths, JsonSerializer, HttpClient); - RegisterSingleInstance(MediaEncoder); + await RegisterMediaEncoder().ConfigureAwait(false); var clientConnectionManager = new SessionManager(UserDataRepository, ServerConfigurationManager, Logger, UserRepository); RegisterSingleInstance(clientConnectionManager); @@ -316,6 +315,18 @@ namespace MediaBrowser.ServerApplication SetKernelProperties(); } + /// + /// Registers the media encoder. + /// + /// Task. + private async Task RegisterMediaEncoder() + { + var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient).GetFFMpegInfo().ConfigureAwait(false); + + MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.Path, info.ProbePath, info.Version); + RegisterSingleInstance(MediaEncoder); + } + /// /// Sets the kernel properties. /// diff --git a/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs new file mode 100644 index 0000000000..7fd0acddd2 --- /dev/null +++ b/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs @@ -0,0 +1,205 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.Implementations +{ + public class FFMpegDownloader + { + private readonly IZipClient _zipClient; + private readonly IHttpClient _httpClient; + private readonly IApplicationPaths _appPaths; + private readonly ILogger _logger; + + public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient) + { + _logger = logger; + _appPaths = appPaths; + _httpClient = httpClient; + _zipClient = zipClient; + } + + public async Task GetFFMpegInfo() + { + var assembly = GetType().Assembly; + + var prefix = GetType().Namespace + "."; + + var srch = prefix + "ffmpeg"; + + var resource = assembly.GetManifestResourceNames().First(r => r.StartsWith(srch)); + + var filename = + resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length); + + var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), + Path.GetFileNameWithoutExtension(filename)); + + if (!Directory.Exists(versionedDirectoryPath)) + { + Directory.CreateDirectory(versionedDirectoryPath); + } + + await ExtractTools(assembly, resource, versionedDirectoryPath).ConfigureAwait(false); + + return new FFMpegInfo + { + ProbePath = Path.Combine(versionedDirectoryPath, "ffprobe.exe"), + Path = Path.Combine(versionedDirectoryPath, "ffmpeg.exe"), + Version = Path.GetFileNameWithoutExtension(versionedDirectoryPath) + }; + } + + /// + /// Extracts the tools. + /// + /// The assembly. + /// The zip file resource path. + /// The target path. + private async Task ExtractTools(Assembly assembly, string zipFileResourcePath, string targetPath) + { + using (var resourceStream = assembly.GetManifestResourceStream(zipFileResourcePath)) + { + _zipClient.ExtractAll(resourceStream, targetPath, false); + } + + try + { + await DownloadFonts(targetPath).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting ffmpeg font files", ex); + } + } + + private const string FontUrl = "https://www.dropbox.com/s/9nb76tybcsw5xrk/ARIALUNI.zip?dl=1"; + + /// + /// Extracts the fonts. + /// + /// The target path. + private async Task DownloadFonts(string targetPath) + { + var fontsDirectory = Path.Combine(targetPath, "fonts"); + + if (!Directory.Exists(fontsDirectory)) + { + Directory.CreateDirectory(fontsDirectory); + } + + const string fontFilename = "ARIALUNI.TTF"; + + var fontFile = Path.Combine(fontsDirectory, fontFilename); + + if (!File.Exists(fontFile)) + { + await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false); + } + + await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); + } + + /// + /// Downloads the font file. + /// + /// The fonts directory. + /// The font filename. + /// Task. + private async Task DownloadFontFile(string fontsDirectory, string fontFilename) + { + var existingFile = Directory + .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories) + .FirstOrDefault(); + + if (existingFile != null) + { + try + { + File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true); + return; + } + catch (IOException ex) + { + // Log this, but don't let it fail the operation + _logger.ErrorException("Error copying file", ex); + } + } + + var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions + { + Url = FontUrl, + Progress = new Progress() + }); + + _zipClient.ExtractAll(tempFile, fontsDirectory, true); + + try + { + File.Delete(tempFile); + } + catch (IOException ex) + { + // Log this, but don't let it fail the operation + _logger.ErrorException("Error deleting temp file {0}", ex, tempFile); + } + } + + /// + /// Writes the font config file. + /// + /// The fonts directory. + /// Task. + private async Task WriteFontConfigFile(string fontsDirectory) + { + const string fontConfigFilename = "fonts.conf"; + var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); + + if (!File.Exists(fontConfigFile)) + { + var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); + + var bytes = Encoding.UTF8.GetBytes(contents); + + using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write, + FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, + FileOptions.Asynchronous)) + { + await fileStream.WriteAsync(bytes, 0, bytes.Length); + } + } + } + + /// + /// Gets the media tools path. + /// + /// if set to true [create]. + /// System.String. + private string GetMediaToolsPath(bool create) + { + var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg"); + + if (create && !Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + return path; + } + } + + public class FFMpegInfo + { + public string Path { get; set; } + public string ProbePath { get; set; } + public string Version { get; set; } + } +} diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/ffmpeg20130904.zip.REMOVED.git-id b/MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id similarity index 100% rename from MediaBrowser.Server.Implementations/MediaEncoder/ffmpeg20130904.zip.REMOVED.git-id rename to MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/readme.txt b/MediaBrowser.ServerApplication/Implementations/readme.txt similarity index 100% rename from MediaBrowser.Server.Implementations/MediaEncoder/readme.txt rename to MediaBrowser.ServerApplication/Implementations/readme.txt diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index f19ffe5b01..043d5c18f1 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -210,6 +210,7 @@ + Component @@ -277,6 +278,7 @@ Resources.Designer.cs + SettingsSingleFileGenerator @@ -388,6 +390,9 @@ + + + if $(ConfigurationName) == Release ( From cacba5ca11d600ed9d496c566807be92b228de7e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Sep 2013 11:40:47 -0400 Subject: [PATCH 9/9] removed test code --- MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs index 035c0e9dce..f6547dec17 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs @@ -531,7 +531,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { new ClientWebSocket(); - _supportsNativeWebSocket = false; + _supportsNativeWebSocket = true; } catch (PlatformNotSupportedException) {