From aa66b9cf3d0f120d7926a3be198830f6d06d255e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 01:52:32 -0400 Subject: [PATCH 001/220] restore version --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index a452789cf2..c7790e6af7 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.5986")] +[assembly: AssemblyVersion("3.1.72")] From 90127597690f98e95bb3bfb59a6cd0315f64e14b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 01:59:21 -0400 Subject: [PATCH 002/220] 3.0.5990 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index a452789cf2..c122e6db75 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.5986")] +[assembly: AssemblyVersion("3.0.5990")] From 00b80a33c15eddb22ef7ede348309d8dc5034eca Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 13:59:14 -0400 Subject: [PATCH 003/220] fix merge conflict --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index c7790e6af7..d996b5e97d 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.72")] +[assembly: AssemblyVersion("3.1.*")] +//[assembly: AssemblyVersion("3.0.5986")] From af8aec7365c3c726f174026a28083fb77c1a4005 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 13:59:56 -0400 Subject: [PATCH 004/220] 3.1.73 --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d996b5e97d..660e04d022 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.1.*")] -//[assembly: AssemblyVersion("3.0.5986")] +//[assembly: AssemblyVersion("3.1.*")] +[assembly: AssemblyVersion("3.1.73")] From 821d6731113d63dd340b8b7f45e6c1698e005393 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 16:47:35 -0400 Subject: [PATCH 005/220] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index c122e6db75..660e04d022 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.5990")] +[assembly: AssemblyVersion("3.1.73")] From f71e88f748fe3aba928d8a845286f3b89278075c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jul 2016 16:48:46 -0400 Subject: [PATCH 006/220] 3.0.5991 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 660e04d022..108a16bf44 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.73")] +[assembly: AssemblyVersion("3.0.5991")] From a3fc9e38461114eefc34fbe0063f8fd5e719c9a4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jul 2016 02:18:48 -0400 Subject: [PATCH 007/220] 3.1.74 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 660e04d022..89e4bfd4fa 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.73")] +[assembly: AssemblyVersion("3.1.74")] From 1bc0c1481e325328a5825ce7f440ed1ac02dd9d5 Mon Sep 17 00:00:00 2001 From: YounJae Rho Date: Sat, 23 Jul 2016 07:12:26 -0400 Subject: [PATCH 008/220] fix dlna update profile --- MediaBrowser.Api/Dlna/DlnaService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/Dlna/DlnaService.cs b/MediaBrowser.Api/Dlna/DlnaService.cs index b6c4f5dfba..92ef8722ed 100644 --- a/MediaBrowser.Api/Dlna/DlnaService.cs +++ b/MediaBrowser.Api/Dlna/DlnaService.cs @@ -31,11 +31,11 @@ namespace MediaBrowser.Api.Dlna public string Id { get; set; } } - [Route("/Dlna/Profiles/{ProfileId}", "POST", Summary = "Updates a profile")] + [Route("/Dlna/Profiles/{Id}", "POST", Summary = "Updates a profile")] public class UpdateProfile : DeviceProfile, IReturnVoid { - [ApiMember(Name = "ProfileId", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string ProfileId { get; set; } + [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } } [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")] From a0c310e0f3abdd6bbe8ab27218ac2bde6609818d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jul 2016 16:06:12 -0400 Subject: [PATCH 009/220] 3.1.75 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 89e4bfd4fa..17087a0981 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.74")] +[assembly: AssemblyVersion("3.1.75")] From d661f690f58cd05be86843d2c7c8a2984c66c2f6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jul 2016 16:12:52 -0400 Subject: [PATCH 010/220] fix merge conflicts --- MediaBrowser.Api/Dlna/DlnaService.cs | 4 +--- SharedVersion.cs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Api/Dlna/DlnaService.cs b/MediaBrowser.Api/Dlna/DlnaService.cs index 92ef8722ed..dd4b59b920 100644 --- a/MediaBrowser.Api/Dlna/DlnaService.cs +++ b/MediaBrowser.Api/Dlna/DlnaService.cs @@ -34,8 +34,6 @@ namespace MediaBrowser.Api.Dlna [Route("/Dlna/Profiles/{Id}", "POST", Summary = "Updates a profile")] public class UpdateProfile : DeviceProfile, IReturnVoid { - [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string Id { get; set; } } [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")] @@ -89,4 +87,4 @@ namespace MediaBrowser.Api.Dlna _dlnaManager.CreateProfile(request); } } -} +} \ No newline at end of file diff --git a/SharedVersion.cs b/SharedVersion.cs index 108a16bf44..17087a0981 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.5991")] +[assembly: AssemblyVersion("3.1.75")] From 677709f420b5f62046ba1aecb47418735596c07e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jul 2016 16:13:49 -0400 Subject: [PATCH 011/220] 3.0.6000 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 17087a0981..651eaf4380 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.75")] +[assembly: AssemblyVersion("3.0.6000")] From d416bdfbb1186afb23765a5530ef9d0b5bf1c09d Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 23 Jul 2016 16:42:21 -0400 Subject: [PATCH 012/220] update mac project --- .../Emby.Server.Mac.csproj | 3058 ++--------------- 1 file changed, 377 insertions(+), 2681 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index d80bec7d8f..4ada5df68c 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -711,9 +711,6 @@ Resources\dashboard-ui\bower_components\Sortable\Sortable.html - - Resources\dashboard-ui\bower_components\Sortable\Sortable.js - Resources\dashboard-ui\bower_components\Sortable\Sortable.min.js @@ -741,132 +738,6 @@ Resources\dashboard-ui\bower_components\Sortable\react-sortable-mixin.js - - Resources\dashboard-ui\bower_components\Sortable\meteor\.versions - - - Resources\dashboard-ui\bower_components\Sortable\meteor\README.md - - - Resources\dashboard-ui\bower_components\Sortable\meteor\methods-client.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\methods-server.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\package.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\publish.sh - - - Resources\dashboard-ui\bower_components\Sortable\meteor\reactivize.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\runtests.bat - - - Resources\dashboard-ui\bower_components\Sortable\meteor\runtests.sh - - - Resources\dashboard-ui\bower_components\Sortable\meteor\template.html - - - Resources\dashboard-ui\bower_components\Sortable\meteor\test.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\README.md - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\model.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\run.bat - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\run.sh - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\.finished-upgraders - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\.gitignore - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\.id - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\packages - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\platforms - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\release - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\.meteor\versions - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\client\define-object-type.css - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\client\define-object-type.html - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\client\define-object-type.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\server\fixtures.js - - - Resources\dashboard-ui\bower_components\Sortable\meteor\example\server\sortable-collections.js - - - Resources\dashboard-ui\bower_components\Sortable\st\app.css - - - Resources\dashboard-ui\bower_components\Sortable\st\app.js - - - Resources\dashboard-ui\bower_components\Sortable\st\face-01.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-02.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-03.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-04.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-05.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-06.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-07.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-08.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\face-09.jpg - - - Resources\dashboard-ui\bower_components\Sortable\st\logo.png - - - Resources\dashboard-ui\bower_components\Sortable\st\og-image.png - - - Resources\dashboard-ui\bower_components\Sortable\st\iframe\frame.html - - - Resources\dashboard-ui\bower_components\Sortable\st\iframe\index.html - Resources\dashboard-ui\bower_components\Swiper\.bower.json @@ -891,144 +762,12 @@ Resources\dashboard-ui\bower_components\Swiper\package.js - - Resources\dashboard-ui\bower_components\Swiper\dist\css\swiper.css - Resources\dashboard-ui\bower_components\Swiper\dist\css\swiper.min.css - - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.jquery.js - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.jquery.min.js - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.jquery.umd.js - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.jquery.umd.min.js - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.js - Resources\dashboard-ui\bower_components\Swiper\dist\js\swiper.min.js - - Resources\dashboard-ui\bower_components\Swiper\dist\js\maps\swiper.jquery.min.js.map - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\maps\swiper.jquery.umd.min.js.map - - - Resources\dashboard-ui\bower_components\Swiper\dist\js\maps\swiper.min.js.map - - - Resources\dashboard-ui\bower_components\Swiper\src\js\a11y.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\amd.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\controller.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\core.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\dom-plugins.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\dom.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\effects.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\emitter.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\get-dom-lib.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\get-jquery.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\hashnav.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\init.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\keyboard.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\lazy-load.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\mousewheel.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\parallax.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\plugins.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\scrollbar.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\swiper-intro-f7.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\swiper-intro.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\swiper-outro.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\swiper-proto.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\wrap-end-umd.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\wrap-end.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\wrap-start-umd.js - - - Resources\dashboard-ui\bower_components\Swiper\src\js\wrap-start.js - - - Resources\dashboard-ui\bower_components\Swiper\src\less\core.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\effects.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\mixins.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\navigation-f7.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\navigation.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\preloader-f7.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\preloader.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\scrollbar.less - - - Resources\dashboard-ui\bower_components\Swiper\src\less\swiper.less - Resources\dashboard-ui\bower_components\cryptojslib\.bower.json @@ -1251,72 +990,6 @@ Resources\dashboard-ui\bower_components\cryptojslib\components\x64-core.js - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\aes.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-md5.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-ripemd160.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha1.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha224.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha256.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha3.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha384.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\hmac-sha512.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\md5.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\pbkdf2.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\rabbit-legacy.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\rabbit.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\rc4.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\ripemd160.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha1.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha224.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha256.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha3.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha384.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\sha512.js - - - Resources\dashboard-ui\bower_components\cryptojslib\rollups\tripledes.js - Resources\dashboard-ui\bower_components\emby-apiclient\.bower.json @@ -1374,9 +1047,6 @@ Resources\dashboard-ui\bower_components\emby-apiclient\sync\serversync.js - - Resources\dashboard-ui\bower_components\emby-collapsible\emby-collapsible.html - Resources\dashboard-ui\bower_components\emby-icons\emby-icons.html @@ -1407,6 +1077,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\datetime.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\dom.js + Resources\dashboard-ui\bower_components\emby-webcomponents\fetchhelper.js @@ -1422,6 +1095,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\globalize.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\inputmanager.js + Resources\dashboard-ui\bower_components\emby-webcomponents\itemcontextmenu.js @@ -1431,12 +1107,18 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\layoutmanager.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\librarychangednotifications.js + Resources\dashboard-ui\bower_components\emby-webcomponents\multidownload.js Resources\dashboard-ui\bower_components\emby-webcomponents\objectassign.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\playmenu.js + Resources\dashboard-ui\bower_components\emby-webcomponents\qualityoptions.js @@ -1458,9 +1140,6 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\shortcuts.js - - Resources\dashboard-ui\bower_components\emby-webcomponents\usersettings.js - Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js @@ -1497,6 +1176,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\dialog\dialog.js + Resources\dashboard-ui\bower_components\emby-webcomponents\dialoghelper\dialoghelper.css @@ -1530,6 +1212,15 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\emby-input\emby-input.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-itemscontainer\emby-itemscontainer.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-radio\emby-radio.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-radio\emby-radio.js + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-select\emby-select.css @@ -1764,6 +1455,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\input\api.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\itemhovermenu\itemhovermenu.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\itemhovermenu\itemhovermenu.js + Resources\dashboard-ui\bower_components\emby-webcomponents\listview\listview.css @@ -1797,6 +1494,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\mediainfo\rotten.png + + Resources\dashboard-ui\bower_components\emby-webcomponents\multiselect\multiselect.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\multiselect\multiselect.js + Resources\dashboard-ui\bower_components\emby-webcomponents\page.js\page.js @@ -1839,6 +1542,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\require\requiretext.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\scroller\smoothscroller.js + Resources\dashboard-ui\bower_components\emby-webcomponents\sharing\sharingmanager.js @@ -1890,6 +1596,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\strings\es-MX.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\fr.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\kk.json @@ -1908,6 +1617,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ru.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\sv.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\zh-TW.json + Resources\dashboard-ui\bower_components\emby-webcomponents\subtitleeditor\subtitleeditor.css @@ -1923,6 +1638,18 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\toast\toast.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\userdatabuttons\userdatabuttons.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\userdatabuttons\userdatabuttons.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\usersettings\usersettings.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\usersettings\usersettingsbuilder.js + Resources\dashboard-ui\bower_components\emby-webcomponents\viewmanager\viewcontainer-lite.css @@ -1932,6 +1659,54 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\viewmanager\viewmanager.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\Readme.md + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\grammarprocessor.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\voice.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\voicecommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\voicedialog.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\voiceprocessor.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\voicereceiver.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\controlcommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\disablecommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\enablecommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\playcommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\searchcommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\showcommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\commands\togglecommands.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\grammar\en-US.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\voice\grammar\grammar.json + Resources\dashboard-ui\bower_components\fetch\.bower.json @@ -1974,48 +1749,6 @@ Resources\dashboard-ui\bower_components\fingerprintjs2\dist\fingerprint2.min.js - - Resources\dashboard-ui\bower_components\fingerprintjs2\flash\FontList.as - - - Resources\dashboard-ui\bower_components\fingerprintjs2\flash\Makefile - - - Resources\dashboard-ui\bower_components\fingerprintjs2\flash\compiled\FontList.swf - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\phantomjs-testrunner.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\phantomjs.runner.sh - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\spec_runner.html - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\specs.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\boot.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\jasmine-html.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\jasmine-matchers.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\jasmine.css - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\jasmine.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\jasmine_favicon.png - - - Resources\dashboard-ui\bower_components\fingerprintjs2\specs\lib\jasmine-2.3.4\terminal.js - Resources\dashboard-ui\bower_components\font-roboto\.bower.json @@ -2118,162 +1851,9 @@ Resources\dashboard-ui\bower_components\hls.js\package.json - - Resources\dashboard-ui\bower_components\hls.js\demo\benchmark.html - - - Resources\dashboard-ui\bower_components\hls.js\demo\canvas.js - - - Resources\dashboard-ui\bower_components\hls.js\demo\index.html - - - Resources\dashboard-ui\bower_components\hls.js\demo\jsonpack.js - - - Resources\dashboard-ui\bower_components\hls.js\demo\metrics.html - - - Resources\dashboard-ui\bower_components\hls.js\demo\metrics.js - - - Resources\dashboard-ui\bower_components\hls.js\dist\hls.js - - - Resources\dashboard-ui\bower_components\hls.js\dist\hls.js.map - Resources\dashboard-ui\bower_components\hls.js\dist\hls.min.js - - Resources\dashboard-ui\bower_components\hls.js\misc\mp4-inspector.js - - - Resources\dashboard-ui\bower_components\hls.js\misc\sync_gh.sh - - - Resources\dashboard-ui\bower_components\hls.js\src\errors.js - - - Resources\dashboard-ui\bower_components\hls.js\src\event-handler.js - - - Resources\dashboard-ui\bower_components\hls.js\src\events.js - - - Resources\dashboard-ui\bower_components\hls.js\src\hls.js - - - Resources\dashboard-ui\bower_components\hls.js\src\index.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\abr-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\buffer-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\cap-level-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\ewma-bandwidth-estimator.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\fps-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\level-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\stream-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\controller\timeline-controller.js - - - Resources\dashboard-ui\bower_components\hls.js\src\crypt\aes.js - - - Resources\dashboard-ui\bower_components\hls.js\src\crypt\aes128-decrypter.js - - - Resources\dashboard-ui\bower_components\hls.js\src\crypt\decrypter.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\aacdemuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\adts.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\demuxer-inline.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\demuxer-worker.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\demuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\exp-golomb.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\id3.js - - - Resources\dashboard-ui\bower_components\hls.js\src\demux\tsdemuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\helper\buffer-helper.js - - - Resources\dashboard-ui\bower_components\hls.js\src\helper\level-helper.js - - - Resources\dashboard-ui\bower_components\hls.js\src\loader\fragment-loader.js - - - Resources\dashboard-ui\bower_components\hls.js\src\loader\key-loader.js - - - Resources\dashboard-ui\bower_components\hls.js\src\loader\playlist-loader.js - - - Resources\dashboard-ui\bower_components\hls.js\src\remux\dummy-remuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\remux\mp4-generator.js - - - Resources\dashboard-ui\bower_components\hls.js\src\remux\mp4-remuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\remux\passthrough-remuxer.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\attr-list.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\binary-search.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\cea-708-interpreter.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\ewma.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\hex.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\logger.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\url.js - - - Resources\dashboard-ui\bower_components\hls.js\src\utils\xhr-loader.js - Resources\dashboard-ui\bower_components\howler.js\.bower.json @@ -2289,9 +1869,6 @@ Resources\dashboard-ui\bower_components\howler.js\bower.json - - Resources\dashboard-ui\bower_components\howler.js\howler.js - Resources\dashboard-ui\bower_components\howler.js\howler.min.js @@ -2322,6 +1899,9 @@ Resources\dashboard-ui\bower_components\iron-a11y-announcer\iron-a11y-announcer.html + + Resources\dashboard-ui\bower_components\iron-a11y-announcer\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\iron-a11y-announcer\demo\index.html @@ -2400,6 +1980,9 @@ Resources\dashboard-ui\bower_components\iron-autogrow-textarea\iron-autogrow-textarea.html + + Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\iron-autogrow-textarea\demo\index.html @@ -2484,6 +2067,9 @@ Resources\dashboard-ui\bower_components\iron-checked-element-behavior\iron-checked-element-behavior.html + + Resources\dashboard-ui\bower_components\iron-checked-element-behavior\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\iron-checked-element-behavior\demo\index.html @@ -2499,36 +2085,6 @@ Resources\dashboard-ui\bower_components\iron-checked-element-behavior\test\simple-checkbox.html - - Resources\dashboard-ui\bower_components\iron-collapse\.gitignore - - - Resources\dashboard-ui\bower_components\iron-collapse\README.md - - - Resources\dashboard-ui\bower_components\iron-collapse\bower.json - - - Resources\dashboard-ui\bower_components\iron-collapse\hero.svg - - - Resources\dashboard-ui\bower_components\iron-collapse\index.html - - - Resources\dashboard-ui\bower_components\iron-collapse\iron-collapse.html - - - Resources\dashboard-ui\bower_components\iron-collapse\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-collapse\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-collapse\test\horizontal.html - - - Resources\dashboard-ui\bower_components\iron-collapse\test\index.html - Resources\dashboard-ui\bower_components\iron-demo-helpers\.bower.json @@ -2691,6 +2247,9 @@ Resources\dashboard-ui\bower_components\iron-icon\iron-icon.html + + Resources\dashboard-ui\bower_components\iron-icon\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\iron-icon\demo\async.html @@ -2904,60 +2463,6 @@ Resources\dashboard-ui\bower_components\iron-location\test\redirection.html - - Resources\dashboard-ui\bower_components\iron-menu-behavior\.bower.json - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\.gitignore - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\README.md - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\bower.json - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\index.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\iron-menu-behavior.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\iron-menubar-behavior.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\demo\simple-menu.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\demo\simple-menubar.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\test\index.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\test\iron-menu-behavior.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\test\iron-menubar-behavior.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\test\test-menu.html - - - Resources\dashboard-ui\bower_components\iron-menu-behavior\test\test-menubar.html - Resources\dashboard-ui\bower_components\iron-meta\.bower.json @@ -2997,59 +2502,20 @@ Resources\dashboard-ui\bower_components\iron-meta\test\iron-meta.html - - Resources\dashboard-ui\bower_components\iron-pages\.bower.json - - - Resources\dashboard-ui\bower_components\iron-pages\.gitignore + + Resources\dashboard-ui\bower_components\iron-range-behavior\.bower.json - - Resources\dashboard-ui\bower_components\iron-pages\.travis.yml + + Resources\dashboard-ui\bower_components\iron-range-behavior\.gitignore - - Resources\dashboard-ui\bower_components\iron-pages\CONTRIBUTING.md + + Resources\dashboard-ui\bower_components\iron-range-behavior\.travis.yml - - Resources\dashboard-ui\bower_components\iron-pages\README.md + + Resources\dashboard-ui\bower_components\iron-range-behavior\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\iron-pages\bower.json - - - Resources\dashboard-ui\bower_components\iron-pages\hero.svg - - - Resources\dashboard-ui\bower_components\iron-pages\index.html - - - Resources\dashboard-ui\bower_components\iron-pages\iron-pages.html - - - Resources\dashboard-ui\bower_components\iron-pages\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-pages\test\attr-for-selected.html - - - Resources\dashboard-ui\bower_components\iron-pages\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-pages\test\index.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.bower.json - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.gitignore - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-range-behavior\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-range-behavior\README.md + + Resources\dashboard-ui\bower_components\iron-range-behavior\README.md Resources\dashboard-ui\bower_components\iron-range-behavior\bower.json @@ -3075,213 +2541,6 @@ Resources\dashboard-ui\bower_components\iron-range-behavior\test\x-progressbar.html - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\.bower.json - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\README.md - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\bower.json - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\index.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\iron-resizable-behavior.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\demo\src\x-app.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\test\index.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\test\iron-resizable-behavior.html - - - Resources\dashboard-ui\bower_components\iron-resizable-behavior\test\test-elements.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\.bower.json - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\.gitignore - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\README.md - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\bower.json - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\index.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\iron-scroll-target-behavior.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\demo\document.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\demo\scrolling-region.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\demo\x-scrollable.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\test\index.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\test\x-nested-scrollable.html - - - Resources\dashboard-ui\bower_components\iron-scroll-target-behavior\test\x-scrollable.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\.bower.json - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\.gitignore - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\README.md - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\bower.json - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\index.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\iron-scroll-threshold.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\demo\document.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\demo\sample-content.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\demo\scrolling-region-decoupled.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\demo\scrolling-region.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-scroll-threshold\test\index.html - - - Resources\dashboard-ui\bower_components\iron-selector\.bower.json - - - Resources\dashboard-ui\bower_components\iron-selector\.gitignore - - - Resources\dashboard-ui\bower_components\iron-selector\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-selector\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-selector\README.md - - - Resources\dashboard-ui\bower_components\iron-selector\bower.json - - - Resources\dashboard-ui\bower_components\iron-selector\index.html - - - Resources\dashboard-ui\bower_components\iron-selector\iron-multi-selectable.html - - - Resources\dashboard-ui\bower_components\iron-selector\iron-selectable.html - - - Resources\dashboard-ui\bower_components\iron-selector\iron-selection.html - - - Resources\dashboard-ui\bower_components\iron-selector\iron-selector.html - - - Resources\dashboard-ui\bower_components\iron-selector\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-selector\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\activate-event.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\attr-for-selected-elements.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\attr-for-selected.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\content-element.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\content.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\excluded-local-names.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\index.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\multi.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\next-previous.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\numeric-ids.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\selected-attribute.html - - - Resources\dashboard-ui\bower_components\iron-selector\test\template-repeat.html - Resources\dashboard-ui\bower_components\iron-validatable-behavior\.bower.json @@ -3399,8 +2658,8 @@ Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map - - Resources\dashboard-ui\bower_components\jquery\src\.jshintrc + + Resources\dashboard-ui\bower_components\jquery\src\.eslintrc Resources\dashboard-ui\bower_components\jquery\src\ajax.js @@ -3513,6 +2772,9 @@ Resources\dashboard-ui\bower_components\jquery\src\core\ready.js + + Resources\dashboard-ui\bower_components\jquery\src\core\readyException.js + Resources\dashboard-ui\bower_components\jquery\src\core\support.js @@ -3744,102 +3006,12 @@ Resources\dashboard-ui\bower_components\libjass\libjass.css - - Resources\dashboard-ui\bower_components\libjass\libjass.js - - - Resources\dashboard-ui\bower_components\libjass\libjass.js.map - Resources\dashboard-ui\bower_components\libjass\libjass.min.js - - Resources\dashboard-ui\bower_components\libjass\libjass.min.js.map - Resources\dashboard-ui\bower_components\libjass\package.json - - Resources\dashboard-ui\bower_components\marked\.bower.json - - - Resources\dashboard-ui\bower_components\marked\Gulpfile.js - - - Resources\dashboard-ui\bower_components\marked\LICENSE - - - Resources\dashboard-ui\bower_components\marked\Makefile - - - Resources\dashboard-ui\bower_components\marked\README.md - - - Resources\dashboard-ui\bower_components\marked\bower.json - - - Resources\dashboard-ui\bower_components\marked\component.json - - - Resources\dashboard-ui\bower_components\marked\index.js - - - Resources\dashboard-ui\bower_components\marked\marked.min.js - - - Resources\dashboard-ui\bower_components\marked\package.json - - - Resources\dashboard-ui\bower_components\marked\doc\broken.md - - - Resources\dashboard-ui\bower_components\marked\doc\todo.md - - - Resources\dashboard-ui\bower_components\marked\lib\marked.js - - - Resources\dashboard-ui\bower_components\marked\man\marked.1 - - - Resources\dashboard-ui\bower_components\marked-element\.bower.json - - - Resources\dashboard-ui\bower_components\marked-element\.gitignore - - - Resources\dashboard-ui\bower_components\marked-element\.travis.yml - - - Resources\dashboard-ui\bower_components\marked-element\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\marked-element\README.md - - - Resources\dashboard-ui\bower_components\marked-element\bower.json - - - Resources\dashboard-ui\bower_components\marked-element\hero.svg - - - Resources\dashboard-ui\bower_components\marked-element\index.html - - - Resources\dashboard-ui\bower_components\marked-element\marked-element.html - - - Resources\dashboard-ui\bower_components\marked-element\marked-import.html - - - Resources\dashboard-ui\bower_components\marked-element\demo\index.html - - - Resources\dashboard-ui\bower_components\marked-element\test\index.html - - - Resources\dashboard-ui\bower_components\marked-element\test\marked-element.html - Resources\dashboard-ui\bower_components\native-promise-only\.bower.json @@ -3864,216 +3036,6 @@ Resources\dashboard-ui\bower_components\native-promise-only\lib\npo.src.js - - Resources\dashboard-ui\bower_components\neon-animation\.bower.json - - - Resources\dashboard-ui\bower_components\neon-animation\.gitignore - - - Resources\dashboard-ui\bower_components\neon-animation\.travis.yml - - - Resources\dashboard-ui\bower_components\neon-animation\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\neon-animation\README.md - - - Resources\dashboard-ui\bower_components\neon-animation\bower.json - - - Resources\dashboard-ui\bower_components\neon-animation\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animatable-behavior.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animatable.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animated-pages.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animation-behavior.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animation-runner-behavior.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-animations.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-shared-element-animatable-behavior.html - - - Resources\dashboard-ui\bower_components\neon-animation\neon-shared-element-animation-behavior.html - - - Resources\dashboard-ui\bower_components\neon-animation\web-animations.html - - - Resources\dashboard-ui\bower_components\neon-animation\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\neon-animation\animations\cascaded-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\fade-in-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\fade-out-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\hero-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\opaque-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\reverse-ripple-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\ripple-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\scale-down-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\scale-up-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-down-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-from-bottom-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-from-left-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-from-right-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-from-top-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-left-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-right-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\slide-up-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\animations\transform-animation.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\shared-styles.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\card\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\card\x-card.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\card\x-cards-list.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\declarative\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-animatable.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-dialog.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\dropdown\animated-dropdown.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\dropdown\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\grid\animated-grid.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\grid\fullsize-page-with-card.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\grid\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\list\full-view.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\list\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\list\list-demo.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\list\list-view.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\load\animated-grid.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\load\full-page.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\load\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\reprojection\animated-grid.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\reprojection\fullsize-page-with-card.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\reprojection\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\reprojection\reprojected-pages.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\tiles\circles-page.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\tiles\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\demo\tiles\squares-page.html - - - Resources\dashboard-ui\bower_components\neon-animation\guides\neon-animation.md - - - Resources\dashboard-ui\bower_components\neon-animation\test\index.html - - - Resources\dashboard-ui\bower_components\neon-animation\test\neon-animated-pages-descendant-selection.html - - - Resources\dashboard-ui\bower_components\neon-animation\test\neon-animated-pages-lazy.html - - - Resources\dashboard-ui\bower_components\neon-animation\test\neon-animated-pages.html - - - Resources\dashboard-ui\bower_components\neon-animation\test\test-resizable-pages.html - Resources\dashboard-ui\bower_components\paper-behaviors\.bower.json @@ -4107,6 +3069,9 @@ Resources\dashboard-ui\bower_components\paper-behaviors\paper-ripple-behavior.html + + Resources\dashboard-ui\bower_components\paper-behaviors\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\paper-behaviors\demo\index.html @@ -4140,42 +3105,6 @@ Resources\dashboard-ui\bower_components\paper-behaviors\test\test-radio-button.html - - Resources\dashboard-ui\bower_components\paper-button\.bower.json - - - Resources\dashboard-ui\bower_components\paper-button\.gitignore - - - Resources\dashboard-ui\bower_components\paper-button\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-button\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-button\README.md - - - Resources\dashboard-ui\bower_components\paper-button\bower.json - - - Resources\dashboard-ui\bower_components\paper-button\index.html - - - Resources\dashboard-ui\bower_components\paper-button\paper-button.html - - - Resources\dashboard-ui\bower_components\paper-button\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-button\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-button\test\index.html - - - Resources\dashboard-ui\bower_components\paper-button\test\paper-button.html - Resources\dashboard-ui\bower_components\paper-checkbox\.bower.json @@ -4261,1516 +3190,346 @@ Resources\dashboard-ui\bower_components\paper-icon-button\bower.json - Resources\dashboard-ui\bower_components\paper-icon-button\index.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\paper-icon-button-light.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\paper-icon-button.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-icon-button\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\demo\paper-icon-button-light.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\test\a11y.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-icon-button\test\index.html - - - Resources\dashboard-ui\bower_components\paper-input\.bower.json - - - Resources\dashboard-ui\bower_components\paper-input\.gitignore - - - Resources\dashboard-ui\bower_components\paper-input\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-input\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-input\README.md - - - Resources\dashboard-ui\bower_components\paper-input\all-imports.html - - - Resources\dashboard-ui\bower_components\paper-input\bower.json - - - Resources\dashboard-ui\bower_components\paper-input\hero.svg - - - Resources\dashboard-ui\bower_components\paper-input\index.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-addon-behavior.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-behavior.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-char-counter.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-container.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-error.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-textarea.html - - - Resources\dashboard-ui\bower_components\paper-input\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-input\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-input\demo\ssn-input.html - - - Resources\dashboard-ui\bower_components\paper-input\demo\ssn-validator.html - - - Resources\dashboard-ui\bower_components\paper-input\test\index.html - - - Resources\dashboard-ui\bower_components\paper-input\test\letters-only.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-char-counter.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-container.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-error.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-textarea.html - - - Resources\dashboard-ui\bower_components\paper-item\.bower.json - - - Resources\dashboard-ui\bower_components\paper-item\.gitignore - - - Resources\dashboard-ui\bower_components\paper-item\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-item\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-item\README.md - - - Resources\dashboard-ui\bower_components\paper-item\all-imports.html - - - Resources\dashboard-ui\bower_components\paper-item\bower.json - - - Resources\dashboard-ui\bower_components\paper-item\index.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-icon-item.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-behavior.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-body.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-shared-styles.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item.html - - - Resources\dashboard-ui\bower_components\paper-item\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-item\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-item\test\index.html - - - Resources\dashboard-ui\bower_components\paper-item\test\paper-item.html - - - Resources\dashboard-ui\bower_components\paper-material\.bower.json - - - Resources\dashboard-ui\bower_components\paper-material\.gitignore - - - Resources\dashboard-ui\bower_components\paper-material\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-material\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-material\README.md - - - Resources\dashboard-ui\bower_components\paper-material\bower.json - - - Resources\dashboard-ui\bower_components\paper-material\index.html - - - Resources\dashboard-ui\bower_components\paper-material\paper-material-shared-styles.html - - - Resources\dashboard-ui\bower_components\paper-material\paper-material.html - - - Resources\dashboard-ui\bower_components\paper-material\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-material\test\index.html - - - Resources\dashboard-ui\bower_components\paper-material\test\paper-material.html - - - Resources\dashboard-ui\bower_components\paper-menu\.bower.json - - - Resources\dashboard-ui\bower_components\paper-menu\.gitignore - - - Resources\dashboard-ui\bower_components\paper-menu\README.md - - - Resources\dashboard-ui\bower_components\paper-menu\bower.json - - - Resources\dashboard-ui\bower_components\paper-menu\hero.svg - - - Resources\dashboard-ui\bower_components\paper-menu\index.html - - - Resources\dashboard-ui\bower_components\paper-menu\paper-menu.html - - - Resources\dashboard-ui\bower_components\paper-menu\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-menu\test\index.html - - - Resources\dashboard-ui\bower_components\paper-menu\test\paper-menu.html - - - Resources\dashboard-ui\bower_components\paper-progress\.bower.json - - - Resources\dashboard-ui\bower_components\paper-progress\.gitignore - - - Resources\dashboard-ui\bower_components\paper-progress\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-progress\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-progress\README.md - - - Resources\dashboard-ui\bower_components\paper-progress\bower.json - - - Resources\dashboard-ui\bower_components\paper-progress\hero.svg - - - Resources\dashboard-ui\bower_components\paper-progress\index.html - - - Resources\dashboard-ui\bower_components\paper-progress\paper-progress.html - - - Resources\dashboard-ui\bower_components\paper-progress\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-progress\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-progress\test\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-button\.bower.json - - - Resources\dashboard-ui\bower_components\paper-radio-button\.gitignore - - - Resources\dashboard-ui\bower_components\paper-radio-button\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-radio-button\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-radio-button\README.md - - - Resources\dashboard-ui\bower_components\paper-radio-button\bower.json - - - Resources\dashboard-ui\bower_components\paper-radio-button\hero.svg - - - Resources\dashboard-ui\bower_components\paper-radio-button\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-button\paper-radio-button.html - - - Resources\dashboard-ui\bower_components\paper-radio-button\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-button\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-radio-button\test\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-group\.bower.json - - - Resources\dashboard-ui\bower_components\paper-radio-group\.gitignore - - - Resources\dashboard-ui\bower_components\paper-radio-group\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-radio-group\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-radio-group\README.md - - - Resources\dashboard-ui\bower_components\paper-radio-group\bower.json - - - Resources\dashboard-ui\bower_components\paper-radio-group\hero.svg - - - Resources\dashboard-ui\bower_components\paper-radio-group\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-group\paper-radio-group.html - - - Resources\dashboard-ui\bower_components\paper-radio-group\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-radio-group\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-radio-group\test\index.html - - - Resources\dashboard-ui\bower_components\paper-ripple\.bower.json - - - Resources\dashboard-ui\bower_components\paper-ripple\.gitignore - - - Resources\dashboard-ui\bower_components\paper-ripple\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-ripple\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-ripple\README.md - - - Resources\dashboard-ui\bower_components\paper-ripple\bower.json - - - Resources\dashboard-ui\bower_components\paper-ripple\hero.svg - - - Resources\dashboard-ui\bower_components\paper-ripple\index.html - - - Resources\dashboard-ui\bower_components\paper-ripple\paper-ripple.html - - - Resources\dashboard-ui\bower_components\paper-ripple\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-ripple\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-ripple\test\index.html - - - Resources\dashboard-ui\bower_components\paper-ripple\test\paper-ripple.html - - - Resources\dashboard-ui\bower_components\paper-spinner\.bower.json - - - Resources\dashboard-ui\bower_components\paper-spinner\.gitignore - - - Resources\dashboard-ui\bower_components\paper-spinner\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-spinner\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-spinner\README.md - - - Resources\dashboard-ui\bower_components\paper-spinner\bower.json - - - Resources\dashboard-ui\bower_components\paper-spinner\hero.svg - - - Resources\dashboard-ui\bower_components\paper-spinner\index.html - - - Resources\dashboard-ui\bower_components\paper-spinner\paper-spinner-styles.html - - - Resources\dashboard-ui\bower_components\paper-spinner\paper-spinner.html - - - Resources\dashboard-ui\bower_components\paper-spinner\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-spinner\test\index.html - - - Resources\dashboard-ui\bower_components\paper-spinner\test\paper-spinner.html - - - Resources\dashboard-ui\bower_components\paper-styles\.bower.json - - - Resources\dashboard-ui\bower_components\paper-styles\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-styles\README.md - - - Resources\dashboard-ui\bower_components\paper-styles\bower.json - - - Resources\dashboard-ui\bower_components\paper-styles\color.html - - - Resources\dashboard-ui\bower_components\paper-styles\default-theme.html - - - Resources\dashboard-ui\bower_components\paper-styles\demo-pages.html - - - Resources\dashboard-ui\bower_components\paper-styles\demo.css - - - Resources\dashboard-ui\bower_components\paper-styles\index.html - - - Resources\dashboard-ui\bower_components\paper-styles\paper-styles-classes.html - - - Resources\dashboard-ui\bower_components\paper-styles\paper-styles.html - - - Resources\dashboard-ui\bower_components\paper-styles\shadow.html - - - Resources\dashboard-ui\bower_components\paper-styles\typography.html - - - Resources\dashboard-ui\bower_components\paper-styles\classes\global.html - - - Resources\dashboard-ui\bower_components\paper-styles\classes\shadow-layout.html - - - Resources\dashboard-ui\bower_components\paper-styles\classes\shadow.html - - - Resources\dashboard-ui\bower_components\paper-styles\classes\typography.html - - - Resources\dashboard-ui\bower_components\paper-styles\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-tabs\.bower.json - - - Resources\dashboard-ui\bower_components\paper-tabs\.gitignore - - - Resources\dashboard-ui\bower_components\paper-tabs\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-tabs\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-tabs\README.md - - - Resources\dashboard-ui\bower_components\paper-tabs\bower.json - - - Resources\dashboard-ui\bower_components\paper-tabs\hero.svg - - - Resources\dashboard-ui\bower_components\paper-tabs\index.html - - - Resources\dashboard-ui\bower_components\paper-tabs\paper-tab.html - - - Resources\dashboard-ui\bower_components\paper-tabs\paper-tabs-icons.html - - - Resources\dashboard-ui\bower_components\paper-tabs\paper-tabs.html - - - Resources\dashboard-ui\bower_components\paper-tabs\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-tabs\demo\paper-tabs-demo-styles.html - - - Resources\dashboard-ui\bower_components\paper-tabs\demo\tabs-with-content-example.html - - - Resources\dashboard-ui\bower_components\paper-tabs\test\attr-for-selected.html - - - Resources\dashboard-ui\bower_components\paper-tabs\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-tabs\test\index.html - - - Resources\dashboard-ui\bower_components\paper-toggle-button\.bower.json - - - Resources\dashboard-ui\bower_components\paper-toggle-button\.gitignore - - - Resources\dashboard-ui\bower_components\paper-toggle-button\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-toggle-button\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-toggle-button\README.md - - - Resources\dashboard-ui\bower_components\paper-toggle-button\bower.json - - - Resources\dashboard-ui\bower_components\paper-toggle-button\hero.svg - - - Resources\dashboard-ui\bower_components\paper-toggle-button\index.html - - - Resources\dashboard-ui\bower_components\paper-toggle-button\paper-toggle-button.html - - - Resources\dashboard-ui\bower_components\paper-toggle-button\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-toggle-button\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-toggle-button\test\index.html - - - Resources\dashboard-ui\bower_components\polymer\.bower.json - - - Resources\dashboard-ui\bower_components\polymer\LICENSE.txt - - - Resources\dashboard-ui\bower_components\polymer\bower.json - - - Resources\dashboard-ui\bower_components\polymer\polymer-micro.html - - - Resources\dashboard-ui\bower_components\polymer\polymer-mini.html - - - Resources\dashboard-ui\bower_components\polymer\polymer.html - - - Resources\dashboard-ui\bower_components\prism\.bower.json - - - Resources\dashboard-ui\bower_components\prism\CHANGELOG.md - - - Resources\dashboard-ui\bower_components\prism\LICENSE - - - Resources\dashboard-ui\bower_components\prism\README.md - - - Resources\dashboard-ui\bower_components\prism\bower.json - - - Resources\dashboard-ui\bower_components\prism\components.js - - - Resources\dashboard-ui\bower_components\prism\examples.js - - - Resources\dashboard-ui\bower_components\prism\gulpfile.js - - - Resources\dashboard-ui\bower_components\prism\package.json - - - Resources\dashboard-ui\bower_components\prism\prism.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-abap.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-abap.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-actionscript.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-actionscript.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-apacheconf.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-apacheconf.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-apl.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-apl.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-applescript.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-applescript.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-asciidoc.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-asciidoc.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-aspnet.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-aspnet.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-autohotkey.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-autohotkey.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-autoit.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-autoit.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bash.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bash.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-basic.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-basic.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-batch.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-batch.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bison.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bison.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-brainfuck.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-brainfuck.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bro.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-bro.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-c.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-c.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-clike.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-clike.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-coffeescript.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-coffeescript.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-core.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-core.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-cpp.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-cpp.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-crystal.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-crystal.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-csharp.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-csharp.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-css-extras.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-css-extras.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-css.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-css.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-d.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-d.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-dart.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-dart.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-diff.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-diff.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-docker.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-docker.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-eiffel.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-eiffel.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-elixir.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-elixir.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-erlang.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-erlang.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-fortran.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-fortran.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-fsharp.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-fsharp.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-gherkin.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-gherkin.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-git.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-git.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-glsl.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-glsl.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-go.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-go.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-groovy.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-groovy.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haml.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haml.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-handlebars.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-handlebars.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haskell.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haskell.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haxe.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-haxe.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-http.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-http.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-icon.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-icon.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-inform7.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-inform7.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ini.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ini.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-j.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-j.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-jade.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-jade.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-java.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-java.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-javascript.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-javascript.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-json.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-json.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-jsx.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-jsx.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-julia.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-julia.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-keyman.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-keyman.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-kotlin.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-kotlin.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-latex.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-latex.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-less.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-less.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-lolcode.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-lolcode.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-lua.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-lua.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-makefile.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-makefile.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-markdown.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-markdown.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-markup.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-markup.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-matlab.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-matlab.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-mel.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-mel.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-mizar.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-mizar.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-monkey.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-monkey.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nasm.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nasm.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nginx.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nginx.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nim.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nim.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nix.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nix.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nsis.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-nsis.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-objectivec.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-objectivec.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ocaml.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ocaml.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-oz.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-oz.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-parigp.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-parigp.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-parser.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-parser.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-pascal.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-pascal.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-perl.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-perl.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-php-extras.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-php-extras.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-php.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-php.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-powershell.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-powershell.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-processing.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-processing.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-prolog.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-prolog.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-protobuf.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-protobuf.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-puppet.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-puppet.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-pure.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-pure.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-python.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-python.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-q.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-q.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-qore.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-qore.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-r.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-r.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rest.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rest.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rip.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rip.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-roboconf.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-roboconf.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ruby.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-ruby.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rust.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-rust.min.js - - - Resources\dashboard-ui\bower_components\prism\components\prism-sas.js + Resources\dashboard-ui\bower_components\paper-icon-button\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-sas.min.js + + Resources\dashboard-ui\bower_components\paper-icon-button\paper-icon-button-light.html - - Resources\dashboard-ui\bower_components\prism\components\prism-sass.js + + Resources\dashboard-ui\bower_components\paper-icon-button\paper-icon-button.html - - Resources\dashboard-ui\bower_components\prism\components\prism-sass.min.js + + Resources\dashboard-ui\bower_components\paper-icon-button\.github\ISSUE_TEMPLATE.md - - Resources\dashboard-ui\bower_components\prism\components\prism-scala.js + + Resources\dashboard-ui\bower_components\paper-icon-button\demo\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-scala.min.js + + Resources\dashboard-ui\bower_components\paper-icon-button\demo\paper-icon-button-light.html - - Resources\dashboard-ui\bower_components\prism\components\prism-scheme.js + + Resources\dashboard-ui\bower_components\paper-icon-button\test\a11y.html - - Resources\dashboard-ui\bower_components\prism\components\prism-scheme.min.js + + Resources\dashboard-ui\bower_components\paper-icon-button\test\basic.html - - Resources\dashboard-ui\bower_components\prism\components\prism-scss.js + + Resources\dashboard-ui\bower_components\paper-icon-button\test\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-scss.min.js + + Resources\dashboard-ui\bower_components\paper-input\.bower.json - - Resources\dashboard-ui\bower_components\prism\components\prism-smalltalk.js + + Resources\dashboard-ui\bower_components\paper-input\.gitignore - - Resources\dashboard-ui\bower_components\prism\components\prism-smalltalk.min.js + + Resources\dashboard-ui\bower_components\paper-input\.travis.yml - - Resources\dashboard-ui\bower_components\prism\components\prism-smarty.js + + Resources\dashboard-ui\bower_components\paper-input\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\components\prism-smarty.min.js + + Resources\dashboard-ui\bower_components\paper-input\README.md - - Resources\dashboard-ui\bower_components\prism\components\prism-sql.js + + Resources\dashboard-ui\bower_components\paper-input\all-imports.html - - Resources\dashboard-ui\bower_components\prism\components\prism-sql.min.js + + Resources\dashboard-ui\bower_components\paper-input\bower.json - - Resources\dashboard-ui\bower_components\prism\components\prism-stylus.js + + Resources\dashboard-ui\bower_components\paper-input\hero.svg - - Resources\dashboard-ui\bower_components\prism\components\prism-stylus.min.js + + Resources\dashboard-ui\bower_components\paper-input\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-swift.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input-addon-behavior.html - - Resources\dashboard-ui\bower_components\prism\components\prism-swift.min.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input-behavior.html - - Resources\dashboard-ui\bower_components\prism\components\prism-tcl.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input-char-counter.html - - Resources\dashboard-ui\bower_components\prism\components\prism-tcl.min.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input-container.html - - Resources\dashboard-ui\bower_components\prism\components\prism-textile.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input-error.html - - Resources\dashboard-ui\bower_components\prism\components\prism-textile.min.js + + Resources\dashboard-ui\bower_components\paper-input\paper-input.html - - Resources\dashboard-ui\bower_components\prism\components\prism-twig.js + + Resources\dashboard-ui\bower_components\paper-input\paper-textarea.html - - Resources\dashboard-ui\bower_components\prism\components\prism-twig.min.js + + Resources\dashboard-ui\bower_components\paper-input\.github\ISSUE_TEMPLATE.md - - Resources\dashboard-ui\bower_components\prism\components\prism-typescript.js + + Resources\dashboard-ui\bower_components\paper-input\demo\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-typescript.min.js + + Resources\dashboard-ui\bower_components\paper-input\demo\ssn-input.html - - Resources\dashboard-ui\bower_components\prism\components\prism-verilog.js + + Resources\dashboard-ui\bower_components\paper-input\demo\ssn-validator.html - - Resources\dashboard-ui\bower_components\prism\components\prism-verilog.min.js + + Resources\dashboard-ui\bower_components\paper-input\test\index.html - - Resources\dashboard-ui\bower_components\prism\components\prism-vhdl.js + + Resources\dashboard-ui\bower_components\paper-input\test\letters-only.html - - Resources\dashboard-ui\bower_components\prism\components\prism-vhdl.min.js + + Resources\dashboard-ui\bower_components\paper-input\test\paper-input-char-counter.html - - Resources\dashboard-ui\bower_components\prism\components\prism-vim.js + + Resources\dashboard-ui\bower_components\paper-input\test\paper-input-container.html - - Resources\dashboard-ui\bower_components\prism\components\prism-vim.min.js + + Resources\dashboard-ui\bower_components\paper-input\test\paper-input-error.html - - Resources\dashboard-ui\bower_components\prism\components\prism-wiki.js + + Resources\dashboard-ui\bower_components\paper-input\test\paper-input.html - - Resources\dashboard-ui\bower_components\prism\components\prism-wiki.min.js + + Resources\dashboard-ui\bower_components\paper-input\test\paper-textarea.html - - Resources\dashboard-ui\bower_components\prism\components\prism-yaml.js + + Resources\dashboard-ui\bower_components\paper-item\.bower.json - - Resources\dashboard-ui\bower_components\prism\components\prism-yaml.min.js + + Resources\dashboard-ui\bower_components\paper-item\.gitignore - - Resources\dashboard-ui\bower_components\prism\plugins\autolinker\prism-autolinker.css + + Resources\dashboard-ui\bower_components\paper-item\.travis.yml - - Resources\dashboard-ui\bower_components\prism\plugins\autolinker\prism-autolinker.js + + Resources\dashboard-ui\bower_components\paper-item\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\plugins\autolinker\prism-autolinker.min.js + + Resources\dashboard-ui\bower_components\paper-item\README.md - - Resources\dashboard-ui\bower_components\prism\plugins\autoloader\prism-autoloader.js + + Resources\dashboard-ui\bower_components\paper-item\all-imports.html - - Resources\dashboard-ui\bower_components\prism\plugins\autoloader\prism-autoloader.min.js + + Resources\dashboard-ui\bower_components\paper-item\bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\command-line\prism-command-line.css + + Resources\dashboard-ui\bower_components\paper-item\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\command-line\prism-command-line.js + + Resources\dashboard-ui\bower_components\paper-item\paper-icon-item.html - - Resources\dashboard-ui\bower_components\prism\plugins\command-line\prism-command-line.min.js + + Resources\dashboard-ui\bower_components\paper-item\paper-item-behavior.html - - Resources\dashboard-ui\bower_components\prism\plugins\file-highlight\prism-file-highlight.js + + Resources\dashboard-ui\bower_components\paper-item\paper-item-body.html - - Resources\dashboard-ui\bower_components\prism\plugins\file-highlight\prism-file-highlight.min.js + + Resources\dashboard-ui\bower_components\paper-item\paper-item-shared-styles.html - - Resources\dashboard-ui\bower_components\prism\plugins\highlight-keywords\prism-highlight-keywords.js + + Resources\dashboard-ui\bower_components\paper-item\paper-item.html - - Resources\dashboard-ui\bower_components\prism\plugins\highlight-keywords\prism-highlight-keywords.min.js + + Resources\dashboard-ui\bower_components\paper-item\.github\ISSUE_TEMPLATE.md - - Resources\dashboard-ui\bower_components\prism\plugins\ie8\prism-ie8.css + + Resources\dashboard-ui\bower_components\paper-item\demo\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\ie8\prism-ie8.js + + Resources\dashboard-ui\bower_components\paper-item\test\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\ie8\prism-ie8.min.js + + Resources\dashboard-ui\bower_components\paper-item\test\paper-item.html - - Resources\dashboard-ui\bower_components\prism\plugins\jsonp-highlight\prism-jsonp-highlight.js + + Resources\dashboard-ui\bower_components\paper-material\.bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\jsonp-highlight\prism-jsonp-highlight.min.js + + Resources\dashboard-ui\bower_components\paper-material\.gitignore - - Resources\dashboard-ui\bower_components\prism\plugins\keep-markup\prism-keep-markup.js + + Resources\dashboard-ui\bower_components\paper-material\.travis.yml - - Resources\dashboard-ui\bower_components\prism\plugins\keep-markup\prism-keep-markup.min.js + + Resources\dashboard-ui\bower_components\paper-material\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\plugins\line-highlight\prism-line-highlight.css + + Resources\dashboard-ui\bower_components\paper-material\README.md - - Resources\dashboard-ui\bower_components\prism\plugins\line-highlight\prism-line-highlight.js + + Resources\dashboard-ui\bower_components\paper-material\bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\line-highlight\prism-line-highlight.min.js + + Resources\dashboard-ui\bower_components\paper-material\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\line-numbers\prism-line-numbers.css + + Resources\dashboard-ui\bower_components\paper-material\paper-material-shared-styles.html - - Resources\dashboard-ui\bower_components\prism\plugins\line-numbers\prism-line-numbers.js + + Resources\dashboard-ui\bower_components\paper-material\paper-material.html - - Resources\dashboard-ui\bower_components\prism\plugins\line-numbers\prism-line-numbers.min.js + + Resources\dashboard-ui\bower_components\paper-material\demo\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\normalize-whitespace\prism-normalize-whitespace.js + + Resources\dashboard-ui\bower_components\paper-material\test\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\normalize-whitespace\prism-normalize-whitespace.min.js + + Resources\dashboard-ui\bower_components\paper-material\test\paper-material.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-angle\prism-previewer-angle.css + + Resources\dashboard-ui\bower_components\paper-progress\.bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-angle\prism-previewer-angle.js + + Resources\dashboard-ui\bower_components\paper-progress\.gitignore - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-angle\prism-previewer-angle.min.js + + Resources\dashboard-ui\bower_components\paper-progress\.travis.yml - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-base\prism-previewer-base.css + + Resources\dashboard-ui\bower_components\paper-progress\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-base\prism-previewer-base.js + + Resources\dashboard-ui\bower_components\paper-progress\README.md - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-base\prism-previewer-base.min.js + + Resources\dashboard-ui\bower_components\paper-progress\bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-color\prism-previewer-color.css + + Resources\dashboard-ui\bower_components\paper-progress\hero.svg - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-color\prism-previewer-color.js + + Resources\dashboard-ui\bower_components\paper-progress\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-color\prism-previewer-color.min.js + + Resources\dashboard-ui\bower_components\paper-progress\paper-progress.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-easing\prism-previewer-easing.css + + Resources\dashboard-ui\bower_components\paper-progress\demo\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-easing\prism-previewer-easing.js + + Resources\dashboard-ui\bower_components\paper-progress\test\basic.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-easing\prism-previewer-easing.min.js + + Resources\dashboard-ui\bower_components\paper-progress\test\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-gradient\prism-previewer-gradient.css + + Resources\dashboard-ui\bower_components\paper-ripple\.bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-gradient\prism-previewer-gradient.js + + Resources\dashboard-ui\bower_components\paper-ripple\.gitignore - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-gradient\prism-previewer-gradient.min.js + + Resources\dashboard-ui\bower_components\paper-ripple\.travis.yml - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-time\prism-previewer-time.css + + Resources\dashboard-ui\bower_components\paper-ripple\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-time\prism-previewer-time.js + + Resources\dashboard-ui\bower_components\paper-ripple\README.md - - Resources\dashboard-ui\bower_components\prism\plugins\previewer-time\prism-previewer-time.min.js + + Resources\dashboard-ui\bower_components\paper-ripple\bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\remove-initial-line-feed\prism-remove-initial-line-feed.js + + Resources\dashboard-ui\bower_components\paper-ripple\hero.svg - - Resources\dashboard-ui\bower_components\prism\plugins\remove-initial-line-feed\prism-remove-initial-line-feed.min.js + + Resources\dashboard-ui\bower_components\paper-ripple\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\show-invisibles\prism-show-invisibles.css + + Resources\dashboard-ui\bower_components\paper-ripple\paper-ripple.html - - Resources\dashboard-ui\bower_components\prism\plugins\show-invisibles\prism-show-invisibles.js + + Resources\dashboard-ui\bower_components\paper-ripple\.github\ISSUE_TEMPLATE.md - - Resources\dashboard-ui\bower_components\prism\plugins\show-invisibles\prism-show-invisibles.min.js + + Resources\dashboard-ui\bower_components\paper-ripple\demo\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\show-language\prism-show-language.css + + Resources\dashboard-ui\bower_components\paper-ripple\test\index.html - - Resources\dashboard-ui\bower_components\prism\plugins\show-language\prism-show-language.js + + Resources\dashboard-ui\bower_components\paper-ripple\test\paper-ripple.html - - Resources\dashboard-ui\bower_components\prism\plugins\show-language\prism-show-language.min.js + + Resources\dashboard-ui\bower_components\paper-styles\.bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\unescaped-markup\prism-unescaped-markup.css + + Resources\dashboard-ui\bower_components\paper-styles\CONTRIBUTING.md - - Resources\dashboard-ui\bower_components\prism\plugins\unescaped-markup\prism-unescaped-markup.js + + Resources\dashboard-ui\bower_components\paper-styles\README.md - - Resources\dashboard-ui\bower_components\prism\plugins\unescaped-markup\prism-unescaped-markup.min.js + + Resources\dashboard-ui\bower_components\paper-styles\bower.json - - Resources\dashboard-ui\bower_components\prism\plugins\wpd\prism-wpd.css + + Resources\dashboard-ui\bower_components\paper-styles\color.html - - Resources\dashboard-ui\bower_components\prism\plugins\wpd\prism-wpd.js + + Resources\dashboard-ui\bower_components\paper-styles\default-theme.html - - Resources\dashboard-ui\bower_components\prism\plugins\wpd\prism-wpd.min.js + + Resources\dashboard-ui\bower_components\paper-styles\demo-pages.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-coy.css + + Resources\dashboard-ui\bower_components\paper-styles\demo.css - - Resources\dashboard-ui\bower_components\prism\themes\prism-dark.css + + Resources\dashboard-ui\bower_components\paper-styles\index.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-funky.css + + Resources\dashboard-ui\bower_components\paper-styles\paper-styles-classes.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-okaidia.css + + Resources\dashboard-ui\bower_components\paper-styles\paper-styles.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-solarizedlight.css + + Resources\dashboard-ui\bower_components\paper-styles\shadow.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-tomorrow.css + + Resources\dashboard-ui\bower_components\paper-styles\typography.html - - Resources\dashboard-ui\bower_components\prism\themes\prism-twilight.css + + Resources\dashboard-ui\bower_components\paper-styles\classes\global.html - - Resources\dashboard-ui\bower_components\prism\themes\prism.css + + Resources\dashboard-ui\bower_components\paper-styles\classes\shadow-layout.html - - Resources\dashboard-ui\bower_components\prism\vendor\promise.js + + Resources\dashboard-ui\bower_components\paper-styles\classes\shadow.html - - Resources\dashboard-ui\bower_components\prism-element\.bower.json + + Resources\dashboard-ui\bower_components\paper-styles\classes\typography.html - - Resources\dashboard-ui\bower_components\prism-element\CONTRIBUTING.md + + Resources\dashboard-ui\bower_components\paper-styles\demo\index.html - - Resources\dashboard-ui\bower_components\prism-element\README.md + + Resources\dashboard-ui\bower_components\polymer\.bower.json - - Resources\dashboard-ui\bower_components\prism-element\bower.json + + Resources\dashboard-ui\bower_components\polymer\LICENSE.txt - - Resources\dashboard-ui\bower_components\prism-element\index.html + + Resources\dashboard-ui\bower_components\polymer\bower.json - - Resources\dashboard-ui\bower_components\prism-element\prism-highlighter.html + + Resources\dashboard-ui\bower_components\polymer\polymer-micro.html - - Resources\dashboard-ui\bower_components\prism-element\prism-import.html + + Resources\dashboard-ui\bower_components\polymer\polymer-mini.html - - Resources\dashboard-ui\bower_components\prism-element\prism-theme-default.html + + Resources\dashboard-ui\bower_components\polymer\polymer.html Resources\dashboard-ui\bower_components\query-string\.bower.json @@ -5847,51 +3606,30 @@ Resources\dashboard-ui\bower_components\web-animations-js\web-animations-next-lite.min.js - - Resources\dashboard-ui\bower_components\web-animations-js\web-animations-next-lite.min.js.map - Resources\dashboard-ui\bower_components\web-animations-js\web-animations-next.min.js - - Resources\dashboard-ui\bower_components\web-animations-js\web-animations-next.min.js.map - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.html Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js - - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js.map - Resources\dashboard-ui\bower_components\webcomponentsjs\.bower.json - - Resources\dashboard-ui\bower_components\webcomponentsjs\CustomElements.js - Resources\dashboard-ui\bower_components\webcomponentsjs\CustomElements.min.js - - Resources\dashboard-ui\bower_components\webcomponentsjs\HTMLImports.js - Resources\dashboard-ui\bower_components\webcomponentsjs\HTMLImports.min.js - - Resources\dashboard-ui\bower_components\webcomponentsjs\MutationObserver.js - Resources\dashboard-ui\bower_components\webcomponentsjs\MutationObserver.min.js Resources\dashboard-ui\bower_components\webcomponentsjs\README.md - - Resources\dashboard-ui\bower_components\webcomponentsjs\ShadowDOM.js - Resources\dashboard-ui\bower_components\webcomponentsjs\ShadowDOM.min.js @@ -5901,27 +3639,27 @@ Resources\dashboard-ui\bower_components\webcomponentsjs\package.json - - Resources\dashboard-ui\bower_components\webcomponentsjs\webcomponents-lite.js - Resources\dashboard-ui\bower_components\webcomponentsjs\webcomponents-lite.min.js - - Resources\dashboard-ui\bower_components\webcomponentsjs\webcomponents.js - Resources\dashboard-ui\bower_components\webcomponentsjs\webcomponents.min.js Resources\dashboard-ui\components\apphost.js + + Resources\dashboard-ui\components\categorysyncbuttons.js + Resources\dashboard-ui\components\chromecasthelpers.js Resources\dashboard-ui\components\favoriteitems.js + + Resources\dashboard-ui\components\groupedcards.js + Resources\dashboard-ui\components\humanedate.js @@ -5955,6 +3693,12 @@ Resources\dashboard-ui\components\filterdialog\style.css + + Resources\dashboard-ui\components\guestinviter\connectlink.js + + + Resources\dashboard-ui\components\guestinviter\connectlink.template.html + Resources\dashboard-ui\components\guestinviter\guestinviter.js @@ -6501,9 +4245,6 @@ Resources\dashboard-ui\scripts\librarydisplay.js - - Resources\dashboard-ui\scripts\librarylist.js - Resources\dashboard-ui\scripts\librarymenu.js @@ -7026,50 +4767,5 @@ Resources\dashboard-ui\thirdparty\jstree\themes\default\throbber.gif - - Resources\dashboard-ui\voice\Readme.md - - - Resources\dashboard-ui\voice\grammarprocessor.js - - - Resources\dashboard-ui\voice\voice.css - - - Resources\dashboard-ui\voice\voice.js - - - Resources\dashboard-ui\voice\voicecommands.js - - - Resources\dashboard-ui\voice\voicedialog.js - - - Resources\dashboard-ui\voice\commands\controlcommands.js - - - Resources\dashboard-ui\voice\commands\disablecommands.js - - - Resources\dashboard-ui\voice\commands\enablecommands.js - - - Resources\dashboard-ui\voice\commands\playcommands.js - - - Resources\dashboard-ui\voice\commands\searchcommands.js - - - Resources\dashboard-ui\voice\commands\showcommands.js - - - Resources\dashboard-ui\voice\commands\togglecommands.js - - - Resources\dashboard-ui\voice\grammar\en-US.json - - - Resources\dashboard-ui\voice\grammar\grammar.json - \ No newline at end of file From 4a39fba7d3357128532fc0bd6eee27fd2374c9df Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jul 2016 19:02:22 -0400 Subject: [PATCH 013/220] 3.1.76 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 17087a0981..4d6e7bfddc 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.75")] +[assembly: AssemblyVersion("3.1.76")] From 222b2492f6aa35f3d933c9ed3d142f574e9d6d20 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jul 2016 12:49:41 -0400 Subject: [PATCH 014/220] 3.1.77 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 4d6e7bfddc..84b0d2282e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.76")] +[assembly: AssemblyVersion("3.1.77")] From e389d92e68a3f8d13da8a88b04bb9000f4d0e512 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 25 Jul 2016 12:59:43 -0400 Subject: [PATCH 015/220] 3.1.78 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 84b0d2282e..7f0f8c8399 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.77")] +[assembly: AssemblyVersion("3.1.78")] From aa434d591e8ad80c2f750221d2b44189a8e0ccda Mon Sep 17 00:00:00 2001 From: softworkz Date: Tue, 26 Jul 2016 05:29:05 +0200 Subject: [PATCH 016/220] Add StringUsageReporter StringUsageReporter reports usages of localization strings in the web application and can also list all unused strings --- .../Resources/SampleTransformed.htm | 1348 +++++++++++++++++ .../Resources/StringCheck.xslt | 145 ++ .../Resources/StringCheckSample.xml | 239 +++ .../ConsistencyTests/StringUsageReporter.cs | 260 ++++ .../TextIndexing/IndexBuilder.cs | 54 + .../TextIndexing/WordIndex.cs | 39 + .../TextIndexing/WordOccurrence.cs | 24 + .../TextIndexing/WordOccurrences.cs | 17 + MediaBrowser.Tests/MediaBrowser.Tests.csproj | 15 + 9 files changed, 2141 insertions(+) create mode 100644 MediaBrowser.Tests/ConsistencyTests/Resources/SampleTransformed.htm create mode 100644 MediaBrowser.Tests/ConsistencyTests/Resources/StringCheck.xslt create mode 100644 MediaBrowser.Tests/ConsistencyTests/Resources/StringCheckSample.xml create mode 100644 MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs create mode 100644 MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs create mode 100644 MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs create mode 100644 MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs create mode 100644 MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs diff --git a/MediaBrowser.Tests/ConsistencyTests/Resources/SampleTransformed.htm b/MediaBrowser.Tests/ConsistencyTests/Resources/SampleTransformed.htm new file mode 100644 index 0000000000..9bff396d13 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/Resources/SampleTransformed.htm @@ -0,0 +1,1348 @@ + + + + + String Usage Report + + + +

String Usage Report

+
+

Strings

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ LabelExit: "
+
Exit"
+
+
+
+
+ LabelVisitCommunity: "
+
Visit Community"
+
+
+
+
+ LabelGithub: "
+
Github"
+
+
+
+
+ LabelSwagger: "
+
Swagger"
+
+
+
+
+ LabelStandard: "
+
Standard"
+
+
+
+
+ LabelApiDocumentation: "
+
Api Documentation"
+
+
+
+
+ LabelDeveloperResources: "
+
Developer Resources"
+
+
+
+
+ LabelBrowseLibrary: "
+
Browse Library"
+
+
+
+
+ LabelConfigureServer: "
+
Configure Emby"
+
+
+
+
+ LabelOpenLibraryViewer: "
+
Open Library Viewer"
+
+
+
+
+ LabelRestartServer: "
+
Restart Server"
+
+
+
+
+ LabelShowLogWindow: "
+
Show Log Window"
+
+
+
+
+ LabelPrevious: "
+
Previous"
+
+
+ \wizardagreement.html:21 +
+ \wizardcomponents.html:54 +
+ \wizardfinish.html:40 +
+ \wizardlibrary.html:19 +
+ \wizardlivetvguide.html:30 +
+ \wizardlivetvtuner.html:31 +
+ \wizardservice.html:17 +
+ \wizardsettings.html:32 +
+ \wizarduser.html:27 +
+
+
+ LabelFinish: "
+
Finish"
+
+
+ \wizardfinish.html:41 +
+
+
+ LabelNext: "
+
Next"
+
+
+ \wizardagreement.html:22 +
+ \wizardcomponents.html:55 +
+ \wizardlibrary.html:20 +
+ \wizardlivetvguide.html:31 +
+ \wizardlivetvtuner.html:32 +
+ \wizardservice.html:18 +
+ \wizardsettings.html:33 +
+ \wizardstart.html:25 +
+ \wizarduser.html:28 +
+
+
+ LabelYoureDone: "
+
You're Done!"
+
+
+ \wizardfinish.html:7 +
+
+
+ WelcomeToProject: "
+
Welcome to Emby!"
+
+
+ \wizardstart.html:10 +
+
+
+ ThisWizardWillGuideYou: "
+
This wizard will help guide you through the setup process. To begin, please select your preferred language."
+
+
+ \wizardstart.html:16 +
+
+
+ TellUsAboutYourself: "
+
Tell us about yourself"
+
+
+ \wizarduser.html:8 +
+
+
+ ButtonQuickStartGuide: "
+
Quick start guide"
+
+
+ \wizardstart.html:12 +
+
+
+ LabelYourFirstName: "
+
Your first name:"
+
+
+ \wizarduser.html:14 +
+
+
+ MoreUsersCanBeAddedLater: "
+
More users can be added later within the Dashboard."
+
+
+ \wizarduser.html:15 +
+
+
+ UserProfilesIntro: "
+
Emby includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls."
+
+
+ \wizarduser.html:11 +
+
+
+ LabelWindowsService: "
+
Windows Service"
+
+
+ \wizardservice.html:7 +
+
+
+ AWindowsServiceHasBeenInstalled: "
+
A Windows Service has been installed."
+
+
+ \wizardservice.html:10 +
+
+
+ WindowsServiceIntro1: "
+
Emby Server normally runs as a desktop application with a tray icon, but if you prefer to run it as a background service, it can be started from the windows services control panel instead."
+
+
+ \wizardservice.html:12 +
+
+
+ WindowsServiceIntro2: "
+
If using the windows service, please note that it cannot be run at the same time as the tray icon, so you'll need to exit the tray in order to run the service. The service will also need to be configured with administrative privileges via the control panel. When running as a service, you will need to ensure that the service account has access to your media folders."
+
+
+ \wizardservice.html:14 +
+
+
+ WizardCompleted: "
+
That's all we need for now. Emby has begun collecting information about your media library. Check out some of our apps, and then click <b>Finish</b> to view the <b>Server Dashboard</b>."
+
+
+ \wizardfinish.html:10 +
+
+
+ LabelConfigureSettings: "
+
Configure settings"
+
+
+ \wizardsettings.html:8 +
+
+
+ LabelEnableVideoImageExtraction: "
+
Enable video image extraction"
+
+
+
+
+ VideoImageExtractionHelp: "
+
For videos that don't already have images, and that we're unable to find internet images for. This will add some additional time to the initial library scan but will result in a more pleasing presentation."
+
+
+
+
+ LabelEnableChapterImageExtractionForMovies: "
+
Extract chapter image extraction for Movies"
+
+
+
+
+ LabelChapterImageExtractionForMoviesHelp: "
+
Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours."
+
+
+
+
+ LabelEnableAutomaticPortMapping: "
+
Enable automatic port mapping"
+
+
+
+
+ LabelEnableAutomaticPortMappingHelp: "
+
UPnP allows automated router configuration for easy remote access. This may not work with some router models."
+
+
+
+
+ HeaderTermsOfService: "
+
Emby Terms of Service"
+
+
+ \wizardagreement.html:9 +
+
+
+ MessagePleaseAcceptTermsOfService: "
+
Please accept the terms of service and privacy policy before continuing."
+
+
+ \wizardagreement.html:12 +
+
+
+ OptionIAcceptTermsOfService: "
+
I accept the terms of service"
+
+
+ \wizardagreement.html:17 +
+
+
+ ButtonPrivacyPolicy: "
+
Privacy policy"
+
+
+ \wizardagreement.html:14 +
+
+
+ ButtonTermsOfService: "
+
Terms of Service"
+
+
+ \wizardagreement.html:15 +
+
+
+ HeaderDeveloperOptions: "
+
Developer Options"
+
+
+ \dashboardgeneral.html:108 +
+
+
+ OptionEnableWebClientResponseCache: "
+
Enable web response caching"
+
+
+ \dashboardgeneral.html:112 +
+
+
+ OptionDisableForDevelopmentHelp: "
+
Configure these as needed for web development purposes."
+
+
+ \dashboardgeneral.html:119 +
+
+
+ OptionEnableWebClientResourceMinification: "
+
Enable web resource minification"
+
+
+ \dashboardgeneral.html:116 +
+
+
+ LabelDashboardSourcePath: "
+
Web client source path:"
+
+
+ \dashboardgeneral.html:124 +
+
+
+ LabelDashboardSourcePathHelp: "
+
If running the server from source, specify the path to the dashboard-ui folder. All web client files will be served from this location."
+
+
+ \dashboardgeneral.html:126 +
+
+
+ ButtonConvertMedia: "
+
Convert media"
+
+
+ \syncactivity.html:22 +
+
+
+ ButtonOrganize: "
+
Organize"
+
+
+ \autoorganizelog.html:8 +
+ \scripts\autoorganizelog.js:293 +
+ \scripts\autoorganizelog.js:294 +
+ \scripts\autoorganizelog.js:296 +
+
+
+ LinkedToEmbyConnect: "
+
Linked to Emby Connect"
+
+
+
+
+ HeaderSupporterBenefits: "
+
Emby Premiere Benefits"
+
+
+
+
+ HeaderAddUser: "
+
Add User"
+
+
+
+
+ LabelAddConnectSupporterHelp: "
+
To add a user who isn't listed, you'll need to first link their account to Emby Connect from their user profile page."
+
+
+
+
+ LabelPinCode: "
+
Pin code:"
+
+
+
+
+ OptionHideWatchedContentFromLatestMedia: "
+
Hide watched content from latest media"
+
+
+ \mypreferenceshome.html:114 +
+
+
+ HeaderSync: "
+
Sync"
+
+
+ \mysyncsettings.html:7 +
+ \scripts\registrationservices.js:175 +
+ \useredit.html:82 +
+
+
+ ButtonOk: "
+
Ok"
+
+
+ \components\directorybrowser\directorybrowser.js:147 +
+ \components\fileorganizer\fileorganizer.template.html:45 +
+ \components\medialibrarycreator\medialibrarycreator.template.html:30 +
+ \components\metadataeditor\personeditor.template.html:33 +
+ \dlnaprofile.html:372 +
+ \dlnaprofile.html:453 +
+ \dlnaprofile.html:504 +
+ \dlnaprofile.html:542 +
+ \dlnaprofile.html:590 +
+ \dlnaprofile.html:630 +
+ \dlnaprofile.html:661 +
+ \dlnaprofile.html:706 +
+ \nowplaying.html:113 +
+ \scripts\ratingdialog.js:42 +
+
+
+ ButtonCancel: "
+
Cancel"
+
+
+ \components\tvproviders\schedulesdirect.template.html:68 +
+ \components\tvproviders\xmltv.template.html:48 +
+ \connectlogin.html:74 +
+ \connectlogin.html:108 +
+ \dlnaprofile.html:325 +
+ \dlnaprofile.html:375 +
+ \dlnaprofile.html:456 +
+ \dlnaprofile.html:507 +
+ \dlnaprofile.html:545 +
+ \dlnaprofile.html:593 +
+ \dlnaprofile.html:633 +
+ \dlnaprofile.html:664 +
+ \dlnaprofile.html:709 +
+ \forgotpassword.html:23 +
+ \forgotpasswordpin.html:22 +
+ \livetvseriestimer.html:62 +
+ \livetvtunerprovider-hdhomerun.html:35 +
+ \livetvtunerprovider-m3u.html:19 +
+ \livetvtunerprovider-satip.html:65 +
+ \login.html:27 +
+ \notificationsetting.html:64 +
+ \scheduledtask.html:85 +
+ \scripts\librarylist.js:349 +
+ \scripts\mediacontroller.js:167 +
+ \scripts\mediacontroller.js:436 +
+ \scripts\ratingdialog.js:43 +
+ \scripts\site.js:1025 +
+ \scripts\userprofilespage.js:198 +
+ \syncsettings.html:43 +
+ \useredit.html:111 +
+ \userlibraryaccess.html:57 +
+ \usernew.html:45 +
+ \userparentalcontrol.html:101 +
+
+
+ ButtonExit: "
+
Exit"
+
+
+
+
+ ButtonNew: "
+
New"
+
+
+ \components\fileorganizer\fileorganizer.template.html:18 +
+ \dlnaprofile.html:107 +
+ \dlnaprofile.html:278 +
+ \dlnaprofile.html:290 +
+ \dlnaprofile.html:296 +
+ \dlnaprofile.html:302 +
+ \dlnaprofile.html:308 +
+ \dlnaprofile.html:314 +
+ \dlnaprofiles.html:14 +
+ \serversecurity.html:8 +
+
+
+ HeaderTaskTriggers: "
+
Task Triggers"
+
+
+ \scheduledtask.html:11 +
+
+
+ HeaderTV: "
+
TV"
+
+
+ \librarysettings.html:113 +
+
+
+ HeaderAudio: "
+
Audio"
+
+
+ \librarysettings.html:39 +
+
+
+ HeaderVideo: "
+
Video"
+
+
+ \librarysettings.html:50 +
+
+
+ HeaderPaths: "
+
Paths"
+
+
+ \dashboard.html:92 +
+
+
+ CategorySync: "
+
Sync"
+
+
+
+
+ TabPlaylist: "
+
Playlist"
+
+
+ \nowplaying.html:20 +
+
+
+ HeaderEasyPinCode: "
+
Easy Pin Code"
+
+
+ \myprofile.html:69 +
+ \userpassword.html:42 +
+
+
+ HeaderGrownupsOnly: "
+
Grown-ups Only!"
+
+
+
+
+ DividerOr: "
+
-- or --"
+
+
+
+
+ HeaderInstalledServices: "
+
Installed Services"
+
+
+ \appservices.html:6 +
+
+
+ HeaderAvailableServices: "
+
Available Services"
+
+
+ \appservices.html:11 +
+
+
+ + \ No newline at end of file diff --git a/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheck.xslt b/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheck.xslt new file mode 100644 index 0000000000..39586022b3 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheck.xslt @@ -0,0 +1,145 @@ + + + + + + + + + + + + +]> + + + + + + + + <xsl:value-of select="StringUsages/@ReportTitle"/> + + + + +

+ +

+
+

Strings

+
+ + + + + + + + + + + + + + +
+
: "
+
"
+
:
+
+
+ + +
+
\ No newline at end of file diff --git a/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheckSample.xml b/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheckSample.xml new file mode 100644 index 0000000000..118ed55aef --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/Resources/StringCheckSample.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs new file mode 100644 index 0000000000..d036a6c6d7 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs @@ -0,0 +1,260 @@ +using MediaBrowser.Tests.ConsistencyTests.TextIndexing; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace MediaBrowser.Tests.ConsistencyTests +{ + /// + /// This class contains tests for reporting the usage of localization string tokens + /// in the dashboard-ui or similar. + /// + /// + /// Run one of the two tests using Visual Studio's "Test Explorer": + /// + /// + /// + /// + /// + /// + /// + /// On successful run, the bottom section of the test explorer will contain a link "Output". + /// This link will open the test results, displaying the trace and two attachment links. + /// One link will open the output folder, the other link will open the output xml file. + /// + /// + /// The output xml file contains a stylesheet link to render the results as html. + /// How that works depends on the default application configured for XML files: + /// + /// + /// Visual Studio + /// Will open in XML source view. To view the html result, click menu + /// 'XML' => 'Start XSLT without debugging' + /// Internet Explorer + /// XSL transform will be applied automatically. + /// Firefox + /// XSL transform will be applied automatically. + /// Chrome + /// Does not work. Chrome is unable/unwilling to apply xslt transforms from local files. + /// + /// + [TestClass] + public class StringUsageReporter + { + /// + /// Root path of the web application + /// + /// + /// Can be an absolute path or a path relative to the binaries folder (bin\Debug). + /// + public const string WebFolder = @"..\..\..\MediaBrowser.WebDashboard\dashboard-ui"; + + /// + /// Path to the strings file, relative to . + /// + public const string StringsFile = @"strings\en-US.json"; + + /// + /// Path to the output folder + /// + /// + /// Can be an absolute path or a path relative to the binaries folder (bin\Debug). + /// Important: When changing the output path, make sure that "StringCheck.xslt" is present + /// to make the XML transform work. + /// + public const string OutputPath = @"."; + + /// + /// List of file extension to search. + /// + public static string[] TargetExtensions = new[] { "js", "html" }; + + /// + /// List of paths to exclude from search. + /// + public static string[] ExcludePaths = new[] { @"\bower_components\", @"\thirdparty\" }; + + private TestContext testContextInstance; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + public TestContext TestContext + { + get + { + return testContextInstance; + } + set + { + testContextInstance = value; + } + } + + [TestMethod] + public void ReportStringUsage() + { + this.CheckDashboardStrings(false); + } + + [TestMethod] + public void ReportUnusedStrings() + { + this.CheckDashboardStrings(true); + } + + private void CheckDashboardStrings(Boolean unusedOnly) + { + // Init Folders + var currentDir = System.IO.Directory.GetCurrentDirectory(); + Trace("CurrentDir: {0}", currentDir); + + var rootFolderInfo = ResolveFolder(currentDir, WebFolder); + Trace("Web Root: {0}", rootFolderInfo.FullName); + + var outputFolderInfo = ResolveFolder(currentDir, OutputPath); + Trace("Output Path: {0}", outputFolderInfo.FullName); + + // Load Strings + var stringsFileName = Path.Combine(rootFolderInfo.FullName, StringsFile); + + if (!File.Exists(stringsFileName)) + { + throw new Exception(string.Format("Strings file not found: {0}", stringsFileName)); + } + + int lineNumbers; + var stringsDic = this.CreateStringsDictionary(new FileInfo(stringsFileName), out lineNumbers); + + Trace("Loaded {0} strings from strings file containing {1} lines", stringsDic.Count, lineNumbers); + + var allFiles = rootFolderInfo.GetFiles("*", SearchOption.AllDirectories); + + var filteredFiles1 = allFiles.Where(f => TargetExtensions.Any(e => f.Name.EndsWith(e))); + var filteredFiles2 = filteredFiles1.Where(f => !ExcludePaths.Any(p => f.FullName.Contains(p))); + + var selectedFiles = filteredFiles2.OrderBy(f => f.FullName).ToList(); + + var wordIndex = IndexBuilder.BuildIndexFromFiles(selectedFiles, rootFolderInfo.FullName); + + Trace("Created word index from {0} files containing {1} individual words", selectedFiles.Count, wordIndex.Keys.Count); + + var outputFileName = Path.Combine(outputFolderInfo.FullName, string.Format("StringCheck_{0:yyyyMMddHHmmss}.xml", DateTime.Now)); + var settings = new XmlWriterSettings + { + Indent = true, + Encoding = Encoding.UTF8, + WriteEndDocumentOnClose = true + }; + + Trace("Output file: {0}", outputFileName); + + using (XmlWriter writer = XmlWriter.Create(outputFileName, settings)) + { + writer.WriteStartDocument(true); + + // Write the Processing Instruction node. + string xslText = "type=\"text/xsl\" href=\"StringCheck.xslt\""; + writer.WriteProcessingInstruction("xml-stylesheet", xslText); + + writer.WriteStartElement("StringUsages"); + writer.WriteAttributeString("ReportTitle", unusedOnly ? "Unused Strings Report" : "String Usage Report"); + writer.WriteAttributeString("Mode", unusedOnly ? "UnusedOnly" : "All"); + + foreach (var kvp in stringsDic) + { + var occurences = wordIndex.Find(kvp.Key); + + if (occurences == null || !unusedOnly) + { + ////Trace("{0}: {1}", kvp.Key, kvp.Value); + writer.WriteStartElement("Dictionary"); + writer.WriteAttributeString("Token", kvp.Key); + writer.WriteAttributeString("Text", kvp.Value); + + if (occurences != null && !unusedOnly) + { + foreach (var occurence in occurences) + { + writer.WriteStartElement("Occurence"); + writer.WriteAttributeString("FileName", occurence.FileName); + writer.WriteAttributeString("FullPath", occurence.FullPath); + writer.WriteAttributeString("LineNumber", occurence.LineNumber.ToString()); + writer.WriteEndElement(); + ////Trace(" {0}:{1}", occurence.FileName, occurence.LineNumber); + } + } + + writer.WriteEndElement(); + } + } + } + + TestContext.AddResultFile(outputFileName); + TestContext.AddResultFile(outputFolderInfo.FullName); + } + + private SortedDictionary CreateStringsDictionary(FileInfo file, out int lineNumbers) + { + var dic = new SortedDictionary(); + lineNumbers = 0; + + using (var reader = file.OpenText()) + { + while (!reader.EndOfStream) + { + lineNumbers++; + var words = reader + .ReadLine() + .Split(new[] { "\":" }, StringSplitOptions.RemoveEmptyEntries); + + + if (words.Length == 2) + { + var token = words[0].Replace("\"", string.Empty).Trim(); + var text = words[1].Replace("\",", string.Empty).Replace("\"", string.Empty).Trim(); + + if (dic.Keys.Contains(token)) + { + throw new Exception(string.Format("Double string entry found: {0}", token)); + } + + dic.Add(token, text); + } + } + } + + return dic; + } + + private DirectoryInfo ResolveFolder(string currentDir, string folderPath) + { + if (folderPath.IndexOf(@"\:") != 1) + { + folderPath = Path.Combine(currentDir, folderPath); + } + + var folderInfo = new DirectoryInfo(folderPath); + + if (!folderInfo.Exists) + { + throw new Exception(string.Format("Folder not found: {0}", folderInfo.FullName)); + } + + return folderInfo; + } + + + private void Trace(string message, params object[] parameters) + { + var formatted = string.Format(message, parameters); + System.Diagnostics.Trace.WriteLine(formatted); + } + } +} diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs new file mode 100644 index 0000000000..07c0df86c7 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing +{ + public class IndexBuilder + { + public const int MinumumWordLength = 4; + + public static char[] WordChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); + + public static WordIndex BuildIndexFromFiles(IEnumerable wordFiles, string rootFolderPath) + { + var index = new WordIndex(); + + var wordSeparators = Enumerable.Range(32, 127).Select(e => Convert.ToChar(e)).Where(c => !WordChars.Contains(c)).ToArray(); + wordSeparators = wordSeparators.Concat(new[] { '\t' }).ToArray(); // add tab + + foreach (var file in wordFiles) + { + var lineNumber = 1; + var displayFileName = file.FullName.Replace(rootFolderPath, string.Empty); + using (var reader = file.OpenText()) + { + while (!reader.EndOfStream) + { + var words = reader + .ReadLine() + .Split(wordSeparators, StringSplitOptions.RemoveEmptyEntries); + ////.Select(f => f.Trim()); + + var wordIndex = 1; + foreach (var word in words) + { + if (word.Length >= MinumumWordLength) + { + index.AddWordOccurrence(word, displayFileName, file.FullName, lineNumber, wordIndex++); + } + } + + lineNumber++; + } + } + } + + return index; + } + + } +} diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs new file mode 100644 index 0000000000..4ced812373 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing +{ + public class WordIndex : Dictionary + { + public WordIndex() : base(StringComparer.InvariantCultureIgnoreCase) + { + } + + public void AddWordOccurrence(string word, string fileName, string fullPath, int lineNumber, int wordIndex) + { + WordOccurrences current; + if (!this.TryGetValue(word, out current)) + { + current = new WordOccurrences(); + this[word] = current; + } + + current.AddOccurrence(fileName, fullPath, lineNumber, wordIndex); + } + + public WordOccurrences Find(string word) + { + WordOccurrences found; + if (this.TryGetValue(word, out found)) + { + return found; + } + + return null; + } + + } +} diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs new file mode 100644 index 0000000000..40631f5825 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing +{ + public struct WordOccurrence + { + public readonly string FileName; // file containing the word. + public readonly string FullPath; // file containing the word. + public readonly int LineNumber; // line within the file. + public readonly int WordIndex; // index within the line. + + public WordOccurrence(string fileName, string fullPath, int lineNumber, int wordIndex) + { + FileName = fileName; + FullPath = fullPath; + LineNumber = lineNumber; + WordIndex = wordIndex; + } + } +} diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs new file mode 100644 index 0000000000..3ba3b59167 --- /dev/null +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing +{ + public class WordOccurrences : List + { + public void AddOccurrence(string fileName, string fullPath, int lineNumber, int wordIndex) + { + this.Add(new WordOccurrence(fileName, fullPath, lineNumber, wordIndex)); + } + + } +} diff --git a/MediaBrowser.Tests/MediaBrowser.Tests.csproj b/MediaBrowser.Tests/MediaBrowser.Tests.csproj index 0cfe8182c8..76a1861097 100644 --- a/MediaBrowser.Tests/MediaBrowser.Tests.csproj +++ b/MediaBrowser.Tests/MediaBrowser.Tests.csproj @@ -25,6 +25,7 @@ DEBUG;TRACE prompt 4 + bin\Debug\MediaBrowser.Tests.XML none @@ -36,6 +37,7 @@ + @@ -50,6 +52,11 @@ + + + + + @@ -98,6 +105,14 @@ PreserveNewest + + + Always + StringCheck.xslt + + + + From f539c9894c91e15189b2d9d676afa8ea08b3f179 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jul 2016 13:21:27 -0400 Subject: [PATCH 017/220] remove unused code --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index e4150d85cf..7e4b39c364 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -173,9 +173,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 267ada923cde90f19f02deca5b6563b95f288bf6 Mon Sep 17 00:00:00 2001 From: softworkz Date: Wed, 27 Jul 2016 02:45:46 +0200 Subject: [PATCH 018/220] ChannelMediaInfo: Create audio stream even when there is no video --- MediaBrowser.Controller/Channels/ChannelMediaInfo.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs index 9424568b45..1216ae3522 100644 --- a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs +++ b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs @@ -83,8 +83,7 @@ namespace MediaBrowser.Controller.Channels { var list = new List(); - if (!string.IsNullOrWhiteSpace(info.VideoCodec) && - !string.IsNullOrWhiteSpace(info.AudioCodec)) + if (!string.IsNullOrWhiteSpace(info.VideoCodec)) { list.Add(new MediaStream { @@ -99,7 +98,10 @@ namespace MediaBrowser.Controller.Channels BitRate = info.VideoBitrate, AverageFrameRate = info.Framerate }); + } + if (!string.IsNullOrWhiteSpace(info.AudioCodec)) + { list.Add(new MediaStream { Type = MediaStreamType.Audio, From eb78381a3523985745da11931f5d2e08b2e6a0ab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 00:54:38 -0400 Subject: [PATCH 019/220] update resource loading --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 5 ----- 1 file changed, 5 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 7e4b39c364..5c520afcf2 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1410,11 +1410,6 @@ PreserveNewest - - - PreserveNewest - - PreserveNewest From 2fed4c1ab8af48cfb6a0077189e6b8addbedb8d7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 02:24:59 -0400 Subject: [PATCH 020/220] keep season/episode info up to date --- .../TV/EpisodeMetadataService.cs | 33 ++++++++++++++++++- .../TV/SeasonMetadataService.cs | 15 +++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs index a15de48660..b51b113805 100644 --- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs +++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Configuration; +using System; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -6,12 +7,42 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; +using System.Threading.Tasks; using CommonIO; namespace MediaBrowser.Providers.TV { public class EpisodeMetadataService : MetadataService { + protected override async Task BeforeSave(Episode item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false); + + if (updateType <= ItemUpdateType.None) + { + if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal)) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + if (updateType <= ItemUpdateType.None) + { + if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal)) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + if (updateType <= ItemUpdateType.None) + { + if (!string.Equals(item.SeasonName, item.FindSeasonName(), StringComparison.Ordinal)) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + + return updateType; + } + protected override void MergeData(MetadataResult source, MetadataResult target, List lockedFields, bool replaceData, bool mergeMetadataSettings) { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index e4894915d6..f3e6f8e9c5 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -35,6 +35,21 @@ namespace MediaBrowser.Providers.TV updateType |= SaveIsVirtualItem(item, episodes); } + if (updateType <= ItemUpdateType.None) + { + if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal)) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + if (updateType <= ItemUpdateType.None) + { + if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal)) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + return updateType; } From dc855e3c60e24febf376bd84156164b7d55802cc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 02:29:41 -0400 Subject: [PATCH 021/220] 3.1.79 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7f0f8c8399..d1e5851a82 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.78")] +[assembly: AssemblyVersion("3.1.79")] From 308233ceba2c1cd89678c91ab8f5ce2363c79e3d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 13:11:05 -0400 Subject: [PATCH 022/220] update translations --- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 21173feaad..a1fb060607 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.653 + 3.0.654 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 2946858472..ada11fd45a 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.653 + 3.0.654 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 18e8a5c13b..f4a79f454f 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.653 + 3.0.654 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + From 4f32b57e58b0568c7c0112146e87633c965efe88 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 13:11:25 -0400 Subject: [PATCH 023/220] update buffer sizes --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 3 +-- .../Playback/Progressive/ProgressiveStreamWriter.cs | 2 +- MediaBrowser.Common/IO/StreamDefaults.cs | 4 ++-- .../HttpServer/RangeRequestWriter.cs | 3 +-- .../HttpServer/StreamWriter.cs | 3 +-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index e029d4e99a..7de3096997 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -257,8 +257,7 @@ namespace MediaBrowser.Api.Playback.Hls return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } - // 256k - private const int BufferSize = 262144; + private const int BufferSize = 81920; private long GetStartPositionTicks(StreamState state, int requestedIndex) { diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 13d59240f5..860e57b32e 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Api.Playback.Progressive private readonly ILogger _logger; // 256k - private const int BufferSize = 262144; + private const int BufferSize = 81920; private long _bytesWritten = 0; diff --git a/MediaBrowser.Common/IO/StreamDefaults.cs b/MediaBrowser.Common/IO/StreamDefaults.cs index 450d293d4b..8b16d89b3b 100644 --- a/MediaBrowser.Common/IO/StreamDefaults.cs +++ b/MediaBrowser.Common/IO/StreamDefaults.cs @@ -9,11 +9,11 @@ namespace MediaBrowser.Common.IO /// /// The default copy to buffer size /// - public const int DefaultCopyToBufferSize = 262144; + public const int DefaultCopyToBufferSize = 81920; /// /// The default file stream buffer size /// - public const int DefaultFileStreamBufferSize = 262144; + public const int DefaultFileStreamBufferSize = 81920; } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index 7ac92408b2..71cd20743a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -28,8 +28,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer public Action OnComplete { get; set; } private readonly ILogger _logger; - // 256k - private const int BufferSize = 262144; + private const int BufferSize = 81920; /// /// The _options diff --git a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs index f5906f6b7b..ae408f8d68 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs @@ -75,8 +75,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { } - // 256k - private const int BufferSize = 262144; + private const int BufferSize = 81920; /// /// Writes to. From 0ab7174548764390b7bab9b914a295842de30224 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 13:18:53 -0400 Subject: [PATCH 024/220] 3.1.80 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d1e5851a82..3b18c027ea 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.79")] +[assembly: AssemblyVersion("3.1.80")] From f238005d2b2788eb5606c4ba315840fe9d525782 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 13:26:10 -0400 Subject: [PATCH 025/220] update components --- .../MediaBrowser.Common.Implementations.csproj | 2 +- MediaBrowser.Common.Implementations/packages.config | 2 +- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 108eddcf9e..ced2dd5a32 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -55,7 +55,7 @@ ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll - ..\packages\NLog.4.3.5\lib\net45\NLog.dll + ..\packages\NLog.4.3.6\lib\net45\NLog.dll True diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 882acc9ffd..594b4c7c5d 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,7 +2,7 @@ - + \ 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 0f91d52859..2c4c74b35c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -56,8 +56,8 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - - ..\packages\MediaBrowser.Naming.1.0.0.53\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + + ..\packages\MediaBrowser.Naming.1.0.0.54\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 9ae0a126a6..03f7160ae0 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -4,7 +4,7 @@ - + diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index a1fb060607..e96a77e647 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -13,7 +13,7 @@ Copyright © Emby 2013 - + From b3db8fdb0d718a7e4378bb901fbfb7329b8124af Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 15:31:19 -0400 Subject: [PATCH 026/220] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 651eaf4380..3b18c027ea 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6000")] +[assembly: AssemblyVersion("3.1.80")] From 7d520784700d057defaa0155dcc9c577b6c549a0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 15:33:53 -0400 Subject: [PATCH 027/220] 3.0.6010 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 3b18c027ea..d81f6c71cb 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.80")] +[assembly: AssemblyVersion("3.0.6010")] From 40530f729301ba3c7c631ef082a96955cfb4e256 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 27 Jul 2016 15:44:28 -0400 Subject: [PATCH 028/220] update mac project --- .../Emby.Server.Mac.csproj | 139 ++++++++++++------ 1 file changed, 98 insertions(+), 41 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 4ada5df68c..6d56cc99b6 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -14,7 +14,7 @@ MediaBrowser.Server.Mac.MainClass A personal media server - v4.5 + v4.6.1 true @@ -45,7 +45,7 @@ prompt 4 false - false + true true false Developer ID Application @@ -1494,6 +1494,18 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\mediainfo\rotten.png + + Resources\dashboard-ui\bower_components\emby-webcomponents\metadataeditor\metadataeditor.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\metadataeditor\metadataeditor.template.html + + + Resources\dashboard-ui\bower_components\emby-webcomponents\metadataeditor\personeditor.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\metadataeditor\personeditor.template.html + Resources\dashboard-ui\bower_components\emby-webcomponents\multiselect\multiselect.css @@ -1584,42 +1596,123 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\slideshow\style.css + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ar.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\bg-BG.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ca.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\cs.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\da.json Resources\dashboard-ui\bower_components\emby-webcomponents\strings\de.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\el.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\en-GB.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\en-US.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\es-AR.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\es-MX.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\es.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\fi.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\fr-CA.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\fr.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\gsw.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\he.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\hr.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\hu.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\id.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\it.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\kk.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ko.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ms.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\nb.json Resources\dashboard-ui\bower_components\emby-webcomponents\strings\nl.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\pl.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\pt-BR.json Resources\dashboard-ui\bower_components\emby-webcomponents\strings\pt-PT.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ro.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\ru.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\sk.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\sl-SI.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\sv.json + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\tr.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\uk.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\vi.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\zh-CN.json + + + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\zh-HK.json + Resources\dashboard-ui\bower_components\emby-webcomponents\strings\zh-TW.json @@ -2592,24 +2685,6 @@ Resources\dashboard-ui\bower_components\iron-validatable-behavior\test\test-validatable.html - - Resources\dashboard-ui\bower_components\isMobile\.bower.json - - - Resources\dashboard-ui\bower_components\isMobile\README.md - - - Resources\dashboard-ui\bower_components\isMobile\bower.json - - - Resources\dashboard-ui\bower_components\isMobile\isMobile.js - - - Resources\dashboard-ui\bower_components\isMobile\isMobile.min.js - - - Resources\dashboard-ui\bower_components\isMobile\package.json - Resources\dashboard-ui\bower_components\jquery\.bower.json @@ -3675,6 +3750,9 @@ Resources\dashboard-ui\components\channelmapper\channelmapper.js + + Resources\dashboard-ui\components\directorybrowser\directorybrowser.css + Resources\dashboard-ui\components\directorybrowser\directorybrowser.js @@ -3741,18 +3819,6 @@ Resources\dashboard-ui\components\medialibraryeditor\medialibraryeditor.template.html - - Resources\dashboard-ui\components\metadataeditor\metadataeditor.js - - - Resources\dashboard-ui\components\metadataeditor\metadataeditor.template.html - - - Resources\dashboard-ui\components\metadataeditor\personeditor.js - - - Resources\dashboard-ui\components\metadataeditor\personeditor.template.html - Resources\dashboard-ui\components\navdrawer\navdrawer.css @@ -3813,9 +3879,6 @@ Resources\dashboard-ui\css\tileitem.css - - Resources\dashboard-ui\css\fonts\Montserrat.woff - Resources\dashboard-ui\css\images\ani_equalizer_black.gif @@ -4089,9 +4152,6 @@ Resources\dashboard-ui\devices\ios\ios.css - - Resources\dashboard-ui\devices\windowsphone\wp.css - Resources\dashboard-ui\files\dummy.mp4 @@ -4185,9 +4245,6 @@ Resources\dashboard-ui\scripts\episodes.js - - Resources\dashboard-ui\scripts\extensions.js - Resources\dashboard-ui\scripts\externalplayer.js From f593230e446b011a9ed3c7a937cc173b3a4c819f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 16:22:30 -0400 Subject: [PATCH 029/220] fix current image deletion in image saver --- MediaBrowser.Providers/Manager/ImageSaver.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 465677efb6..3de3305578 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -133,6 +133,9 @@ namespace MediaBrowser.Providers.Manager source = memoryStream; var currentImage = GetCurrentImage(item, type, index); + var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile; + var currentImagePath = currentImage == null ? null : currentImage.Path; + var savedPaths = new List(); using (source) @@ -157,9 +160,9 @@ namespace MediaBrowser.Providers.Manager SetImagePath(item, type, imageIndex, savedPaths[0]); // Delete the current path - if (currentImage != null && currentImage.IsLocalFile && !savedPaths.Contains(currentImage.Path, StringComparer.OrdinalIgnoreCase)) + if (currentImageIsLocalFile && !savedPaths.Contains(currentImagePath, StringComparer.OrdinalIgnoreCase)) { - var currentPath = currentImage.Path; + var currentPath = currentImagePath; _logger.Debug("Deleting previous image {0}", currentPath); From 4ebe3a1f0dcb128557699cb0ecdc2279469700cc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jul 2016 16:24:35 -0400 Subject: [PATCH 030/220] restore version --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 3b18c027ea..8de20ebed3 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.80")] +[assembly: AssemblyVersion("3.1.*")] +//[assembly: AssemblyVersion("3.1.80")] From 2c861ca79388114a69a11107042f9ec4bb167eb9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jul 2016 01:19:24 -0400 Subject: [PATCH 031/220] update notifications --- .../MediaBrowser.WebDashboard.csproj | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5c520afcf2..554bfc2d4b 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1405,11 +1405,6 @@ PreserveNewest - - - PreserveNewest - - PreserveNewest @@ -1425,24 +1420,6 @@ PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - PreserveNewest From 2fb082cbf356a1c09f1537a41e55f4e8e9c50353 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jul 2016 01:55:47 -0400 Subject: [PATCH 032/220] update notifications --- .../MediaBrowser.WebDashboard.csproj | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 554bfc2d4b..46178dd9a0 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -242,12 +242,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -386,6 +380,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -785,9 +782,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1347,11 +1341,6 @@ PreserveNewest - - - PreserveNewest - - PreserveNewest @@ -1464,9 +1453,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 9b98d8b2e1e970a8ae23851c8c5f3155f6ff4e88 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jul 2016 02:29:14 -0400 Subject: [PATCH 033/220] update stream management --- MediaBrowser.Api/ApiEntryPoint.cs | 5 ++-- .../BaseProgressiveStreamingService.cs | 7 +++--- MediaBrowser.Api/Playback/StreamState.cs | 2 +- .../Library/MediaSourceManager.cs | 25 ++++++++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index dc811812ae..87fa3d46ca 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -126,9 +126,10 @@ namespace MediaBrowser.Api /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool dispose) { - var jobCount = _activeTranscodingJobs.Count; + var list = _activeTranscodingJobs.ToList(); + var jobCount = list.Count; - Parallel.ForEach(_activeTranscodingJobs.ToList(), j => KillTranscodingJob(j, false, path => true)); + Parallel.ForEach(list, j => KillTranscodingJob(j, false, path => true)); // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files if (jobCount > 0) diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index d75b8947a8..449100fc42 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -175,7 +175,9 @@ namespace MediaBrowser.Api.Playback.Progressive ResponseHeaders = responseHeaders, ContentType = contentType, IsHeadRequest = isHeadRequest, - Path = outputPath + Path = outputPath, + FileShare = FileShare.ReadWrite + }).ConfigureAwait(false); } finally @@ -187,8 +189,7 @@ namespace MediaBrowser.Api.Playback.Progressive // Need to start ffmpeg try { - return await GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource) - .ConfigureAwait(false); + return await GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource).ConfigureAwait(false); } catch { diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index da6be97b61..d97169fa5b 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -208,7 +208,7 @@ namespace MediaBrowser.Api.Playback private async void DisposeLiveStream() { - if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Request.LiveStreamId)) + if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Request.LiveStreamId) && !string.IsNullOrWhiteSpace(MediaSource.LiveStreamId)) { try { diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 4f3fe1bf3e..696bd0f4dc 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -446,8 +446,31 @@ namespace MediaBrowser.Server.Implementations.Library } } + private async Task CloseLiveStreamWithProvider(IMediaSourceProvider provider, string streamId, CancellationToken cancellationToken) + { + _logger.Info("Closing live stream {0} with provider {1}", streamId, provider.GetType().Name); + + try + { + await provider.CloseMediaSource(streamId, cancellationToken).ConfigureAwait(false); + } + catch (NotImplementedException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error closing live stream {0}", ex, streamId); + } + } + public async Task CloseLiveStream(string id, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException("id"); + } + await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try @@ -459,7 +482,7 @@ namespace MediaBrowser.Server.Implementations.Library { var tuple = GetProvider(id); - await tuple.Item1.CloseMediaSource(tuple.Item2, cancellationToken).ConfigureAwait(false); + await CloseLiveStreamWithProvider(tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false); } } From 74f511b2ee0dee5c8c5245e4c3d77c17daf67eb8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jul 2016 16:21:54 -0400 Subject: [PATCH 034/220] update components --- .../TV/EpisodeMetadataService.cs | 14 ++++++++++++++ MediaBrowser.Providers/TV/SeasonMetadataService.cs | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs index b51b113805..90a185ce00 100644 --- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs +++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs @@ -39,6 +39,20 @@ namespace MediaBrowser.Providers.TV updateType |= ItemUpdateType.MetadataImport; } } + if (updateType <= ItemUpdateType.None) + { + if (item.SeriesId != item.FindSeriesId()) + { + updateType |= ItemUpdateType.MetadataImport; + } + } + if (updateType <= ItemUpdateType.None) + { + if (item.SeasonId != item.FindSeasonId()) + { + updateType |= ItemUpdateType.MetadataImport; + } + } return updateType; } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index f3e6f8e9c5..addab3918e 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -49,6 +49,13 @@ namespace MediaBrowser.Providers.TV updateType |= ItemUpdateType.MetadataImport; } } + if (updateType <= ItemUpdateType.None) + { + if (item.SeriesId != item.FindSeriesId()) + { + updateType |= ItemUpdateType.MetadataImport; + } + } return updateType; } From c944d0d7cc44660ce7f172d5590b8540863efd60 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jul 2016 16:24:28 -0400 Subject: [PATCH 035/220] 3.1.81 --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 8de20ebed3..7f78e641ae 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.1.*")] -//[assembly: AssemblyVersion("3.1.80")] +//[assembly: AssemblyVersion("3.1.*")] +[assembly: AssemblyVersion("3.1.81")] From 100236f416e1917d57913f117b7f0c4ee9069d0b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jul 2016 11:59:37 -0400 Subject: [PATCH 036/220] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d81f6c71cb..7f78e641ae 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6010")] +[assembly: AssemblyVersion("3.1.81")] From 4be3ee433bf3d3d2a500a5b41b11407fb58b2445 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jul 2016 12:01:11 -0400 Subject: [PATCH 037/220] 3.0.6020 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7f78e641ae..d5d322353c 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.81")] +[assembly: AssemblyVersion("3.0.6020")] From 219cba75069cd2560e9571eee0c7f4a419256dab Mon Sep 17 00:00:00 2001 From: Sven Van den brande Date: Fri, 29 Jul 2016 21:18:03 +0200 Subject: [PATCH 038/220] Removed redundant Collection Initializers Removed Using directives that are not required --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 5 +---- .../Playback/Hls/BaseHlsService.cs | 1 - .../Progressive/ProgressiveStreamWriter.cs | 2 -- MediaBrowser.Api/UserLibrary/ArtistsService.cs | 2 -- .../UserLibrary/GameGenresService.cs | 2 -- MediaBrowser.Api/UserLibrary/GenresService.cs | 1 - MediaBrowser.Api/UserLibrary/ItemsService.cs | 3 +-- .../UserLibrary/MusicGenresService.cs | 2 -- MediaBrowser.Controller/Channels/Channel.cs | 5 +---- MediaBrowser.Controller/Entities/Folder.cs | 6 +----- MediaBrowser.Controller/Entities/IHasImages.cs | 3 +-- .../Entities/IItemByName.cs | 3 +-- MediaBrowser.Controller/Entities/MusicVideo.cs | 1 - MediaBrowser.Controller/Entities/TV/Season.cs | 1 - MediaBrowser.Controller/Entities/Trailer.cs | 2 -- .../Entities/UserRootFolder.cs | 2 -- .../Entities/UserViewBuilder.cs | 3 --- .../LiveTv/LiveTvProgram.cs | 1 - .../LiveTv/LiveTvVideoRecording.cs | 1 - .../LiveTv/TimerEventInfo.cs | 8 +------- .../LiveTv/TunerChannelMapping.cs | 8 +------- .../MediaEncoding/EncodingJobOptions.cs | 3 +-- .../MediaEncoding/IMediaEncoder.cs | 1 - .../Channels/DlnaChannelFactory.cs | 18 +----------------- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 2 -- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 1 - MediaBrowser.LocalMetadata/BaseXmlProvider.cs | 1 - .../Savers/BoxSetXmlSaver.cs | 2 +- .../Savers/FolderXmlSaver.cs | 2 +- .../Savers/GameSystemXmlSaver.cs | 2 +- .../BdInfo/BdInfoExaminer.cs | 2 +- .../Encoder/EncoderValidator.cs | 1 - MediaBrowser.Model/Dto/BaseItemDto.cs | 1 - MediaBrowser.Model/Dto/BaseItemPerson.cs | 3 +-- MediaBrowser.Model/Dto/UserDto.cs | 1 - MediaBrowser.Model/Dto/UserItemDataDto.cs | 1 - MediaBrowser.Model/Extensions/ListHelper.cs | 2 +- MediaBrowser.Model/LiveTv/ChannelInfoDto.cs | 1 - MediaBrowser.Model/Session/SessionInfoDto.cs | 1 - .../Folders/CollectionFolderMetadataService.cs | 6 +----- .../MediaInfo/VideoImageProvider.cs | 1 - .../Movies/MovieDbProvider.cs | 1 - .../Movies/MovieDbTrailerProvider.cs | 1 - .../Music/FanArtAlbumProvider.cs | 1 - .../Omdb/OmdbImageProvider.cs | 2 -- MediaBrowser.Providers/Omdb/OmdbProvider.cs | 1 - .../TV/MissingEpisodeProvider.cs | 8 ++------ .../TV/Omdb/OmdbEpisodeProvider.cs | 1 - .../TV/SeriesPostScanTask.cs | 1 - .../TV/TheTVDB/TvdbEpisodeImageProvider.cs | 1 - .../TV/TheTVDB/TvdbSeriesProvider.cs | 1 - .../Channels/ChannelManager.cs | 4 ++-- .../Dto/DtoService.cs | 5 ++--- .../EntryPoints/ExternalPortForwarding.cs | 2 -- .../EntryPoints/RecordingNotifier.cs | 3 --- .../IO/LibraryMonitor.cs | 2 -- .../Library/MediaSourceManager.cs | 3 +-- .../Library/Resolvers/TV/EpisodeResolver.cs | 1 - .../Library/UserDataManager.cs | 1 - .../Library/Validators/StudiosValidator.cs | 3 +-- .../Library/Validators/YearsPostScanTask.cs | 1 - .../LiveTv/EmbyTV/EmbyTV.cs | 3 --- .../LiveTv/Listings/XmlTvListingsProvider.cs | 1 - .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 2 -- .../LiveTv/TunerHosts/SatIp/SatIpHost.cs | 2 +- .../Persistence/DataExtensions.cs | 1 - .../Persistence/SqliteExtensions.cs | 5 ----- .../Sorting/DateLastMediaAddedComparer.cs | 1 - .../Sync/SyncJobProcessor.cs | 3 +-- .../Sync/SyncManager.cs | 2 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 4 +--- .../ApplicationHost.cs | 4 +--- .../Browser/BrowserLauncher.cs | 2 -- .../Migrations/CollectionGroupingMigration.cs | 6 +----- .../Migrations/CollectionsViewMigration.cs | 6 +----- MediaBrowser.ServerApplication/MainStartup.cs | 1 - .../Native/DbConnector.cs | 4 +--- .../Native/LnkShortcutHandler.cs | 3 --- .../Native/WindowsApp.cs | 1 - .../ConsistencyTests/StringUsageReporter.cs | 1 - .../TextIndexing/IndexBuilder.cs | 2 -- .../ConsistencyTests/TextIndexing/WordIndex.cs | 3 --- .../TextIndexing/WordOccurrence.cs | 8 +------- .../TextIndexing/WordOccurrences.cs | 6 +----- .../Providers/BaseNfoProvider.cs | 1 - 86 files changed, 36 insertions(+), 195 deletions(-) diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index c687758b72..91157cd11f 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -997,10 +997,7 @@ namespace MediaBrowser.Api.LiveTv public async Task Get(GetRecordingGroup request) { - var result = await _liveTvManager.GetRecordingGroups(new RecordingGroupQuery - { - - }, CancellationToken.None).ConfigureAwait(false); + var result = await _liveTvManager.GetRecordingGroups(new RecordingGroupQuery(), CancellationToken.None).ConfigureAwait(false); var group = result.Items.FirstOrDefault(i => string.Equals(i.Id, request.Id, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 3d8957086d..4ec14c96cb 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 860e57b32e..2019b73c86 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -1,7 +1,5 @@ using MediaBrowser.Model.Logging; -using ServiceStack.Web; using System; -using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index df73ef720b..ad031f483f 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -8,8 +8,6 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using ServiceStack; using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api.UserLibrary diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs index a0883f98cc..a0f3855c55 100644 --- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs @@ -4,11 +4,9 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; using ServiceStack; using System; using System.Collections.Generic; -using System.Linq; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api.UserLibrary diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 57c11a1fad..ec2bc6bda5 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -8,7 +8,6 @@ using MediaBrowser.Model.Entities; using ServiceStack; using System; using System.Collections.Generic; -using System.Linq; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api.UserLibrary diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index b4d88a7f89..97a81b7909 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Collections; -using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs index 887c999411..b2eba070fc 100644 --- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs @@ -8,8 +8,6 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using ServiceStack; using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api.UserLibrary diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 718a0d8786..e0b7204b87 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -57,10 +57,7 @@ namespace MediaBrowser.Controller.Channels catch { // Already logged at lower levels - return new QueryResult - { - - }; + return new QueryResult(); } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 0397e9a88e..6a7e279be8 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Progress; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; @@ -919,10 +918,7 @@ namespace MediaBrowser.Controller.Entities catch { // Already logged at lower levels - return new QueryResult - { - - }; + return new QueryResult(); } } diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 2267480985..a38b7394dd 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -1,5 +1,4 @@ -using System; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Threading; diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index 2ac4af1af7..b69c8bdfcc 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index 7119828e26..8b749b7a5d 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -1,7 +1,6 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Runtime.Serialization; diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ee01c60b1b..f6ca19005b 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -1,6 +1,5 @@ using System; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Users; using MoreLinq; diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index eab5ab6794..6604be977d 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -2,9 +2,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System.Collections.Generic; -using System.Globalization; using System.Runtime.Serialization; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Model.Providers; namespace MediaBrowser.Controller.Entities diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 8e6f11c2ce..4549d0d1df 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -1,6 +1,5 @@ using System.Runtime.Serialization; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; using System; @@ -8,7 +7,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Library; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index e2228bcaf6..11ed269317 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -14,12 +13,10 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.Configuration; using MoreLinq; namespace MediaBrowser.Controller.Entities diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 74c9932480..c7f47b825b 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index a8c7376734..f4dba070dc 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs index 0e1a054754..642dee3af8 100644 --- a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.LiveTv +namespace MediaBrowser.Controller.LiveTv { public class TimerEventInfo { diff --git a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs index da0527eeaf..c1d1c413e8 100644 --- a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs +++ b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.LiveTv +namespace MediaBrowser.Controller.LiveTv { public class TunerChannelMapping { diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs index 44b7417553..844fafcdec 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs @@ -1,5 +1,4 @@ -using System.Linq; -using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Dlna; namespace MediaBrowser.Controller.MediaEncoding { diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index c8a8caa917..05e82a16e7 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -1,7 +1,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.MediaInfo; using System; -using System.IO; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Dlna; diff --git a/MediaBrowser.Dlna/Channels/DlnaChannelFactory.cs b/MediaBrowser.Dlna/Channels/DlnaChannelFactory.cs index a8e778751d..06856989f3 100644 --- a/MediaBrowser.Dlna/Channels/DlnaChannelFactory.cs +++ b/MediaBrowser.Dlna/Channels/DlnaChannelFactory.cs @@ -1,20 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Dlna.ContentDirectory; -using MediaBrowser.Dlna.PlayTo; -using MediaBrowser.Model.Channels; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Dlna.Channels +namespace MediaBrowser.Dlna.Channels { //public class DlnaChannel : IChannel, IDisposable //{ diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index b9d9944eca..fbd027ccf3 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -14,10 +14,8 @@ using MediaBrowser.Dlna.Ssdp; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Dlna.Channels; namespace MediaBrowser.Dlna.Main { diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 0e791eb981..720ea71a08 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Dlna.Server; using MediaBrowser.Model.Logging; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; diff --git a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs index 4b64295ea6..0289ffb083 100644 --- a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs @@ -1,6 +1,5 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; -using System; using System.IO; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs index 31a2901b72..b307ded972 100644 --- a/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BoxSetXmlSaver.cs @@ -65,7 +65,7 @@ namespace MediaBrowser.LocalMetadata.Savers var xmlFilePath = GetSavePath(item); - XmlSaverHelpers.Save(builder, xmlFilePath, new List { }, _config, _fileSystem); + XmlSaverHelpers.Save(builder, xmlFilePath, new List(), _config, _fileSystem); } /// diff --git a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs index 056bd49a86..8dad16fc24 100644 --- a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.LocalMetadata.Savers var xmlFilePath = GetSavePath(item); - XmlSaverHelpers.Save(builder, xmlFilePath, new List { }, _config, _fileSystem); + XmlSaverHelpers.Save(builder, xmlFilePath, new List(), _config, _fileSystem); } /// diff --git a/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs index dea4721afa..ddfaedba68 100644 --- a/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/GameSystemXmlSaver.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.LocalMetadata.Savers var xmlFilePath = GetSavePath(item); - XmlSaverHelpers.Save(builder, xmlFilePath, new List { }, _config, _fileSystem); + XmlSaverHelpers.Save(builder, xmlFilePath, new List(), _config, _fileSystem); } /// diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs index b15b8d15dd..e435c00f23 100644 --- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs +++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo outputStream.RunTimeTicks = TimeSpan.FromSeconds(playlist.TotalLength).Ticks; - var mediaStreams = new List { }; + var mediaStreams = new List(); foreach (var stream in playlist.SortedStreams) { diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 0866bd255a..50df08e66a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using MediaBrowser.Model.Logging; namespace MediaBrowser.MediaEncoding.Encoder diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 8ca1dfcb1e..6edf743fbb 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -7,7 +7,6 @@ using MediaBrowser.Model.Providers; using MediaBrowser.Model.Sync; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; diff --git a/MediaBrowser.Model/Dto/BaseItemPerson.cs b/MediaBrowser.Model/Dto/BaseItemPerson.cs index b749129079..7052f1b82c 100644 --- a/MediaBrowser.Model/Dto/BaseItemPerson.cs +++ b/MediaBrowser.Model/Dto/BaseItemPerson.cs @@ -1,5 +1,4 @@ -using System.ComponentModel; -using System.Diagnostics; +using System.Diagnostics; using System.Runtime.Serialization; namespace MediaBrowser.Model.Dto diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs index 18470466c7..94e4f95a3f 100644 --- a/MediaBrowser.Model/Dto/UserDto.cs +++ b/MediaBrowser.Model/Dto/UserDto.cs @@ -2,7 +2,6 @@ using MediaBrowser.Model.Connect; using MediaBrowser.Model.Users; using System; -using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; diff --git a/MediaBrowser.Model/Dto/UserItemDataDto.cs b/MediaBrowser.Model/Dto/UserItemDataDto.cs index 00491002b4..507dbb06d9 100644 --- a/MediaBrowser.Model/Dto/UserItemDataDto.cs +++ b/MediaBrowser.Model/Dto/UserItemDataDto.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; namespace MediaBrowser.Model.Dto { diff --git a/MediaBrowser.Model/Extensions/ListHelper.cs b/MediaBrowser.Model/Extensions/ListHelper.cs index 741f07469c..711e0ce9cc 100644 --- a/MediaBrowser.Model/Extensions/ListHelper.cs +++ b/MediaBrowser.Model/Extensions/ListHelper.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Extensions { if (value == null) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } return list.Contains(value, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs index aa91e3c747..8991aad866 100644 --- a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs @@ -2,7 +2,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Library; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs index 5c3c9a79c4..42263c6442 100644 --- a/MediaBrowser.Model/Session/SessionInfoDto.cs +++ b/MediaBrowser.Model/Session/SessionInfoDto.cs @@ -1,7 +1,6 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; namespace MediaBrowser.Model.Session diff --git a/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs b/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs index 35c61b5c58..cdaa383667 100644 --- a/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs +++ b/MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using CommonIO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 5fc3630627..fb08f00c19 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -10,7 +10,6 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 27b61225bd..b0d119ff98 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs index 1d8691ab8e..81df7b805c 100644 --- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Providers; -using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index a14c7123a0..2f09d64af0 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; -using MediaBrowser.Providers.TV; using System; using System.Collections.Generic; using System.Globalization; diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs index 5631189403..90d172bc2c 100644 --- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs @@ -10,8 +10,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; using System.Collections.Generic; -using System.IO; -using System.Text; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index 0379313005..f3766f007b 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -1,5 +1,4 @@ using CommonIO; -using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 22e1267952..afa1abbbb9 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -135,9 +135,7 @@ namespace MediaBrowser.Providers.TV { var directoryService = new DirectoryService(_fileSystem); - await series.RefreshMetadata(new MetadataRefreshOptions(directoryService) - { - }, cancellationToken).ConfigureAwait(false); + await series.RefreshMetadata(new MetadataRefreshOptions(directoryService), cancellationToken).ConfigureAwait(false); await series.ValidateChildren(new Progress(), cancellationToken, new MetadataRefreshOptions(directoryService), true) .ConfigureAwait(false); @@ -438,9 +436,7 @@ namespace MediaBrowser.Providers.TV await season.AddChild(episode, cancellationToken).ConfigureAwait(false); - await episode.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) - { - }, cancellationToken).ConfigureAwait(false); + await episode.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs index 64e30f47f8..621f665146 100644 --- a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs @@ -10,7 +10,6 @@ using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; using MediaBrowser.Providers.Omdb; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index d044c828ff..d6ae84b91b 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -14,7 +14,6 @@ using CommonIO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Tasks; namespace MediaBrowser.Providers.TV { diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs index 8815132864..a0280cf409 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; -using System; using System.Collections.Generic; using System.Globalization; using System.Linq; diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index b6cc8777d8..66a02eba21 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -5,7 +5,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index 41592865c0..bb7e142b68 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -657,7 +657,7 @@ namespace MediaBrowser.Server.Implementations.Channels _logger.ErrorException("Error getting all media from {0}", ex, i.Name); } } - return new Tuple(i, new ChannelItemResult { }); + return new Tuple(i, new ChannelItemResult()); }); var results = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -811,7 +811,7 @@ namespace MediaBrowser.Server.Implementations.Channels _logger.ErrorException("Error getting all media from {0}", ex, i.Name); } } - return new Tuple(i, new ChannelItemResult { }); + return new Tuple(i, new ChannelItemResult()); }); var results = await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 616625bc9c..f17f5e5a2f 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -11,7 +11,6 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Drawing; @@ -102,8 +101,8 @@ namespace MediaBrowser.Server.Implementations.Dto var syncDictionary = GetSyncedItemProgressDictionary(syncJobItems); var list = new List(); - var programTuples = new List> { }; - var channelTuples = new List> { }; + var programTuples = new List>(); + var channelTuples = new List>(); foreach (var item in items) { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 50ad3cfbc6..64e3c56a63 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -7,9 +7,7 @@ using Mono.Nat; using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Net; -using System.Text; using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs index cc4ef1972e..620eea774e 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Plugins; diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 99cb80cb25..8c2b927e3a 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -5,14 +5,12 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.ScheduledTasks; using Microsoft.Win32; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 696bd0f4dc..4a533ff93c 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -278,8 +278,7 @@ namespace MediaBrowser.Server.Implementations.Library } var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference) - ? new List { } - : new List { user.Configuration.SubtitleLanguagePreference }; + ? new List() : new List { user.Configuration.SubtitleLanguagePreference }; var defaultAudioIndex = source.DefaultAudioStreamIndex; var audioLangage = defaultAudioIndex == null diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 7b8832c594..2f940eb1d8 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using System.Linq; diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index 715f3c522d..307cf4cd2f 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -10,7 +10,6 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index c1803b5e4c..e697dbd90b 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs index 7f52a4506f..164b142234 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs @@ -1,7 +1,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; -using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 8f56554f10..a36eae8d22 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -12,7 +12,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; -using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -26,8 +25,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Power; diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 1e82e3fce2..d1d8df2e81 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -11,7 +11,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Emby.XmlTv.Classes; -using Emby.XmlTv.Entities; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 2a974b5459..5b83e7cbe8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -141,7 +141,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return new List { mediaSource }; } - return new List { }; + return new List(); } protected override Task IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index d0a55966f3..43f48b37bf 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -1,6 +1,4 @@ using System; -using System.Globalization; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 1e571c84fb..b1e349a862 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -110,7 +110,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp return new List { mediaSource }; } - return new List { }; + return new List(); } protected override async Task GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs index 61ce6e351b..a16d237005 100644 --- a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs @@ -4,7 +4,6 @@ using MediaBrowser.Model.Serialization; using System; using System.Data; using System.IO; -using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Persistence { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs index d5b582da56..c273d49458 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -1,12 +1,7 @@ using System; -using System.Collections.Generic; using System.Data; using System.Data.SQLite; -using System.Linq; -using System.Text; using System.Threading.Tasks; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Persistence diff --git a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs index e8c78b8e73..5080edffd5 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Querying; using System; -using System.Linq; namespace MediaBrowser.Server.Implementations.Sorting { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e120d3a4dc..d5dfd38569 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -951,8 +951,7 @@ namespace MediaBrowser.Server.Implementations.Sync : new[] { user.Configuration.AudioLanguagePreference }; var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference) - ? new List { } - : new List { user.Configuration.SubtitleLanguagePreference }; + ? new List() : new List { user.Configuration.SubtitleLanguagePreference }; foreach (var source in mediaSources) { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 38edc30240..92221ffbad 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.Sync UserId = request.UserId, UnwatchedOnly = request.UnwatchedOnly, ItemLimit = request.ItemLimit, - RequestedItemIds = request.ItemIds ?? new List { }, + RequestedItemIds = request.ItemIds ?? new List(), DateCreated = DateTime.UtcNow, DateLastModified = DateTime.UtcNow, SyncNewContent = request.SyncNewContent, diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs index 5ad3ecfef2..39b53b3709 100644 --- a/MediaBrowser.Server.Mono/Native/DbConnector.cs +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -1,6 +1,4 @@ -using System; -using System.Data; -using System.Data.SQLite; +using System.Data; using System.Threading.Tasks; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.Persistence; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index b7ea5bdad8..3f1f98cd00 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -362,9 +362,7 @@ namespace MediaBrowser.Server.Startup.Common private void PerformPreInitMigrations() { - var migrations = new List - { - }; + var migrations = new List(); foreach (var task in migrations) { diff --git a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs index db48d1110e..6b3602a73d 100644 --- a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs +++ b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs @@ -1,7 +1,5 @@ using MediaBrowser.Controller; -using MediaBrowser.Model.Logging; using System; -using System.Diagnostics; namespace MediaBrowser.Server.Startup.Common.Browser { diff --git a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs index b497eeb424..5041c49b8b 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; diff --git a/MediaBrowser.Server.Startup.Common/Migrations/CollectionsViewMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/CollectionsViewMigration.cs index c6186ce081..3f68ec48b3 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/CollectionsViewMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/CollectionsViewMigration.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index bdfd7d1bb0..a87ad7dbf7 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -19,7 +19,6 @@ 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; diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs index 9aaa96a804..f403ce2ce4 100644 --- a/MediaBrowser.ServerApplication/Native/DbConnector.cs +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -1,6 +1,4 @@ -using System; -using System.Data; -using System.Data.SQLite; +using System.Data; using System.Threading.Tasks; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.Persistence; diff --git a/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs b/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs index 67d2e83f0e..dc1e3c79b2 100644 --- a/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs +++ b/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs @@ -1,11 +1,8 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Security; using System.Text; -using System.Threading.Tasks; using CommonIO; namespace MediaBrowser.ServerApplication.Native diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index d8b2720c2c..3c9c04acbf 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; -using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; using MediaBrowser.Model.System; diff --git a/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs index d036a6c6d7..bea709c5c8 100644 --- a/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs +++ b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; using System.Xml; namespace MediaBrowser.Tests.ConsistencyTests diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs index 07c0df86c7..e88e3ae292 100644 --- a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/IndexBuilder.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing { diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs index 4ced812373..60b88dd5e0 100644 --- a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordIndex.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing { diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs index 40631f5825..7564d90f3c 100644 --- a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrence.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing +namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing { public struct WordOccurrence { diff --git a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs index 3ba3b59167..821a74d21b 100644 --- a/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs +++ b/MediaBrowser.Tests/ConsistencyTests/TextIndexing/WordOccurrences.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; namespace MediaBrowser.Tests.ConsistencyTests.TextIndexing { diff --git a/MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs index c1dd929877..f3c40a1696 100644 --- a/MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs @@ -1,7 +1,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.XbmcMetadata.Savers; -using System; using System.IO; using System.Threading; using System.Threading.Tasks; From d174f641836eea232885a45dec86ab0a9f3c9f4b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jul 2016 16:06:58 -0400 Subject: [PATCH 039/220] begin unifying card layouts --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 46178dd9a0..a07f56e2bd 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -671,9 +671,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From f7c3ee1c6800d98ab1f71a7807a962c682254625 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sat, 30 Jul 2016 01:44:14 +0200 Subject: [PATCH 040/220] Fix: Emby notification icon remained visible after shutdown Also implemented the recommended pattern for IDisposable. --- MediaBrowser.ServerApplication/MainStartup.cs | 6 ++ .../ServerNotifyIcon.cs | 65 +++++-------------- 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index bdfd7d1bb0..aba4952f39 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -619,6 +619,12 @@ namespace MediaBrowser.ServerApplication private static void ShutdownWindowsApplication() { + if (_serverNotifyIcon != null) + { + _serverNotifyIcon.Dispose(); + _serverNotifyIcon = null; + } + //_logger.Info("Calling Application.Exit"); //Application.Exit(); diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index 27816db5a4..d04128a18c 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -4,14 +4,13 @@ using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common.Browser; using System; +using System.ComponentModel; using System.Windows.Forms; namespace MediaBrowser.ServerApplication { public class ServerNotifyIcon : IDisposable { - bool IsDisposing = false; - private NotifyIcon notifyIcon1; private ContextMenuStrip contextMenuStrip1; private ToolStripMenuItem cmdExit; @@ -21,25 +20,13 @@ namespace MediaBrowser.ServerApplication private ToolStripMenuItem cmdRestart; private ToolStripSeparator toolStripSeparator1; private ToolStripMenuItem cmdCommunity; + private Container components; private readonly ILogger _logger; private readonly IServerApplicationHost _appHost; private readonly IServerConfigurationManager _configurationManager; private readonly ILocalizationManager _localization; - public bool Visible - { - get - { - return notifyIcon1.Visible; - } - set - { - Action act = () => notifyIcon1.Visible = false; - Invoke(act); - } - } - public void Invoke(Action action) { contextMenuStrip1.Invoke(action); @@ -55,7 +42,7 @@ namespace MediaBrowser.ServerApplication _appHost = appHost; _configurationManager = configurationManager; - var components = new System.ComponentModel.Container(); + components = new System.ComponentModel.Container(); var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); contextMenuStrip1 = new ContextMenuStrip(components); @@ -138,32 +125,6 @@ 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 - { - notifyIcon1.Visible = false; - } - catch - { - - } } void notifyIcon1_DoubleClick(object sender, EventArgs e) @@ -222,16 +183,26 @@ namespace MediaBrowser.ServerApplication _appHost.Shutdown(); } - ~ServerNotifyIcon() + public void Dispose() { - Dispose(); + Dispose(true); } - public void Dispose() + protected virtual void Dispose(bool disposing) { - if (!IsDisposing) + if (disposing) { - IsDisposing = true; + if (notifyIcon1 != null) + { + notifyIcon1.Visible = false; + notifyIcon1.Dispose(); + notifyIcon1 = null; + } + + if (components != null) + { + components.Dispose(); + } } } } From 6af3dc91c5595c6a440f5597bd4269751cf4102a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jul 2016 00:21:26 -0400 Subject: [PATCH 041/220] adjust audio transcoding bitrate --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index c05ca41878..80e81a41a4 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -600,18 +600,22 @@ namespace MediaBrowser.Model.Dlna { defaultBitrate = 192000; } + if (!string.IsNullOrEmpty(targetAudioCodec) && audioStream != null && StringHelper.EqualsIgnoreCase(audioStream.Codec, targetAudioCodec)) + { + defaultBitrate = audioStream.BitRate ?? defaultBitrate; + } if (targetAudioChannels.HasValue) { - if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 2000000) + if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1500000) { if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) { - defaultBitrate = 448000; + defaultBitrate = Math.Max(448000, defaultBitrate); } else { - defaultBitrate = 320000; + defaultBitrate = Math.Max(320000, defaultBitrate); } } } From 1bd3b22c811bea35bb2779d8f6e322e074bd47cc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jul 2016 13:52:06 -0400 Subject: [PATCH 042/220] update service stack config --- .../HttpServer/HttpListenerHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 17e4793cb5..4121c5e5e6 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -67,6 +67,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer public override void Configure(Container container) { HostConfig.Instance.DefaultRedirectPath = DefaultRedirectPath; + HostConfig.Instance.LogUnobservedTaskExceptions = false; HostConfig.Instance.MapExceptionToStatusCode = new Dictionary { @@ -80,7 +81,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer {typeof (ApplicationException), 500} }; - HostConfig.Instance.DebugMode = true; + HostConfig.Instance.DebugMode = false; HostConfig.Instance.LogFactory = LogManager.LogFactory; From 62b0c2605f66f319d093ac6feb5a0d52d7c4aafb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jul 2016 15:19:46 -0400 Subject: [PATCH 043/220] remove nameof --- MediaBrowser.Model/Extensions/ListHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Model/Extensions/ListHelper.cs b/MediaBrowser.Model/Extensions/ListHelper.cs index 711e0ce9cc..741f07469c 100644 --- a/MediaBrowser.Model/Extensions/ListHelper.cs +++ b/MediaBrowser.Model/Extensions/ListHelper.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Extensions { if (value == null) { - throw new ArgumentNullException(nameof(value)); + throw new ArgumentNullException("value"); } return list.Contains(value, StringComparer.OrdinalIgnoreCase); From 235d341524cfc3f65fea6617a3fd51840ea1a130 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jul 2016 15:22:35 -0400 Subject: [PATCH 044/220] force audio stream copy when audio transcoding is not allowed --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ce3691095c..ab73aabe43 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1788,6 +1788,19 @@ namespace MediaBrowser.Api.Playback { state.OutputAudioCodec = "copy"; } + else + { + // If the user doesn't have access to transcoding, then force stream copy, regardless of whether it will be compatible or not + var auth = AuthorizationContext.GetAuthorizationInfo(Request); + if (!string.IsNullOrWhiteSpace(auth.UserId)) + { + var user = UserManager.GetUserById(auth.UserId); + if (!user.Policy.EnableAudioPlaybackTranscoding) + { + state.OutputAudioCodec = "copy"; + } + } + } } private void AttachMediaSourceInfo(StreamState state, From a0d65d7e8cd1a9198415d663e9c215dcd4841e32 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jul 2016 19:26:08 -0400 Subject: [PATCH 045/220] 3.1.82 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7f78e641ae..2a3b8e0e5f 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.81")] +[assembly: AssemblyVersion("3.1.82")] From bbd4431f79c8c328cd3793d010e41c371fc5ec1b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jul 2016 00:11:23 -0400 Subject: [PATCH 046/220] update shared components --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a07f56e2bd..9e47a0b1e3 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -194,12 +194,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest From 733beb8516f0677cd27f8bc26dd322edab73cbc3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jul 2016 01:27:56 -0400 Subject: [PATCH 047/220] 3.1.83 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 2a3b8e0e5f..1c50f596ae 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.82")] +[assembly: AssemblyVersion("3.1.83")] From b4ad3a1658f4dbc3dad1ec3f2afdcf346484a836 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jul 2016 02:21:49 -0400 Subject: [PATCH 048/220] removed dead code --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 9e47a0b1e3..cc064dc813 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -800,9 +800,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From fc9f6c2eb5a4276e8a3fe06ec936303a0a609247 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jul 2016 15:08:54 -0400 Subject: [PATCH 049/220] 3.1.84 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 1c50f596ae..185d1ccbd5 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.83")] +[assembly: AssemblyVersion("3.1.84")] From ba6cba0b7f28496280a0bedb68dd60ab35d2e256 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 31 Jul 2016 16:58:40 -0400 Subject: [PATCH 050/220] update mac project --- .../Emby.Server.Mac.csproj | 102 ++---------------- 1 file changed, 9 insertions(+), 93 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 6d56cc99b6..3c16eacfe4 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -618,6 +618,9 @@ Resources\dashboard-ui\serversecurity.html + + Resources\dashboard-ui\serviceworker.js + Resources\dashboard-ui\shared.html @@ -1011,9 +1014,6 @@ Resources\dashboard-ui\bower_components\emby-apiclient\connectionmanager.js - - Resources\dashboard-ui\bower_components\emby-apiclient\connectservice.js - Resources\dashboard-ui\bower_components\emby-apiclient\credentials.js @@ -1107,9 +1107,6 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\layoutmanager.js - - Resources\dashboard-ui\bower_components\emby-webcomponents\librarychangednotifications.js - Resources\dashboard-ui\bower_components\emby-webcomponents\multidownload.js @@ -1512,6 +1509,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\multiselect\multiselect.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\notifications\notificationicon.png + + + Resources\dashboard-ui\bower_components\emby-webcomponents\notifications\notifications.js + Resources\dashboard-ui\bower_components\emby-webcomponents\page.js\page.js @@ -2499,63 +2502,6 @@ Resources\dashboard-ui\bower_components\iron-input\test\letters-only.html - - Resources\dashboard-ui\bower_components\iron-location\.bower.json - - - Resources\dashboard-ui\bower_components\iron-location\.gitignore - - - Resources\dashboard-ui\bower_components\iron-location\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-location\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-location\README.md - - - Resources\dashboard-ui\bower_components\iron-location\bower.json - - - Resources\dashboard-ui\bower_components\iron-location\index.html - - - Resources\dashboard-ui\bower_components\iron-location\iron-location.html - - - Resources\dashboard-ui\bower_components\iron-location\iron-query-params.html - - - Resources\dashboard-ui\bower_components\iron-location\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-location\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-location\demo\iron-query-params.html - - - Resources\dashboard-ui\bower_components\iron-location\test\index.html - - - Resources\dashboard-ui\bower_components\iron-location\test\initialization-cases.html - - - Resources\dashboard-ui\bower_components\iron-location\test\initialization-iframe.html - - - Resources\dashboard-ui\bower_components\iron-location\test\initialization-tests.html - - - Resources\dashboard-ui\bower_components\iron-location\test\iron-location.html - - - Resources\dashboard-ui\bower_components\iron-location\test\iron-query-params.html - - - Resources\dashboard-ui\bower_components\iron-location\test\redirection.html - Resources\dashboard-ui\bower_components\iron-meta\.bower.json @@ -3885,9 +3831,6 @@ Resources\dashboard-ui\css\images\ani_equalizer_white.gif - - Resources\dashboard-ui\css\images\checkmarkblack.png - Resources\dashboard-ui\css\images\checkmarkgreen.png @@ -3921,15 +3864,6 @@ Resources\dashboard-ui\css\images\rotten.png - - Resources\dashboard-ui\css\images\splash.jpg - - - Resources\dashboard-ui\css\images\splash720.jpg - - - Resources\dashboard-ui\css\images\stars.png - Resources\dashboard-ui\css\images\touchicon.png @@ -4023,9 +3957,6 @@ Resources\dashboard-ui\css\images\items\list\person.png - - Resources\dashboard-ui\css\images\items\searchhintsv2\tv.png - Resources\dashboard-ui\css\images\media\chapterflyout.png @@ -4035,21 +3966,6 @@ Resources\dashboard-ui\css\images\media\play.png - - Resources\dashboard-ui\css\images\notifications\cancelled.png - - - Resources\dashboard-ui\css\images\notifications\done.png - - - Resources\dashboard-ui\css\images\notifications\download.png - - - Resources\dashboard-ui\css\images\notifications\error.png - - - Resources\dashboard-ui\css\images\notifications\info.png - Resources\dashboard-ui\css\images\supporter\nonsupporterbadge.png From 332426ddffe89fcd6bddb8f074167d10f04f6838 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Aug 2016 01:08:31 -0400 Subject: [PATCH 051/220] update SocketHttpListener --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 2c4c74b35c..3ec95633bf 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -73,8 +73,8 @@ ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True - - ..\packages\SocketHttpListener.1.0.0.35\lib\net45\SocketHttpListener.dll + + ..\packages\SocketHttpListener.1.0.0.36\lib\net45\SocketHttpListener.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 03f7160ae0..84be864b7b 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -9,5 +9,5 @@ - + \ No newline at end of file From 5f71a615c4fbe5500dee2a7e8f3702039fd16375 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Aug 2016 01:08:52 -0400 Subject: [PATCH 052/220] reduce file system access by dlna manager --- MediaBrowser.Dlna/DlnaManager.cs | 110 +++++++++--------- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 8 +- MediaBrowser.Dlna/Profiles/LgTvProfile.cs | 2 +- MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml | 6 +- MediaBrowser.Dlna/Profiles/Xml/Default.xml | 6 +- MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml | 6 +- .../Profiles/Xml/DirecTV HD-DVR.xml | 6 +- .../Profiles/Xml/Dish Hopper-Joey.xml | 10 +- MediaBrowser.Dlna/Profiles/Xml/Kodi.xml | 6 +- .../Profiles/Xml/LG Smart TV.xml | 9 +- .../Profiles/Xml/Linksys DMA2100.xml | 6 +- .../Profiles/Xml/MediaMonkey.xml | 6 +- .../Profiles/Xml/Panasonic Viera.xml | 7 +- .../Profiles/Xml/Popcorn Hour.xml | 11 +- .../Profiles/Xml/Samsung Smart TV.xml | 11 +- .../Profiles/Xml/Sony Blu-ray Player 2013.xml | 8 +- .../Profiles/Xml/Sony Blu-ray Player.xml | 9 +- .../Profiles/Xml/Sony Bravia (2010).xml | 12 +- .../Profiles/Xml/Sony Bravia (2011).xml | 12 +- .../Profiles/Xml/Sony Bravia (2012).xml | 9 +- .../Profiles/Xml/Sony Bravia (2013).xml | 8 +- .../Profiles/Xml/Sony Bravia (2014).xml | 8 +- .../Profiles/Xml/Sony PlayStation 3.xml | 10 +- .../Profiles/Xml/Sony PlayStation 4.xml | 10 +- MediaBrowser.Dlna/Profiles/Xml/Vlc.xml | 6 +- MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 11 +- MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 12 +- MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml | 6 +- 29 files changed, 204 insertions(+), 135 deletions(-) diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index b4127a91f1..42e976ce8b 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Dlna private readonly IJsonSerializer _jsonSerializer; private readonly IServerApplicationHost _appHost; - private readonly Dictionary _profiles = new Dictionary(StringComparer.Ordinal); + private readonly Dictionary> _profiles = new Dictionary>(StringComparer.Ordinal); public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, @@ -45,50 +45,40 @@ namespace MediaBrowser.Dlna _appHost = appHost; } - public IEnumerable GetProfiles() + public void InitProfiles() { - ExtractProfilesIfNeeded(); + try + { + ExtractSystemProfiles(); + LoadProfiles(); + } + catch (Exception ex) + { + _logger.ErrorException("Error extracting DLNA profiles.", ex); + } + } + private void LoadProfiles() + { var list = GetProfiles(UserProfilesPath, DeviceProfileType.User) .OrderBy(i => i.Name) .ToList(); list.AddRange(GetProfiles(SystemProfilesPath, DeviceProfileType.System) .OrderBy(i => i.Name)); - - return list; } - private bool _extracted; - private readonly object _syncLock = new object(); - private void ExtractProfilesIfNeeded() + public IEnumerable GetProfiles() { - if (!_extracted) + lock (_profiles) { - lock (_syncLock) - { - if (!_extracted) - { - try - { - ExtractSystemProfiles(); - } - catch (Exception ex) - { - _logger.ErrorException("Error extracting DLNA profiles.", ex); - } - - _extracted = true; - } - - } + var list = _profiles.Values.ToList(); + return list.Select(i => i.Item2).OrderBy(i => i.Name); } } public DeviceProfile GetDefaultProfile() { - ExtractProfilesIfNeeded(); - return new DefaultProfile(); } @@ -304,20 +294,20 @@ namespace MediaBrowser.Dlna { lock (_profiles) { - DeviceProfile profile; - if (_profiles.TryGetValue(path, out profile)) + Tuple profileTuple; + if (_profiles.TryGetValue(path, out profileTuple)) { - return profile; + return profileTuple.Item2; } try { - profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path); + var profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path); profile.Id = path.ToLower().GetMD5().ToString("N"); profile.ProfileType = type; - _profiles[path] = profile; + _profiles[path] = new Tuple(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile); return profile; } @@ -344,12 +334,14 @@ namespace MediaBrowser.Dlna private IEnumerable GetProfileInfosInternal() { - ExtractProfilesIfNeeded(); - - return GetProfileInfos(UserProfilesPath, DeviceProfileType.User) - .Concat(GetProfileInfos(SystemProfilesPath, DeviceProfileType.System)) - .OrderBy(i => i.Info.Type == DeviceProfileType.User ? 0 : 1) - .ThenBy(i => i.Info.Name); + lock (_profiles) + { + var list = _profiles.Values.ToList(); + return list + .Select(i => i.Item1) + .OrderBy(i => i.Info.Type == DeviceProfileType.User ? 0 : 1) + .ThenBy(i => i.Info.Name); + } } public IEnumerable GetProfileInfos() @@ -363,17 +355,7 @@ namespace MediaBrowser.Dlna { return _fileSystem.GetFiles(path) .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) - .Select(i => new InternalProfileInfo - { - Path = i.FullName, - - Info = new DeviceProfileInfo - { - Id = i.FullName.ToLower().GetMD5().ToString("N"), - Name = _fileSystem.GetFileNameWithoutExtension(i), - Type = type - } - }) + .Select(i => GetInternalProfileInfo(i, type)) .ToList(); } catch (DirectoryNotFoundException) @@ -382,6 +364,21 @@ namespace MediaBrowser.Dlna } } + private InternalProfileInfo GetInternalProfileInfo(FileSystemMetadata file, DeviceProfileType type) + { + return new InternalProfileInfo + { + Path = file.FullName, + + Info = new DeviceProfileInfo + { + Id = file.FullName.ToLower().GetMD5().ToString("N"), + Name = _fileSystem.GetFileNameWithoutExtension(file), + Type = type + } + }; + } + private void ExtractSystemProfiles() { var assembly = GetType().Assembly; @@ -427,6 +424,11 @@ namespace MediaBrowser.Dlna } _fileSystem.DeleteFile(info.Path); + + lock (_profiles) + { + _profiles.Remove(info.Path); + } } public void CreateProfile(DeviceProfile profile) @@ -441,7 +443,7 @@ namespace MediaBrowser.Dlna var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml"; var path = Path.Combine(UserProfilesPath, newFilename); - SaveProfile(profile, path); + SaveProfile(profile, path, DeviceProfileType.User); } public void UpdateProfile(DeviceProfile profile) @@ -468,14 +470,14 @@ namespace MediaBrowser.Dlna _fileSystem.DeleteFile(current.Path); } - SaveProfile(profile, path); + SaveProfile(profile, path, DeviceProfileType.User); } - private void SaveProfile(DeviceProfile profile, string path) + private void SaveProfile(DeviceProfile profile, string path, DeviceProfileType type) { lock (_profiles) { - _profiles[path] = profile; + _profiles[path] = new Tuple(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile); } _xmlSerializer.SerializeToFile(profile, path); } diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index fbd027ccf3..9f2726b315 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -80,6 +80,8 @@ namespace MediaBrowser.Dlna.Main public void Run() { + ((DlnaManager)_dlnaManager).InitProfiles(); + ReloadComponents(); _config.ConfigurationUpdated += _config_ConfigurationUpdated; @@ -240,9 +242,9 @@ namespace MediaBrowser.Dlna.Main var services = new List { - "upnp:rootdevice", - "urn:schemas-upnp-org:device:MediaServer:1", - "urn:schemas-upnp-org:service:ContentDirectory:1", + "upnp:rootdevice", + "urn:schemas-upnp-org:device:MediaServer:1", + "urn:schemas-upnp-org:service:ContentDirectory:1", "urn:schemas-upnp-org:service:ConnectionManager:1", "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1", "uuid:" + udn diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs index 202ea76fbf..ab9a6a51ff 100644 --- a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Dlna.Profiles new TranscodingProfile { Container = "ts", - AudioCodec = "ac3", + AudioCodec = "ac3,aac,mp3", VideoCodec = "h264", Type = DlnaProfileType.Video }, diff --git a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml index 38b7414549..08fec73db2 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml @@ -40,9 +40,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index 9364f464b6..8fae686325 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -33,9 +33,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml index 5b8ff5d684..b15378276b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml @@ -37,9 +37,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml index 561abe0e5c..27192847d3 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml @@ -39,8 +39,8 @@ - - + + @@ -51,11 +51,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml index b2d2676575..678c31f80c 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml @@ -43,9 +43,9 @@ - - - + + + @@ -57,6 +57,7 @@ + @@ -65,16 +66,19 @@ + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml index d0985e1350..79c0dd3033 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml @@ -40,9 +40,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index 1147aa2993..b74ecd1cec 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -42,9 +42,9 @@ - - - + + + @@ -61,6 +61,7 @@ + @@ -69,11 +70,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml index 1e6db99b12..04dc262d89 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml @@ -37,9 +37,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml index 679aa26bd6..7b3aa03e82 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml @@ -43,9 +43,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml index 256443093f..cbc275eb17 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml @@ -50,9 +50,9 @@ - - - + + + @@ -69,6 +69,7 @@ + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml index 3d50b1724c..bfdeb7cb59 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml @@ -38,9 +38,9 @@ - - - + + + @@ -51,6 +51,7 @@ + @@ -58,22 +59,26 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index 967538bdf0..c806c1238b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -50,9 +50,9 @@ - - - + + + @@ -70,6 +70,7 @@ + @@ -78,6 +79,7 @@ + @@ -87,6 +89,7 @@ + @@ -95,11 +98,13 @@ + + 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 49f4759b98..e304043625 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml @@ -48,9 +48,9 @@ - - - + + + @@ -67,11 +67,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml index 41a996b663..c355057f89 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml @@ -47,9 +47,9 @@ - - - + + + @@ -68,16 +68,19 @@ + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml index ed66118d32..e045d130bf 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml @@ -45,9 +45,9 @@ - - - + + + @@ -66,6 +66,7 @@ + @@ -74,6 +75,7 @@ + @@ -81,22 +83,26 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml index 88ff6047fd..3ccceeaaab 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml @@ -48,9 +48,9 @@ - - - + + + @@ -69,6 +69,7 @@ + @@ -77,6 +78,7 @@ + @@ -84,22 +86,26 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml index fb06ab0acf..a0b992283c 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml @@ -50,9 +50,9 @@ - - - + + + @@ -69,16 +69,19 @@ + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml index 67526f5f20..52f51c59ed 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml @@ -55,9 +55,9 @@ - - - + + + @@ -74,11 +74,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml index 8502377565..2a6f179df3 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml @@ -55,9 +55,9 @@ - - - + + + @@ -74,11 +74,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index 11dc332398..9512a61436 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -45,9 +45,9 @@ - - - + + + @@ -66,22 +66,26 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml index 5a763006b1..914a6155a6 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml @@ -45,9 +45,9 @@ - - - + + + @@ -66,22 +66,26 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml index a007a4aa32..9dfacdbc63 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml @@ -40,9 +40,9 @@ - - - + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index 6f245202d4..ed0ba41944 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -51,9 +51,9 @@ - - - + + + @@ -70,11 +70,13 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index bb937101d3..982a375f65 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -46,9 +46,9 @@ - - - + + + @@ -71,6 +71,7 @@ + @@ -79,6 +80,7 @@ + @@ -87,17 +89,20 @@ + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index 3816769442..38ca3b2f7e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -46,9 +46,9 @@ - - - + + + @@ -67,6 +67,7 @@ + @@ -77,6 +78,7 @@ + @@ -87,23 +89,27 @@ + + + + diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml index ebc5e83664..d729d6d547 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml @@ -43,9 +43,9 @@ - - - + + + From c09cd955087eb096961e3a2638820b24d12d0576 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Aug 2016 12:34:58 -0400 Subject: [PATCH 053/220] 3.1.85 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 185d1ccbd5..1c974a5942 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.84")] +[assembly: AssemblyVersion("3.1.85")] From fd53e18ee99123d2fac7d64d5772b0a3eff2b86b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Aug 2016 14:16:07 -0400 Subject: [PATCH 054/220] fix sync layout --- MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs index 6e3114fa15..dfa5c1b71a 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs @@ -199,10 +199,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { - if ((item.ParentIndexNumber ?? 0) == 0) - { - item.AirsBeforeSeasonNumber = rval; - } + item.AirsBeforeSeasonNumber = rval; } } @@ -220,10 +217,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { - if ((item.ParentIndexNumber ?? 0) == 0) - { - item.AirsBeforeEpisodeNumber = rval; - } + item.AirsBeforeEpisodeNumber = rval; } } From a308ab8912dc91d1bba61afa15f859eba0b2df2c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Aug 2016 01:55:52 -0400 Subject: [PATCH 055/220] update components --- MediaBrowser.Model/Querying/ItemFields.cs | 1 + .../Dto/DtoService.cs | 46 ++++++------------- .../LiveTv/LiveTvManager.cs | 1 + .../Sync/SyncManager.cs | 1 + 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 21f87247ab..0400e374af 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -219,6 +219,7 @@ /// Studios, + BasicSyncInfo, /// /// The synchronize information /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index f17f5e5a2f..90111ad8ea 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - FillSyncInfo(dto, item, syncJobItems, options, user); + FillSyncInfo(dto, item, options, user, syncJobItems); list.Add(dto); } @@ -253,39 +253,16 @@ namespace MediaBrowser.Server.Implementations.Dto { var item = tuple.Item1; - FillSyncInfo(tuple.Item2, item, syncProgress, options, user); + FillSyncInfo(tuple.Item2, item, options, user, syncProgress); } } } private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, SyncedItemProgress[] syncProgress) { - if (options.Fields.Contains(ItemFields.SyncInfo)) - { - var userCanSync = user != null && user.Policy.EnableSync; - dto.SupportsSync = userCanSync && _syncManager.SupportsSync(item); - } - - if (dto.SupportsSync ?? false) - { - dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); - dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); - - if (dto.IsSynced.Value) - { - dto.SyncStatus = SyncJobItemStatus.Synced; - } + var hasFullSyncInfo = options.Fields.Contains(ItemFields.SyncInfo); - else if (dto.HasSyncJob.Value) - { - dto.SyncStatus = syncProgress.Where(i => string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)).Select(i => i.Status).Max(); - } - } - } - - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, SyncedItemProgress[] syncProgress, DtoOptions options, User user) - { - if (options.Fields.Contains(ItemFields.SyncInfo)) + if (hasFullSyncInfo || options.Fields.Contains(ItemFields.BasicSyncInfo)) { var userCanSync = user != null && user.Policy.EnableSync; dto.SupportsSync = userCanSync && _syncManager.SupportsSync(item); @@ -296,14 +273,17 @@ namespace MediaBrowser.Server.Implementations.Dto dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); - if (dto.IsSynced.Value) + if (hasFullSyncInfo) { - dto.SyncStatus = SyncJobItemStatus.Synced; - } + if (dto.IsSynced.Value) + { + dto.SyncStatus = SyncJobItemStatus.Synced; + } - else if (dto.HasSyncJob.Value) - { - dto.SyncStatus = syncProgress.Where(i => string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)).Select(i => i.Status).Max(); + else if (dto.HasSyncJob.Value) + { + dto.SyncStatus = syncProgress.Where(i => string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)).Select(i => i.Status).Max(); + } } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 64af35a9aa..26ec599fa4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1187,6 +1187,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv // Load these now which will prefetch metadata var dtoOptions = new DtoOptions(); dtoOptions.Fields.Remove(ItemFields.SyncInfo); + dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false); progress.Report(100); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 92221ffbad..15855f5538 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -646,6 +646,7 @@ namespace MediaBrowser.Server.Implementations.Sync dtoOptions.Fields.Remove(ItemFields.SeriesGenres); dtoOptions.Fields.Remove(ItemFields.Settings); dtoOptions.Fields.Remove(ItemFields.SyncInfo); + dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions); From fb6839f5e7dc656b46f3aa343bfdf17aa3a0f26e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Aug 2016 02:00:17 -0400 Subject: [PATCH 056/220] 3.1.86 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 1c974a5942..42da31e60e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.85")] +[assembly: AssemblyVersion("3.1.86")] From a9cc5d5c4472fb3b1705d3d1cabc88c33fe9ea62 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Aug 2016 13:07:58 -0400 Subject: [PATCH 057/220] add MediaMonkey dlna playback fix --- MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 233ec9546f..9b5030325a 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -602,7 +602,7 @@ namespace MediaBrowser.Dlna.ContentDirectory id = id.Substring(paramsIndex + paramsSrch.Length); var parts = id.Split(';'); - id = parts[24]; + id = parts[23]; } if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase)) From 7e1a0baf9bb26c6142731af25f72120e8415a0a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 00:33:34 -0400 Subject: [PATCH 058/220] update media probe --- .../Encoder/MediaEncoder.cs | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 897684b732..86ff12b1a7 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -500,7 +500,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // Must consume both or ffmpeg may hang due to deadlocks. See comments below. RedirectStandardOutput = true, //RedirectStandardError = true, - RedirectStandardInput = true, + RedirectStandardInput = false, FileName = FFProbePath, Arguments = string.Format(args, probeSizeArgument, inputPath).Trim(), @@ -514,7 +514,7 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - using (var processWrapper = new ProcessWrapper(process, this, _logger)) + using (var processWrapper = new ProcessWrapper(process, this, _logger, false)) { await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); @@ -630,7 +630,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // Must consume both or ffmpeg may hang due to deadlocks. See comments below. //RedirectStandardOutput = true, RedirectStandardError = true, - RedirectStandardInput = true, + RedirectStandardInput = false, FileName = FFMpegPath, Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(), @@ -644,7 +644,7 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); var idetFoundInterlaced = false; - using (var processWrapper = new ProcessWrapper(process, this, _logger)) + using (var processWrapper = new ProcessWrapper(process, this, _logger, false)) { try { @@ -898,14 +898,13 @@ namespace MediaBrowser.MediaEncoding.Encoder FileName = FFMpegPath, Arguments = args, WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false, - RedirectStandardInput = true + ErrorDialog = false } }; _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - using (var processWrapper = new ProcessWrapper(process, this, _logger)) + using (var processWrapper = new ProcessWrapper(process, this, _logger, false)) { await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); @@ -1010,7 +1009,7 @@ namespace MediaBrowser.MediaEncoding.Encoder bool ranToCompletion = false; - using (var processWrapper = new ProcessWrapper(process, this, _logger)) + using (var processWrapper = new ProcessWrapper(process, this, _logger, true)) { try { @@ -1118,13 +1117,16 @@ namespace MediaBrowser.MediaEncoding.Encoder { _logger.Info("Killing ffmpeg process"); - try - { - process.Process.StandardInput.WriteLine("q"); - } - catch (Exception) + if (process.IsRedirectingStdin) { - _logger.Error("Error sending q command to process"); + try + { + process.Process.StandardInput.WriteLine("q"); + } + catch (Exception) + { + _logger.Error("Error sending q command to process"); + } } try @@ -1201,13 +1203,15 @@ namespace MediaBrowser.MediaEncoding.Encoder public int? ExitCode; private readonly MediaEncoder _mediaEncoder; private readonly ILogger _logger; + public bool IsRedirectingStdin { get; set; } - public ProcessWrapper(Process process, MediaEncoder mediaEncoder, ILogger logger) + public ProcessWrapper(Process process, MediaEncoder mediaEncoder, ILogger logger, bool isRedirectingStdin) { Process = process; _mediaEncoder = mediaEncoder; _logger = logger; Process.Exited += Process_Exited; + IsRedirectingStdin = isRedirectingStdin; } void Process_Exited(object sender, EventArgs e) From 04d480297dc9b4f9a1a9e35fe33f424ecc7662e1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 02:38:19 -0400 Subject: [PATCH 059/220] reduce sync db access --- .../UserLibrary/BaseItemsByNameService.cs | 6 +- MediaBrowser.Controller/Dto/IDtoService.cs | 11 +- MediaBrowser.Controller/Sync/ISyncManager.cs | 2 +- .../Sync/ISyncRepository.cs | 5 +- .../Sync/SyncedItemProgress.cs | 2 +- MediaBrowser.Model/Dto/IHasSyncInfo.cs | 1 + .../Dto/DtoService.cs | 113 ++++++++---------- .../Sync/SyncManager.cs | 2 +- .../Sync/SyncRepository.cs | 99 ++++++++++++--- 9 files changed, 145 insertions(+), 96 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 9465d1fdc5..852a3d59ee 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -180,9 +180,10 @@ namespace MediaBrowser.Api.UserLibrary var result = GetItems(request, query); + var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions); var dtos = result.Items.Select(i => { - var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, user); + var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, syncProgess, user); if (!string.IsNullOrWhiteSpace(request.IncludeItemTypes)) { @@ -325,7 +326,8 @@ namespace MediaBrowser.Api.UserLibrary tuples = ibnItems.Select(i => new Tuple>(i, new List())); } - var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, user)); + var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions); + var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, syncProgess, user)); result.Items = dtos.Where(i => i != null).ToArray(); diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index e4aa466dfd..a8e93fb2b8 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -4,6 +4,8 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Querying; using System.Collections.Generic; using System.Threading.Tasks; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Sync; namespace MediaBrowser.Controller.Dto { @@ -89,11 +91,8 @@ namespace MediaBrowser.Controller.Dto /// /// Gets the item by name dto. /// - /// The item. - /// The options. - /// The tagged items. - /// The user. - /// BaseItemDto. - BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, User user = null); + BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, Dictionary syncProgress, User user = null); + + Dictionary GetSyncedItemProgress(DtoOptions options); } } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 8eb934eaa8..fbcb549ad8 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -151,7 +151,7 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); + Dictionary GetSyncedItemProgresses(SyncJobItemQuery query); /// /// Reports the synchronize job item transfer beginning. diff --git a/MediaBrowser.Controller/Sync/ISyncRepository.cs b/MediaBrowser.Controller/Sync/ISyncRepository.cs index 2af09dbaad..8e9b2bf774 100644 --- a/MediaBrowser.Controller/Sync/ISyncRepository.cs +++ b/MediaBrowser.Controller/Sync/ISyncRepository.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Querying; +using System.Collections.Generic; +using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; using System.Threading.Tasks; @@ -74,6 +75,6 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); + Dictionary GetSyncedItemProgresses(SyncJobItemQuery query); } } diff --git a/MediaBrowser.Controller/Sync/SyncedItemProgress.cs b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs index edb42eb0f1..0fd929eb18 100644 --- a/MediaBrowser.Controller/Sync/SyncedItemProgress.cs +++ b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs @@ -4,7 +4,7 @@ namespace MediaBrowser.Controller.Sync { public class SyncedItemProgress { - public string ItemId { get; set; } + public double Progress { get; set; } public SyncJobItemStatus Status { get; set; } } } diff --git a/MediaBrowser.Model/Dto/IHasSyncInfo.cs b/MediaBrowser.Model/Dto/IHasSyncInfo.cs index d2cf1f8cfe..7471dacdd7 100644 --- a/MediaBrowser.Model/Dto/IHasSyncInfo.cs +++ b/MediaBrowser.Model/Dto/IHasSyncInfo.cs @@ -7,6 +7,7 @@ namespace MediaBrowser.Model.Dto string Id { get; } bool? SupportsSync { get; set; } bool? HasSyncJob { get; set; } + double? SyncPercent { get; set; } bool? IsSynced { get; set; } SyncJobItemStatus? SyncStatus { get; set; } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 90111ad8ea..779afdcf27 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -97,8 +97,7 @@ namespace MediaBrowser.Server.Implementations.Dto throw new ArgumentNullException("options"); } - var syncJobItems = GetSyncedItemProgress(options); - var syncDictionary = GetSyncedItemProgressDictionary(syncJobItems); + var syncDictionary = GetSyncedItemProgress(options); var list = new List(); var programTuples = new List>(); @@ -106,7 +105,7 @@ namespace MediaBrowser.Server.Implementations.Dto foreach (var item in items) { - var dto = await GetBaseItemDtoInternal(item, options, syncDictionary, user, owner).ConfigureAwait(false); + var dto = await GetBaseItemDtoInternal(item, options, user, owner).ConfigureAwait(false); var tvChannel = item as LiveTvChannel; if (tvChannel != null) @@ -133,7 +132,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - FillSyncInfo(dto, item, options, user, syncJobItems); + FillSyncInfo(dto, item, options, user, syncDictionary); list.Add(dto); } @@ -151,23 +150,11 @@ namespace MediaBrowser.Server.Implementations.Dto return list; } - private Dictionary GetSyncedItemProgressDictionary(IEnumerable items) - { - var dict = new Dictionary(); - - foreach (var item in items) - { - dict[item.ItemId] = item; - } - - return dict; - } - public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { - var syncProgress = GetSyncedItemProgress(options); + var syncDictionary = GetSyncedItemProgress(options); - var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user, owner).Result; + var dto = GetBaseItemDtoInternal(item, options, user, owner).Result; var tvChannel = item as LiveTvChannel; if (tvChannel != null) { @@ -190,11 +177,11 @@ namespace MediaBrowser.Server.Implementations.Dto SetItemByNameInfo(item, dto, GetTaggedItems(byName, user), user); } - FillSyncInfo(dto, item, options, user, syncProgress); + FillSyncInfo(dto, item, options, user, syncDictionary); return dto; } - FillSyncInfo(dto, item, options, user, syncProgress); + FillSyncInfo(dto, item, options, user, syncDictionary); return dto; } @@ -210,23 +197,24 @@ namespace MediaBrowser.Server.Implementations.Dto return items; } - private SyncedItemProgress[] GetSyncedItemProgress(DtoOptions options) + public Dictionary GetSyncedItemProgress(DtoOptions options) { - if (!options.Fields.Contains(ItemFields.SyncInfo)) + if (!options.Fields.Contains(ItemFields.BasicSyncInfo) && + !options.Fields.Contains(ItemFields.SyncInfo)) { - return new SyncedItemProgress[] { }; + return new Dictionary(); } var deviceId = options.DeviceId; if (string.IsNullOrWhiteSpace(deviceId)) { - return new SyncedItemProgress[] { }; + return new Dictionary(); } var caps = _deviceManager().GetCapabilities(deviceId); if (caps == null || !caps.SupportsSync) { - return new SyncedItemProgress[] { }; + return new Dictionary(); } return _syncManager.GetSyncedItemProgresses(new SyncJobItemQuery @@ -240,12 +228,13 @@ namespace MediaBrowser.Server.Implementations.Dto SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced } - }).Items; + }); } public void FillSyncInfo(IEnumerable> tuples, DtoOptions options, User user) { - if (options.Fields.Contains(ItemFields.SyncInfo)) + if (options.Fields.Contains(ItemFields.BasicSyncInfo) || + options.Fields.Contains(ItemFields.SyncInfo)) { var syncProgress = GetSyncedItemProgress(options); @@ -258,37 +247,40 @@ namespace MediaBrowser.Server.Implementations.Dto } } - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, SyncedItemProgress[] syncProgress) + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, Dictionary syncProgress) { var hasFullSyncInfo = options.Fields.Contains(ItemFields.SyncInfo); - if (hasFullSyncInfo || options.Fields.Contains(ItemFields.BasicSyncInfo)) + if (!options.Fields.Contains(ItemFields.BasicSyncInfo) && + !hasFullSyncInfo) { - var userCanSync = user != null && user.Policy.EnableSync; - dto.SupportsSync = userCanSync && _syncManager.SupportsSync(item); + return; } if (dto.SupportsSync ?? false) { - dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); - dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); - - if (hasFullSyncInfo) + SyncedItemProgress syncStatus; + if (syncProgress.TryGetValue(dto.Id, out syncStatus)) { - if (dto.IsSynced.Value) + if (syncStatus.Status == SyncJobItemStatus.Synced) { - dto.SyncStatus = SyncJobItemStatus.Synced; + dto.SyncPercent = 100; + } + else + { + dto.SyncPercent = syncStatus.Progress; } - else if (dto.HasSyncJob.Value) + if (hasFullSyncInfo) { - dto.SyncStatus = syncProgress.Where(i => string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)).Select(i => i.Status).Max(); + dto.HasSyncJob = true; + dto.SyncStatus = syncStatus.Status; } } } } - private async Task GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary syncProgress, User user = null, BaseItem owner = null) + private async Task GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { var fields = options.Fields; @@ -337,7 +329,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (user != null) { - await AttachUserSpecificInfo(dto, item, user, fields, syncProgress).ConfigureAwait(false); + await AttachUserSpecificInfo(dto, item, user, fields).ConfigureAwait(false); } var hasMediaSources = item as IHasMediaSources; @@ -400,11 +392,9 @@ namespace MediaBrowser.Server.Implementations.Dto return dto; } - public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, User user = null) + public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, Dictionary syncProgress, User user = null) { - var syncProgress = GetSyncedItemProgress(options); - - var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user).Result; + var dto = GetBaseItemDtoInternal(item, options, user).Result; if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts)) { @@ -452,28 +442,13 @@ namespace MediaBrowser.Server.Implementations.Dto /// The item. /// The user. /// The fields. - /// The synchronize progress. - private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields, Dictionary syncProgress) + private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields) { if (item.IsFolder) { var folder = (Folder)item; - if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren && fields.Contains(ItemFields.SyncInfo)) - { - // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice - // TODO: Improve in future - dto.UserData = GetUserItemDataDto(_userDataRepository.GetUserData(user, item)); - - await SetSpecialCounts(folder, user, dto, fields, syncProgress).ConfigureAwait(false); - - dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && - dto.UserData.PlayedPercentage.Value >= 100; - } - else - { - dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); - } + dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); if (item.SourceType == SourceType.Library) { @@ -498,6 +473,12 @@ namespace MediaBrowser.Server.Implementations.Dto dto.PlayAccess = item.GetPlayAccess(user); + if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo)) + { + var userCanSync = user != null && user.Policy.EnableSync; + dto.SupportsSync = userCanSync && _syncManager.SupportsSync(item); + } + if (fields.Contains(ItemFields.SeasonUserData)) { var episode = item as Episode; @@ -1424,7 +1405,7 @@ namespace MediaBrowser.Server.Implementations.Dto BaseItem parent = null; var isFirst = true; - while (((!dto.HasLogo && logoLimit > 0) || (!dto.HasArtImage && artLimit > 0) || (!dto.HasThumb && thumbLimit > 0) || parent is Series) && + while (((!dto.HasLogo && logoLimit > 0) || (!dto.HasArtImage && artLimit > 0) || (!dto.HasThumb && thumbLimit > 0) || parent is Series) && (parent = parent ?? (isFirst ? item.GetParent() ?? owner : parent)) != null) { if (parent == null) @@ -1531,7 +1512,7 @@ namespace MediaBrowser.Server.Implementations.Dto /// The fields. /// The synchronize progress. /// Task. - private async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields, Dictionary syncProgress) + private async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields, Dictionary syncProgress) { var recursiveItemCount = 0; var unplayed = 0; @@ -1580,10 +1561,10 @@ namespace MediaBrowser.Server.Implementations.Dto } double percent = 0; - SyncedItemProgress syncItemProgress; + SyncJobItemStatus syncItemProgress; if (syncProgress.TryGetValue(child.Id.ToString("N"), out syncItemProgress)) { - switch (syncItemProgress.Status) + switch (syncItemProgress) { case SyncJobItemStatus.Synced: percent = 100; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 15855f5538..ffba60af84 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1124,7 +1124,7 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } - public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) + public Dictionary GetSyncedItemProgresses(SyncJobItemQuery query) { return _repo.GetSyncedItemProgresses(query); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index a1ed66a995..df4149fa72 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -29,6 +29,17 @@ namespace MediaBrowser.Server.Implementations.Sync DbFilePath = Path.Combine(appPaths.DataPath, "sync14.db"); } + private class SyncSummary + { + public Dictionary Items { get; set; } + + public SyncSummary() + { + Items = new Dictionary(); + } + } + + public async Task Initialize() { using (var connection = await CreateConnection().ConfigureAwait(false)) @@ -41,7 +52,10 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT, ItemDateModifiedTicks BIGINT)", "create index if not exists idx_SyncJobItems1 on SyncJobItems(Id)", - "create index if not exists idx_SyncJobItems2 on SyncJobItems(TargetId)", + + "drop index if exists idx_SyncJobItems2", + "drop index if exists idx_SyncJobItems3", + "create index if not exists idx_SyncJobItems4 on SyncJobItems(TargetId,ItemId,Status,Progress,DateCreated)", "pragma shrink_memory" }; @@ -583,9 +597,74 @@ namespace MediaBrowser.Server.Implementations.Sync } } - public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) + public Dictionary GetSyncedItemProgresses(SyncJobItemQuery query) { - return GetJobItemReader(query, "select ItemId,Status from SyncJobItems", GetSyncedItemProgress); + var result = new Dictionary(); + + using (var connection = CreateConnection(true).Result) + { + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select ItemId,Progress,Status from SyncJobItems"; + + var whereClauses = new List(); + + if (!string.IsNullOrWhiteSpace(query.TargetId)) + { + whereClauses.Add("TargetId=@TargetId"); + cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; + } + + if (query.Statuses.Length > 0) + { + var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); + + whereClauses.Add(string.Format("Status in ({0})", statuses)); + } + + if (whereClauses.Count > 0) + { + cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); + } + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + var itemId = reader.GetString(0); + + if (!reader.IsDBNull(1)) + { + var status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(1), true); + + if (status == SyncJobItemStatus.Synced) + { + result[itemId] = new SyncedItemProgress + { + Status = SyncJobItemStatus.Synced + }; + } + else + { + SyncedItemProgress currentStatus; + double progress = reader.IsDBNull(2) ? 0.0 : reader.GetDouble(2); + + if (!result.TryGetValue(itemId, out currentStatus) || (currentStatus.Status != SyncJobItemStatus.Synced && progress >= currentStatus.Progress)) + { + result[itemId] = new SyncedItemProgress + { + Status = status, + Progress = progress + }; + } + } + } + } + } + } + } + + return result; } public QueryResult GetJobItems(SyncJobItemQuery query) @@ -795,19 +874,5 @@ namespace MediaBrowser.Server.Implementations.Sync return info; } - - private SyncedItemProgress GetSyncedItemProgress(IDataReader reader) - { - var item = new SyncedItemProgress(); - - item.ItemId = reader.GetString(0); - - if (!reader.IsDBNull(1)) - { - item.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(1), true); - } - - return item; - } } } From a363beb23c6604bda5518f5b07b42efddfb829e8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 02:38:27 -0400 Subject: [PATCH 060/220] update probing --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 86ff12b1a7..25b80ee92f 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -1203,7 +1203,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public int? ExitCode; private readonly MediaEncoder _mediaEncoder; private readonly ILogger _logger; - public bool IsRedirectingStdin { get; set; } + public bool IsRedirectingStdin { get; private set; } public ProcessWrapper(Process process, MediaEncoder mediaEncoder, ILogger logger, bool isRedirectingStdin) { @@ -1224,7 +1224,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { ExitCode = process.ExitCode; } - catch (Exception ex) + catch { } @@ -1233,11 +1233,16 @@ namespace MediaBrowser.MediaEncoding.Encoder _mediaEncoder._runningProcesses.Remove(this); } + DisposeProcess(process); + } + + private void DisposeProcess(Process process) + { try { process.Dispose(); } - catch (Exception ex) + catch { } } @@ -1253,7 +1258,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (Process != null) { Process.Exited -= Process_Exited; - Process.Dispose(); + DisposeProcess(Process); } } From 81a5166cf4fdfbf86030a935b1c90be278248432 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 02:39:28 -0400 Subject: [PATCH 061/220] 3.1.87 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 42da31e60e..d8cc21ff25 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.86")] +[assembly: AssemblyVersion("3.1.87")] From bbdbe79108177a27a511468004337818396b2417 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 03:07:57 -0400 Subject: [PATCH 062/220] fix sync methods --- MediaBrowser.Server.Implementations/Sync/SyncRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index df4149fa72..d7c77e655b 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -605,7 +605,7 @@ namespace MediaBrowser.Server.Implementations.Sync { using (var cmd = connection.CreateCommand()) { - cmd.CommandText = "select ItemId,Progress,Status from SyncJobItems"; + cmd.CommandText = "select ItemId,Status,Progress from SyncJobItems"; var whereClauses = new List(); From b1a731f4033d536aca48f87316f246325e785d2b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 03:11:26 -0400 Subject: [PATCH 063/220] 3.1.88 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d8cc21ff25..e3a065d641 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.87")] +[assembly: AssemblyVersion("3.1.88")] From 3e23d32e62519b49baf1368cfc50686713032c03 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 13:26:42 -0400 Subject: [PATCH 064/220] update naming project --- MediaBrowser.Controller/Dto/IDtoService.cs | 12 +----------- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index a8e93fb2b8..a6f807ce9d 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -1,11 +1,9 @@ -using System; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Querying; using System.Collections.Generic; using System.Threading.Tasks; using MediaBrowser.Controller.Sync; -using MediaBrowser.Model.Sync; namespace MediaBrowser.Controller.Dto { @@ -45,14 +43,6 @@ namespace MediaBrowser.Controller.Dto /// Task{BaseItemDto}. BaseItemDto GetBaseItemDto(BaseItem item, List fields, User user = null, BaseItem owner = null); - /// - /// Fills the synchronize information. - /// - /// The tuples. - /// The options. - /// The user. - void FillSyncInfo(IEnumerable> tuples, DtoOptions options, User user); - /// /// Gets the base item dto. /// diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 3ec95633bf..92d95b7fd0 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -56,8 +56,8 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - - ..\packages\MediaBrowser.Naming.1.0.0.54\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + + ..\packages\MediaBrowser.Naming.1.0.0.55\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 84be864b7b..8ee333375b 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -4,7 +4,7 @@ - + From e08f5d5d613b0f21676cfbb366940c72741a87df Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 3 Aug 2016 22:57:11 -0400 Subject: [PATCH 065/220] don't keep retrying when metadata not found --- MediaBrowser.Providers/Manager/MetadataService.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 9776c4e2f5..9c108ac7d3 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -138,7 +138,7 @@ namespace MediaBrowser.Providers.Manager } } - var isFirstRefresh = GetLastRefreshDate(item) == default(DateTime); + var isFirstRefresh = item.DateLastRefreshed == default(DateTime); var beforeSaveResult = await BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType).ConfigureAwait(false); updateType = updateType | beforeSaveResult; @@ -193,11 +193,6 @@ namespace MediaBrowser.Providers.Manager lookupInfo.Year = result.ProductionYear; } - private DateTime GetLastRefreshDate(IHasMetadata item) - { - return item.DateLastRefreshed; - } - protected async Task SaveItem(MetadataResult result, ItemUpdateType reason, CancellationToken cancellationToken) { if (result.Item.SupportsPeople && result.People != null) @@ -652,7 +647,6 @@ namespace MediaBrowser.Providers.Manager } else { - refreshResult.Failures++; Logger.Debug("{0} returned no metadata for {1}", providerName, logName); } } From 39245133f805e75164556fad9135e4f56925c33f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 00:38:58 -0400 Subject: [PATCH 066/220] remove people refresh retry --- .../Entities/InternalPeopleQuery.cs | 2 + .../Library/ILibraryManager.cs | 6 --- .../Library/LibraryManager.cs | 7 ---- .../Library/Validators/GameGenresValidator.cs | 29 +-------------- .../Library/Validators/GenresValidator.cs | 29 +-------------- .../Validators/MusicGenresValidator.cs | 30 +-------------- .../Library/Validators/PeopleValidator.cs | 37 +++---------------- .../Library/Validators/StudiosValidator.cs | 4 -- .../Persistence/SqliteItemRepository.cs | 5 +++ 9 files changed, 16 insertions(+), 133 deletions(-) diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs index 05d23d9866..2ba6842ca3 100644 --- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs @@ -11,11 +11,13 @@ namespace MediaBrowser.Controller.Entities public int? MaxListOrder { get; set; } public Guid AppearsInItemId { get; set; } public string NameContains { get; set; } + public SourceType[] SourceTypes { get; set; } public InternalPeopleQuery() { PersonTypes = new List(); ExcludePersonTypes = new List(); + SourceTypes = new SourceType[] { }; } } } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index ad38b9ea5e..70bd3f081c 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -474,12 +474,6 @@ namespace MediaBrowser.Controller.Library /// List<Person>. List GetPeopleItems(InternalPeopleQuery query); - /// - /// Gets all people names. - /// - /// List<System.String>. - List GetAllPeople(); - /// /// Updates the people. /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 712ea4ef30..015fc3778f 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2605,13 +2605,6 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetPeopleNames(query); } - public List GetAllPeople() - { - return GetPeople(new InternalPeopleQuery()) - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .ToList(); - } - public Task UpdatePeople(BaseItem item, List people) { if (!item.SupportsPeople) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index 826154fac4..a149da6510 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; @@ -43,16 +42,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; - var validIds = new List(); - foreach (var name in items) { try { var itemByName = _libraryManager.GetGameGenre(name); - validIds.Add(itemByName.Id); - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -73,28 +68,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } - var allIds = _libraryManager.GetItemIds(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(GameGenre).Name } - }); - - var invalidIds = allIds - .Except(validIds) - .ToList(); - - foreach (var id in invalidIds) - { - cancellationToken.ThrowIfCancellationRequested(); - - var item = _libraryManager.GetItemById(id); - - await _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false - - }).ConfigureAwait(false); - } - progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 11d4c9f166..fac5cfc356 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; @@ -44,16 +43,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; - var validIds = new List(); - foreach (var name in items) { try { var itemByName = _libraryManager.GetGenre(name); - validIds.Add(itemByName.Id); - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -74,28 +69,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } - var allIds = _libraryManager.GetItemIds(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(Genre).Name } - }); - - var invalidIds = allIds - .Except(validIds) - .ToList(); - - foreach (var id in invalidIds) - { - cancellationToken.ThrowIfCancellationRequested(); - - var item = _libraryManager.GetItemById(id); - - await _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false - - }).ConfigureAwait(false); - } - progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 0c8c56f5aa..81433e5b32 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; @@ -44,16 +42,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; - var validIds = new List(); - foreach (var name in items) { try { var itemByName = _libraryManager.GetMusicGenre(name); - validIds.Add(itemByName.Id); - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -74,28 +68,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } - var allIds = _libraryManager.GetItemIds(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(MusicGenre).Name } - }); - - var invalidIds = allIds - .Except(validIds) - .ToList(); - - foreach (var id in invalidIds) - { - cancellationToken.ThrowIfCancellationRequested(); - - var item = _libraryManager.GetItemById(id); - - await _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false - - }).ConfigureAwait(false); - } - progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 5c43f2e137..8430809501 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -89,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var peopleOptions = _config.Configuration.PeopleMetadataOptions; - var people = _libraryManager.GetAllPeople(); + var people = _libraryManager.GetPeople(new InternalPeopleQuery()); var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -112,8 +112,9 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } var numComplete = 0; - var validIds = new List(); - + + _logger.Debug("Will refresh {0} people", dict.Count); + foreach (var person in dict) { cancellationToken.ThrowIfCancellationRequested(); @@ -122,10 +123,9 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { var item = _libraryManager.GetPerson(person.Key); - validIds.Add(item.Id); - var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 90; + performFullRefresh = false; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh @@ -160,31 +160,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100 * percent); } - var allIds = _libraryManager.GetItemIds(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(Person).Name } - }); - - var invalidIds = allIds - .Except(validIds) - .ToList(); - - foreach (var id in invalidIds) - { - cancellationToken.ThrowIfCancellationRequested(); - - var item = _libraryManager.GetItemById(id); - - if (item != null) - { - await _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false - - }).ConfigureAwait(false); - } - } - progress.Report(100); _logger.Info("People validation complete"); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index e697dbd90b..259878566b 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -42,16 +42,12 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; - var validIds = new List(); - foreach (var name in items) { try { var itemByName = _libraryManager.GetStudio(name); - validIds.Add(itemByName.Id); - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 63dd29e0dd..2ef878a20c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3776,6 +3776,11 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("Name like @NameContains"); cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%"; } + if (query.SourceTypes.Length == 1) + { + whereClauses.Add("(select sourcetype from typedbaseitems where guid=ItemId) = @SourceTypes"); + cmd.Parameters.Add(cmd, "@SourceTypes", DbType.String).Value = query.SourceTypes[0].ToString(); + } return whereClauses; } From 6af3bf94c027ae6f9c225cd4838589525378a5d0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 00:42:56 -0400 Subject: [PATCH 067/220] 3.1.89 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index e3a065d641..d852537b24 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.88")] +[assembly: AssemblyVersion("3.1.89")] From 0c3b7a33c29956aafe54f7e956199c0671f92eff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 00:47:50 -0400 Subject: [PATCH 068/220] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d5d322353c..d852537b24 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6020")] +[assembly: AssemblyVersion("3.1.89")] From 980b9baeb514fa3ab18e481d66a52eb4df8a45c0 Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 4 Aug 2016 00:54:04 -0400 Subject: [PATCH 069/220] update mac project --- .../Emby.Server.Mac.csproj | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 3c16eacfe4..dc19921b67 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -1026,6 +1026,9 @@ Resources\dashboard-ui\bower_components\emby-apiclient\localassetmanager.js + + Resources\dashboard-ui\bower_components\emby-apiclient\serverdiscovery-chrome.js + Resources\dashboard-ui\bower_components\emby-apiclient\serverdiscovery.js @@ -1164,6 +1167,18 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\backdrop\style.css + + Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\card.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\cardbuilder.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\chaptercardbuilder.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\peoplecardbuilder.js + Resources\dashboard-ui\bower_components\emby-webcomponents\collectioneditor\collectioneditor.js @@ -1173,6 +1188,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\dialog\dialog.css + Resources\dashboard-ui\bower_components\emby-webcomponents\dialog\dialog.js @@ -1458,27 +1476,30 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\itemhovermenu\itemhovermenu.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\itemidentifier\itemidentifier.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\itemidentifier\itemidentifier.template.html + Resources\dashboard-ui\bower_components\emby-webcomponents\listview\listview.css Resources\dashboard-ui\bower_components\emby-webcomponents\listview\listview.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading-legacy.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading-legacy.js + Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading-lite.css Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading-lite.js - - Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading-smarttv.js - - - Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading.css - - - Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading.js - Resources\dashboard-ui\bower_components\emby-webcomponents\mediainfo\fresh.png @@ -3432,6 +3453,9 @@ Resources\dashboard-ui\bower_components\paper-progress\paper-progress.html + + Resources\dashboard-ui\bower_components\paper-progress\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\paper-progress\demo\index.html @@ -3747,12 +3771,6 @@ Resources\dashboard-ui\components\imageuploader\imageuploader.template.html - - Resources\dashboard-ui\components\itemidentifier\itemidentifier.js - - - Resources\dashboard-ui\components\itemidentifier\itemidentifier.template.html - Resources\dashboard-ui\components\medialibrarycreator\medialibrarycreator.js @@ -3783,9 +3801,6 @@ Resources\dashboard-ui\components\tvproviders\xmltv.template.html - - Resources\dashboard-ui\css\card.css - Resources\dashboard-ui\css\chromecast.css @@ -3822,9 +3837,6 @@ Resources\dashboard-ui\css\site.css - - Resources\dashboard-ui\css\tileitem.css - Resources\dashboard-ui\css\images\ani_equalizer_black.gif From c7798fcd4807279e08ce773ad16732b09a411b4d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 00:55:45 -0400 Subject: [PATCH 070/220] 3.0.6030 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d852537b24..7ffbc0f475 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.89")] +[assembly: AssemblyVersion("3.0.6030")] From 295d47a4878f6981125e12dd6e15d1472b73a476 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 01:03:05 -0400 Subject: [PATCH 071/220] fix version --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7ffbc0f475..d852537b24 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6030")] +[assembly: AssemblyVersion("3.1.89")] From 329ec93499d2711e82cbdd4078567ad79d9a4514 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 01:04:13 -0400 Subject: [PATCH 072/220] fix version --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7ffbc0f475..8de20ebed3 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6030")] +[assembly: AssemblyVersion("3.1.*")] +//[assembly: AssemblyVersion("3.1.80")] From be6e9b29571269d525623794d5f872ee0e7b4894 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 12:39:19 -0400 Subject: [PATCH 073/220] support audio db language choice --- .../Music/AudioDbAlbumProvider.cs | 66 ++++++++++++++----- .../Music/AudioDbArtistProvider.cs | 61 +++++++++++++---- 2 files changed, 96 insertions(+), 31 deletions(-) diff --git a/MediaBrowser.Providers/Music/AudioDbAlbumProvider.cs b/MediaBrowser.Providers/Music/AudioDbAlbumProvider.cs index 2f4df1ea48..5963e90e2e 100644 --- a/MediaBrowser.Providers/Music/AudioDbAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/AudioDbAlbumProvider.cs @@ -61,14 +61,14 @@ namespace MediaBrowser.Providers.Music { result.Item = new MusicAlbum(); result.HasMetadata = true; - ProcessResult(result.Item, obj.album[0]); + ProcessResult(result.Item, obj.album[0], info.MetadataLanguage); } } return result; } - private void ProcessResult(MusicAlbum item, Album result) + private void ProcessResult(MusicAlbum item, Album result, string preferredLanguage) { if (!string.IsNullOrWhiteSpace(result.strArtist)) { @@ -91,7 +91,39 @@ namespace MediaBrowser.Providers.Music item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, result.strMusicBrainzArtistID); item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, result.strMusicBrainzID); - item.Overview = (result.strDescriptionEN ?? string.Empty).StripHtml(); + string overview = null; + + if (string.Equals(preferredLanguage, "de", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionDE; + } + else if (string.Equals(preferredLanguage, "fr", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionFR; + } + else if (string.Equals(preferredLanguage, "nl", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionNL; + } + else if (string.Equals(preferredLanguage, "ru", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionRU; + } + else if (string.Equals(preferredLanguage, "it", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionIT; + } + else if ((preferredLanguage ?? string.Empty).StartsWith("pt", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strDescriptionPT; + } + + if (string.IsNullOrWhiteSpace(overview)) + { + overview = result.strDescriptionEN; + } + + item.Overview = (overview ?? string.Empty).StripHtml(); } public string Name @@ -186,20 +218,20 @@ namespace MediaBrowser.Providers.Music public string strAlbumThumb { get; set; } public string strAlbumCDart { get; set; } public string strDescriptionEN { get; set; } - public object strDescriptionDE { get; set; } - public object strDescriptionFR { get; set; } - public object strDescriptionCN { get; set; } - public object strDescriptionIT { get; set; } - public object strDescriptionJP { get; set; } - public object strDescriptionRU { get; set; } - public object strDescriptionES { get; set; } - public object strDescriptionPT { get; set; } - public object strDescriptionSE { get; set; } - public object strDescriptionNL { get; set; } - public object strDescriptionHU { get; set; } - public object strDescriptionNO { get; set; } - public object strDescriptionIL { get; set; } - public object strDescriptionPL { get; set; } + public string strDescriptionDE { get; set; } + public string strDescriptionFR { get; set; } + public string strDescriptionCN { get; set; } + public string strDescriptionIT { get; set; } + public string strDescriptionJP { get; set; } + public string strDescriptionRU { get; set; } + public string strDescriptionES { get; set; } + public string strDescriptionPT { get; set; } + public string strDescriptionSE { get; set; } + public string strDescriptionNL { get; set; } + public string strDescriptionHU { get; set; } + public string strDescriptionNO { get; set; } + public string strDescriptionIL { get; set; } + public string strDescriptionPL { get; set; } public object intLoved { get; set; } public object intScore { get; set; } public string strReview { get; set; } diff --git a/MediaBrowser.Providers/Music/AudioDbArtistProvider.cs b/MediaBrowser.Providers/Music/AudioDbArtistProvider.cs index 5356174e06..8bcb012282 100644 --- a/MediaBrowser.Providers/Music/AudioDbArtistProvider.cs +++ b/MediaBrowser.Providers/Music/AudioDbArtistProvider.cs @@ -61,17 +61,16 @@ namespace MediaBrowser.Providers.Music { result.Item = new MusicArtist(); result.HasMetadata = true; - ProcessResult(result.Item, obj.artists[0]); + ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage); } } return result; } - private void ProcessResult(MusicArtist item, Artist result) + private void ProcessResult(MusicArtist item, Artist result, string preferredLanguage) { item.HomePageUrl = result.strWebsite; - item.Overview = (result.strBiographyEN ?? string.Empty).StripHtml(); if (!string.IsNullOrEmpty(result.strGenre)) { @@ -80,6 +79,40 @@ namespace MediaBrowser.Providers.Music item.SetProviderId(MetadataProviders.AudioDbArtist, result.idArtist); item.SetProviderId(MetadataProviders.MusicBrainzArtist, result.strMusicBrainzID); + + string overview = null; + + if (string.Equals(preferredLanguage, "de", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyDE; + } + else if (string.Equals(preferredLanguage, "fr", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyFR; + } + else if (string.Equals(preferredLanguage, "nl", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyNL; + } + else if (string.Equals(preferredLanguage, "ru", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyRU; + } + else if (string.Equals(preferredLanguage, "it", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyIT; + } + else if ((preferredLanguage ?? string.Empty).StartsWith("pt", StringComparison.OrdinalIgnoreCase)) + { + overview = result.strBiographyPT; + } + + if (string.IsNullOrWhiteSpace(overview)) + { + overview = result.strBiographyEN; + } + + item.Overview = (overview ?? string.Empty).StripHtml(); } public string Name @@ -180,18 +213,18 @@ namespace MediaBrowser.Providers.Music public string strBiographyEN { get; set; } public string strBiographyDE { get; set; } public string strBiographyFR { get; set; } - public object strBiographyCN { get; set; } + public string strBiographyCN { get; set; } public string strBiographyIT { get; set; } - public object strBiographyJP { get; set; } - public object strBiographyRU { get; set; } - public object strBiographyES { get; set; } - public object strBiographyPT { get; set; } - public object strBiographySE { get; set; } - public object strBiographyNL { get; set; } - public object strBiographyHU { get; set; } - public object strBiographyNO { get; set; } - public object strBiographyIL { get; set; } - public object strBiographyPL { get; set; } + public string strBiographyJP { get; set; } + public string strBiographyRU { get; set; } + public string strBiographyES { get; set; } + public string strBiographyPT { get; set; } + public string strBiographySE { get; set; } + public string strBiographyNL { get; set; } + public string strBiographyHU { get; set; } + public string strBiographyNO { get; set; } + public string strBiographyIL { get; set; } + public string strBiographyPL { get; set; } public string strGender { get; set; } public string intMembers { get; set; } public string strCountry { get; set; } From 97446d04df47262bb65cba60868f76a03b3d4edc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Aug 2016 15:05:52 -0400 Subject: [PATCH 074/220] update SocketHttpListener --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 92d95b7fd0..6c7c2ed283 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -73,8 +73,8 @@ ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True - - ..\packages\SocketHttpListener.1.0.0.36\lib\net45\SocketHttpListener.dll + + ..\packages\SocketHttpListener.1.0.0.37\lib\net45\SocketHttpListener.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 8ee333375b..f8b0ab41db 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -9,5 +9,5 @@ - + \ No newline at end of file From 6cf28f1c4e191b8599aedc1f71c01de77d7ff7cb Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 5 Aug 2016 02:36:04 +0200 Subject: [PATCH 075/220] Fix IndexOutOfRangeException Fixes situations where the filename is something like "-------". --- .../Library/LibraryManager.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 015fc3778f..7af495f5a0 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -923,14 +923,14 @@ namespace MediaBrowser.Server.Implementations.Library if (type == typeof(Person)) { - var subFolderIndex = 0; - - while (!char.IsLetterOrDigit(validFilename[subFolderIndex])) + foreach (char c in validFilename) { - subFolderIndex++; + if (char.IsLetterOrDigit(c)) + { + subFolderPrefix = c.ToString(); + break; + } } - - subFolderPrefix = validFilename.Substring(subFolderIndex, 1); } var fullPath = string.IsNullOrEmpty(subFolderPrefix) ? From 79887b2c341cb515d312f4dba24ba324b28d6975 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Aug 2016 01:12:25 -0400 Subject: [PATCH 076/220] validate encoder presence --- .../Playback/BaseStreamingService.cs | 29 ++++++++---- MediaBrowser.Api/Playback/StreamState.cs | 5 +- .../MediaEncoding/IMediaEncoder.cs | 1 + .../Encoder/EncoderValidator.cs | 1 + .../Encoder/EncodingJobFactory.cs | 47 +++++++++++++------ .../Encoder/MediaEncoder.cs | 4 +- .../Encoder/VideoEncoder.cs | 2 +- 7 files changed, 62 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ab73aabe43..5203e3ba23 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -286,28 +286,41 @@ namespace MediaBrowser.Api.Playback protected string GetH264Encoder(StreamState state) { + var defaultEncoder = "libx264"; + // Only use alternative encoders for video files. // When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. if (state.VideoType == VideoType.VideoFile) { - if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) || - string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + var hwType = ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType; + + if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { - return "h264_qsv"; + return GetAvailableEncoder("h264_qsv", defaultEncoder); } - if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "nvenc", StringComparison.OrdinalIgnoreCase)) { - return "h264_nvenc"; + return GetAvailableEncoder("h264_nvenc", defaultEncoder); } - if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "h264_omx", StringComparison.OrdinalIgnoreCase)) { - return "h264_omx"; + return GetAvailableEncoder("h264_omx", defaultEncoder); } } - return "libx264"; + return defaultEncoder; + } + + private string GetAvailableEncoder(string preferredEncoder, string defaultEncoder) + { + if (MediaEncoder.SupportsEncoder(preferredEncoder)) + { + return preferredEncoder; + } + return defaultEncoder; } /// diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index d97169fa5b..d7d94c69b4 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -80,7 +80,10 @@ namespace MediaBrowser.Api.Playback { return 10; } - if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1) + if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1 || + userAgent.IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 || + userAgent.IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 || + userAgent.IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1) { return 10; } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 05e82a16e7..1fef8bead7 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -133,5 +133,6 @@ namespace MediaBrowser.Controller.MediaEncoding Task Init(); Task UpdateEncoderPath(string path, string pathType); + bool SupportsEncoder(string encoder); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 50df08e66a..5d3db612f6 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -86,6 +86,7 @@ namespace MediaBrowser.MediaEncoding.Encoder "srt", "h264_nvenc", "h264_qsv", + "h264_omx", "ac3" }; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 7c4b7fc2f6..ba7b149508 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -522,10 +522,8 @@ namespace MediaBrowser.MediaEncoding.Encoder /// /// Gets the name of the output video codec /// - /// The state. - /// The options. /// System.String. - internal static string GetVideoEncoder(EncodingJob state, EncodingOptions options) + internal static string GetVideoEncoder(IMediaEncoder mediaEncoder, EncodingJob state, EncodingOptions options) { var codec = state.OutputVideoCodec; @@ -533,7 +531,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase)) { - return GetH264Encoder(state, options); + return GetH264Encoder(mediaEncoder, state, options); } if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase)) { @@ -554,24 +552,43 @@ namespace MediaBrowser.MediaEncoding.Encoder return "copy"; } - internal static string GetH264Encoder(EncodingJob state, EncodingOptions options) + private static string GetAvailableEncoder(IMediaEncoder mediaEncoder, string preferredEncoder, string defaultEncoder) { - if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) || - string.Equals(options.HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + if (mediaEncoder.SupportsEncoder(preferredEncoder)) { - return "h264_qsv"; + return preferredEncoder; } + return defaultEncoder; + } - if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase)) - { - return "h264_nvenc"; - } - if (string.Equals(options.HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase)) + internal static string GetH264Encoder(IMediaEncoder mediaEncoder, EncodingJob state, EncodingOptions options) + { + var defaultEncoder = "libx264"; + + // Only use alternative encoders for video files. + // When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully + // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. + if (state.VideoType == VideoType.VideoFile) { - return "h264_omx"; + var hwType = options.HardwareAccelerationType; + + if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { + return GetAvailableEncoder(mediaEncoder, "h264_qsv", defaultEncoder); + } + + if (string.Equals(hwType, "nvenc", StringComparison.OrdinalIgnoreCase)) + { + return GetAvailableEncoder(mediaEncoder, "h264_nvenc", defaultEncoder); + } + if (string.Equals(hwType, "h264_omx", StringComparison.OrdinalIgnoreCase)) + { + return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder); + } } - return "libx264"; + return defaultEncoder; } internal static bool CanStreamCopyVideo(EncodingJobOptions request, MediaStream videoStream) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 25b80ee92f..08ab99f9b2 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -392,9 +392,9 @@ namespace MediaBrowser.MediaEncoding.Encoder //_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray())); } - public bool SupportsEncoder(string decoder) + public bool SupportsEncoder(string encoder) { - return _encoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); + return _encoders.Contains(encoder, StringComparer.OrdinalIgnoreCase); } public bool SupportsDecoder(string decoder) diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs index 82a9668218..d65e057834 100644 --- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.MediaEncoding.Encoder protected override async Task GetCommandLineArguments(EncodingJob state) { // Get the output codec name - var videoCodec = EncodingJobFactory.GetVideoEncoder(state, GetEncodingOptions()); + var videoCodec = EncodingJobFactory.GetVideoEncoder(MediaEncoder, state, GetEncodingOptions()); var format = string.Empty; var keyFrame = string.Empty; From 8cca5dfb03d126b87b007e4699b061433991d3ae Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Aug 2016 02:13:19 -0400 Subject: [PATCH 077/220] fix merge conflict --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d852537b24..8de20ebed3 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.89")] +[assembly: AssemblyVersion("3.1.*")] +//[assembly: AssemblyVersion("3.1.80")] From bfe746d4e08e9b5d8422856000f0479853df64e4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Aug 2016 02:14:13 -0400 Subject: [PATCH 078/220] 3.1.90 --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 8de20ebed3..07028185d1 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.1.*")] -//[assembly: AssemblyVersion("3.1.80")] +//[assembly: AssemblyVersion("3.1.*")] +[assembly: AssemblyVersion("3.1.90")] From 22fc552fc0f67f2ea6cb6125b154dcfca150d5c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Aug 2016 16:25:09 -0400 Subject: [PATCH 079/220] remove paper-fab --- .../LiveTv/LiveTvManager.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 26ec599fa4..09d156661d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -133,7 +133,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv void service_DataSourceChanged(object sender, EventArgs e) { - _taskManager.CancelIfRunningAndQueue(); + if (!_isDisposed) + { + _taskManager.CancelIfRunningAndQueue(); + } } public async Task> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) @@ -1238,7 +1241,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var programs = new List(); var channels = new List(); - var guideDays = GetGuideDays(list.Count); + var guideDays = GetGuideDays(); _logger.Info("Refreshing guide with {0} days of guide data", guideDays); @@ -1326,7 +1329,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } private const int MaxGuideDays = 14; - private double GetGuideDays(int channelCount) + private double GetGuideDays() { var config = GetConfiguration(); @@ -1335,13 +1338,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return Math.Max(1, Math.Min(config.GuideDays.Value, MaxGuideDays)); } - var programsPerDay = channelCount * 48; - - const int maxPrograms = 24000; - - var days = Math.Round((double)maxPrograms / programsPerDay); - - return Math.Max(3, Math.Min(days, MaxGuideDays)); + return 7; } private async Task>> GetChannels(ILiveTvService service, CancellationToken cancellationToken) @@ -2309,6 +2306,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } private readonly object _disposeLock = new object(); + private bool _isDisposed = false; /// /// Releases unmanaged and - optionally - managed resources. /// @@ -2317,6 +2315,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (dispose) { + _isDisposed = true; + lock (_disposeLock) { foreach (var stream in _openStreams.Values.ToList()) From 407d82ea11383f55d2187a69c9711ee7511ee0e3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Aug 2016 16:35:11 -0400 Subject: [PATCH 080/220] support mp4 subtitles --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 44a0f264da..f37e223ded 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -398,7 +398,8 @@ namespace MediaBrowser.MediaEncoding.Probing // These are mp4 chapters if (string.Equals(streamInfo.codec_name, "mov_text", StringComparison.OrdinalIgnoreCase)) { - return null; + // Edit: but these are also sometimes subtitles? + //return null; } var stream = new MediaStream From 23da61281ee108954de9799761fa9c78dc4547ce Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 5 Aug 2016 23:15:48 +0200 Subject: [PATCH 081/220] Reduced compiler warnings. No functional changes (except MediaEncoder.cs and AutomaticRestartEntryPoint.cs) --- MediaBrowser.Api/ApiEntryPoint.cs | 4 ++-- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/PluginService.cs | 2 +- MediaBrowser.Common/Plugins/BasePlugin.cs | 2 +- MediaBrowser.LocalMetadata/BaseXmlProvider.cs | 2 +- MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs | 2 +- .../Connect/ConnectManager.cs | 2 +- MediaBrowser.Server.Implementations/Dto/DtoService.cs | 2 +- .../EntryPoints/ActivityLogEntryPoint.cs | 2 +- .../EntryPoints/ExternalPortForwarding.cs | 2 +- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../HttpServer/HttpListenerHost.cs | 2 +- .../HttpServer/RangeRequestWriter.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 4 ++-- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 +- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs | 2 +- .../Notifications/SqliteNotificationsRepository.cs | 2 +- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 6 +++--- 20 files changed, 24 insertions(+), 24 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 87fa3d46ca..dbc1179e22 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -559,13 +559,13 @@ namespace MediaBrowser.Api { } - catch (IOException ex) + catch (IOException) { //Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path); DeletePartialStreamFiles(path, jobType, retryCount + 1, 500); } - catch (Exception ex) + catch { //Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path); } diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ab73aabe43..a5f78420c7 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1080,7 +1080,7 @@ namespace MediaBrowser.Api.Playback //process.BeginOutputReadLine(); // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback - Task.Run(() => StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream)); + var task = Task.Run(() => StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream)); // Wait for the file to exist before proceeeding while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 3bf70715fb..7ad69fd041 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -227,7 +227,7 @@ namespace MediaBrowser.Api .ToList(); } } - catch (Exception ex) + catch { //Logger.ErrorException("Error getting plugin list", ex); // Play it safe here diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index a0716137b9..b75accf9b0 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -211,7 +211,7 @@ namespace MediaBrowser.Common.Plugins { return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); } - catch (Exception ex) + catch { return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); } diff --git a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs index 0289ffb083..f23559e4be 100644 --- a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs @@ -75,7 +75,7 @@ namespace MediaBrowser.LocalMetadata } } - public int Order + public virtual int Order { get { diff --git a/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs index 8f9d21eae8..0893f192fa 100644 --- a/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs @@ -31,7 +31,7 @@ namespace MediaBrowser.LocalMetadata.Providers return directoryService.GetFile(Path.Combine(info.Path, "series.xml")); } - public int Order + public override int Order { get { diff --git a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs index d7ef493c2c..71306e0ec0 100644 --- a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs +++ b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.MediaEncoding.Encoder else { // Kick this off, but no need to wait on it - Task.Run(async () => + var task = Task.Run(async () => { await DownloadFontFile(fontsDirectory, fontFilename, new Progress()).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 24750de94c..4e913cf994 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -151,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.Connect { DiscoveredWanIpAddress = address; - UpdateConnectInfo(); + var task = UpdateConnectInfo(); } private async Task UpdateConnectInfo() diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 779afdcf27..cc165da6a7 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1620,7 +1620,7 @@ namespace MediaBrowser.Server.Implementations.Dto { size = _imageProcessor.GetImageSize(imageInfo); } - catch (Exception ex) + catch { //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); return null; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs index 46ddf3dd8c..a36583a412 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly IInstallationManager _installationManager; //private readonly ILogManager _logManager; - private readonly ILogger _logger; + //private readonly ILogger _logger; private readonly ISessionManager _sessionManager; private readonly ITaskManager _taskManager; private readonly IActivityManager _activityManager; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 64e3c56a63..280bec65ba 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -165,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints CreateRules(device); } - catch (Exception ex) + catch { // I think it could be a good idea to log the exception because // you are using permanent portmapping here (never expire) and that means that next time diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index b616b7761a..2bb0101330 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints var changes = _changedItems.ToList(); _changedItems.Clear(); - SendNotifications(changes, CancellationToken.None); + var task = SendNotifications(changes, CancellationToken.None); if (UpdateTimer != null) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 4121c5e5e6..5cf0a246fe 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -251,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer httpRes.Close(); } - catch (Exception errorEx) + catch { //_logger.ErrorException("Error this.ProcessRequest(context)(Exception while writing error to the response)", errorEx); } diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index 71cd20743a..488c630fe4 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer } } } - catch (IOException ex) + catch (IOException) { throw; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index a36eae8d22..ee8ab7c254 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -55,8 +55,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public static EmbyTV Current; - public event EventHandler DataSourceChanged; - public event EventHandler RecordingStatusChanged; + public event EventHandler DataSourceChanged { add { } remove { } } + public event EventHandler RecordingStatusChanged { add { } remove { } } private readonly ConcurrentDictionary _activeRecordings = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index 79b26468e6..7fe271bea4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV catch (FileNotFoundException) { } - catch (DirectoryNotFoundException ex) + catch (DirectoryNotFoundException) { } catch (IOException ex) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 69b6fb5a94..fd4775938a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -431,7 +431,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false)); } } - catch (Exception ex) + catch { } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs index 71b3f8a184..0f8682b7cc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs @@ -649,7 +649,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp #region Public Events - public event PropertyChangedEventHandler PropertyChanged; + ////public event PropertyChangedEventHandler PropertyChanged; #endregion diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index be8c6d48d6..f30ba3e542 100644 --- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.Notifications public event EventHandler NotificationAdded; public event EventHandler NotificationsMarkedRead; - public event EventHandler NotificationUpdated; + ////public event EventHandler NotificationUpdated; public async Task Initialize() { diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 3f1f98cd00..ce99f0a240 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -606,7 +606,7 @@ namespace MediaBrowser.Server.Startup.Common { return new ImageMagickEncoder(LogManager.GetLogger("ImageMagick"), ApplicationPaths, HttpClient, FileSystemManager, ServerConfigurationManager); } - catch (Exception ex) + catch { Logger.Error("Error loading ImageMagick. Will revert to GDI."); } @@ -616,7 +616,7 @@ namespace MediaBrowser.Server.Startup.Common { return new GDIImageEncoder(FileSystemManager, LogManager.GetLogger("GDI")); } - catch (Exception ex) + catch { Logger.Error("Error loading GDI. Will revert to NullImageEncoder."); } @@ -1412,7 +1412,7 @@ namespace MediaBrowser.Server.Startup.Common { return new Uri(externalDns).Host; } - catch (Exception e) + catch { return externalDns; } From 319a956b3870e162b3072b52ea8c7310d5091bc6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 00:38:01 -0400 Subject: [PATCH 082/220] update validators --- MediaBrowser.Api/VideosService.cs | 18 +++++++--- .../Library/ILibraryManager.cs | 1 + .../Persistence/IItemRepository.cs | 1 + .../Library/LibraryManager.cs | 11 ++++++ .../Library/Validators/ArtistsValidator.cs | 34 +++++++++++-------- .../Library/Validators/GameGenresValidator.cs | 17 +++++----- .../Library/Validators/GenresValidator.cs | 17 +++++----- .../Validators/MusicGenresValidator.cs | 18 +++++----- .../Library/Validators/StudiosValidator.cs | 16 ++++----- .../Persistence/SqliteItemRepository.cs | 30 ++++++++++------ 10 files changed, 99 insertions(+), 64 deletions(-) diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index c8dbb7bb26..4a5eb1eab7 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Api { @@ -81,11 +82,18 @@ namespace MediaBrowser.Api var dtoOptions = GetDtoOptions(request); - var video = (Video)item; - - var items = video.GetAdditionalParts() - .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, video)) - .ToArray(); + var video = item as Video; + BaseItemDto[] items; + if (video != null) + { + items = video.GetAdditionalParts() + .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, video)) + .ToArray(); + } + else + { + items = new BaseItemDto[] { }; + } var result = new ItemsResult { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 70bd3f081c..ff7f2fe678 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -562,5 +562,6 @@ namespace MediaBrowser.Controller.Library QueryResult> GetStudios(InternalItemsQuery query); QueryResult> GetArtists(InternalItemsQuery query); QueryResult> GetAlbumArtists(InternalItemsQuery query); + QueryResult> GetAllArtists(InternalItemsQuery query); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 78138999c5..437f0e157a 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -169,6 +169,7 @@ namespace MediaBrowser.Controller.Persistence QueryResult> GetStudios(InternalItemsQuery query); QueryResult> GetArtists(InternalItemsQuery query); QueryResult> GetAlbumArtists(InternalItemsQuery query); + QueryResult> GetAllArtists(InternalItemsQuery query); } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 7af495f5a0..055fde504b 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1385,6 +1385,17 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetMusicGenres(query); } + public QueryResult> GetAllArtists(InternalItemsQuery query) + { + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + + SetTopParentOrAncestorIds(query); + return ItemRepository.GetAllArtists(query); + } + public QueryResult> GetArtists(InternalItemsQuery query) { if (query.User != null) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 2b68f98caf..353be1a44f 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -43,36 +44,39 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var allSongs = _libraryManager.RootFolder - .GetRecursiveChildren(i => !i.IsFolder && i is IHasArtist) - .Cast() + var items = _libraryManager.GetAllArtists(new InternalItemsQuery()) + .Items + .Select(i => i.Item1) .ToList(); - var allArtists = _libraryManager.GetArtists(allSongs).ToList(); - var numComplete = 0; - var numArtists = allArtists.Count; + var count = items.Count; - foreach (var artistItem in allArtists) + foreach (var item in items) { - cancellationToken.ThrowIfCancellationRequested(); - try { - await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } - catch (IOException ex) + catch (OperationCanceledException) { - _logger.ErrorException("Error validating Artist {0}", ex, artistItem.Name); + // Don't clutter the log + break; + } + catch (Exception ex) + { + _logger.ErrorException("Error refreshing {0}", ex, item.Name); } - // Update progress numComplete++; double percent = numComplete; - percent /= numArtists; + percent /= count; + percent *= 100; - progress.Report(100 * percent); + progress.Report(percent); } + + progress.Report(100); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index a149da6510..72864790b8 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -34,21 +34,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Game) - .SelectMany(i => i.Genres) - .DistinctNames() + var items = _libraryManager.GetGameGenres(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Game).Name } + }) + .Items + .Select(i => i.Item1) .ToList(); var numComplete = 0; var count = items.Count; - foreach (var name in items) + foreach (var item in items) { try { - var itemByName = _libraryManager.GetGameGenre(name); - - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -57,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, name); + _logger.ErrorException("Error refreshing {0}", ex, item.Name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index fac5cfc356..6a62d7fe47 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -35,21 +35,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => !(i is IHasMusicGenres) && !(i is Game)) - .SelectMany(i => i.Genres) - .DistinctNames() + var items = _libraryManager.GetGenres(new InternalItemsQuery + { + ExcludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Game).Name } + }) + .Items + .Select(i => i.Item1) .ToList(); var numComplete = 0; var count = items.Count; - foreach (var name in items) + foreach (var item in items) { try { - var itemByName = _libraryManager.GetGenre(name); - - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -58,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, name); + _logger.ErrorException("Error refreshing {0}", ex, item.Name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 81433e5b32..2668d84e95 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -34,21 +35,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is IHasMusicGenres) - .SelectMany(i => i.Genres) - .DistinctNames() + var items = _libraryManager.GetMusicGenres(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name } + }) + .Items + .Select(i => i.Item1) .ToList(); var numComplete = 0; var count = items.Count; - foreach (var name in items) + foreach (var item in items) { try { - var itemByName = _libraryManager.GetMusicGenre(name); - - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -57,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, name); + _logger.ErrorException("Error refreshing {0}", ex, item.Name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index 259878566b..722b74891e 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -1,10 +1,10 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -34,21 +34,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => true) - .SelectMany(i => i.Studios) - .DistinctNames() + var items = _libraryManager.GetStudios(new InternalItemsQuery()) + .Items + .Select(i => i.Item1) .ToList(); var numComplete = 0; var count = items.Count; - foreach (var name in items) + foreach (var item in items) { try { - var itemByName = _libraryManager.GetStudio(name); - - await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -57,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, name); + _logger.ErrorException("Error refreshing {0}", ex, item.Name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 2ef878a20c..21785bcbd2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3817,37 +3817,42 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + public QueryResult> GetAllArtists(InternalItemsQuery query) + { + return GetItemValues(query, new[] { 0, 1 }, typeof(MusicArtist).FullName); + } + public QueryResult> GetArtists(InternalItemsQuery query) { - return GetItemValues(query, 0, typeof(MusicArtist).FullName); + return GetItemValues(query, new[] { 0 }, typeof(MusicArtist).FullName); } public QueryResult> GetAlbumArtists(InternalItemsQuery query) { - return GetItemValues(query, 1, typeof(MusicArtist).FullName); + return GetItemValues(query, new[] { 1 }, typeof(MusicArtist).FullName); } public QueryResult> GetStudios(InternalItemsQuery query) { - return GetItemValues(query, 3, typeof(Studio).FullName); + return GetItemValues(query, new[] { 3 }, typeof(Studio).FullName); } public QueryResult> GetGenres(InternalItemsQuery query) { - return GetItemValues(query, 2, typeof(Genre).FullName); + return GetItemValues(query, new[] { 2 }, typeof(Genre).FullName); } public QueryResult> GetGameGenres(InternalItemsQuery query) { - return GetItemValues(query, 2, typeof(GameGenre).FullName); + return GetItemValues(query, new[] { 2 }, typeof(GameGenre).FullName); } public QueryResult> GetMusicGenres(InternalItemsQuery query) { - return GetItemValues(query, 2, typeof(MusicGenre).FullName); + return GetItemValues(query, new[] { 2 }, typeof(MusicGenre).FullName); } - private QueryResult> GetItemValues(InternalItemsQuery query, int itemValueType, string returnType) + private QueryResult> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType) { if (query == null) { @@ -3863,6 +3868,10 @@ namespace MediaBrowser.Server.Implementations.Persistence var now = DateTime.UtcNow; + var typeClause = itemValueTypes.Length == 1 ? + ("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) : + ("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")"); + using (var cmd = _connection.CreateCommand()) { var itemCountColumns = new List>(); @@ -3887,7 +3896,7 @@ namespace MediaBrowser.Server.Implementations.Persistence }; var whereClauses = GetWhereClauses(typeSubQuery, cmd, "itemTypes"); - whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND Type=@ItemValueType)"); + whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND " + typeClause + ")"); var typeWhereText = whereClauses.Count == 0 ? string.Empty : @@ -3929,12 +3938,12 @@ namespace MediaBrowser.Server.Implementations.Persistence if (typesToCount.Count == 0) { - whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; + whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; } else { //whereText += " And itemTypes not null"; - whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; + whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; } var outerQuery = new InternalItemsQuery(query.User) @@ -3964,7 +3973,6 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += " group by PresentationUniqueKey"; cmd.Parameters.Add(cmd, "@SelectType", DbType.String).Value = returnType; - cmd.Parameters.Add(cmd, "@ItemValueType", DbType.Int32).Value = itemValueType; if (EnableJoinUserData(query)) { From 0706bd5237125c8b95a7b8fa1576aa061703a397 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 00:48:00 -0400 Subject: [PATCH 083/220] update DirectoryService --- MediaBrowser.Api/ItemRefreshService.cs | 7 +++++-- .../Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- .../Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Controller/Entities/User.cs | 2 +- .../Providers/DirectoryService.cs | 18 +++++++++++++----- .../Providers/MetadataRefreshOptions.cs | 3 ++- .../Manager/ProviderManager.cs | 4 ++-- .../Subtitles/SubtitleManager.cs | 2 +- .../TV/MissingEpisodeProvider.cs | 2 +- 11 files changed, 29 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index 5aab15dff1..a918e841fb 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Providers; using ServiceStack; using System.Threading; using CommonIO; +using MediaBrowser.Model.Logging; namespace MediaBrowser.Api { @@ -39,12 +40,14 @@ namespace MediaBrowser.Api private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; - public ItemRefreshService(ILibraryManager libraryManager, IProviderManager providerManager, IFileSystem fileSystem) + public ItemRefreshService(ILibraryManager libraryManager, IProviderManager providerManager, IFileSystem fileSystem, ILogger logger) { _libraryManager = libraryManager; _providerManager = providerManager; _fileSystem = fileSystem; + _logger = logger; } /// @@ -69,7 +72,7 @@ namespace MediaBrowser.Api private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request) { - return new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + return new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) { MetadataRefreshMode = request.MetadataRefreshMode, ImageRefreshMode = request.ImageRefreshMode, diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 588a65e98d..7b42310101 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -76,7 +76,7 @@ namespace MediaBrowser.Controller.Entities { var locations = PhysicalLocations.ToList(); - var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList(); + var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList(); if (!locations.SequenceEqual(newLocations)) { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index c7a6b75ff2..8d00f38beb 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1003,7 +1003,7 @@ namespace MediaBrowser.Controller.Entities public Task RefreshMetadata(CancellationToken cancellationToken) { - return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken); + return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)), cancellationToken); } /// diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 35dfd52e9d..8bf9919f25 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Controller.Entities { var locations = PhysicalLocations.ToList(); - var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList(); + var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList(); if (!locations.SequenceEqual(newLocations)) { diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 6a7e279be8..bb3d4f73df 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -278,7 +278,7 @@ namespace MediaBrowser.Controller.Entities public Task ValidateChildren(IProgress progress, CancellationToken cancellationToken) { - return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(FileSystem))); + return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem))); } /// diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 5c68308f5c..46da469fa5 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -213,7 +213,7 @@ namespace MediaBrowser.Controller.Entities Name = newName; - return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)) + return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)) { ReplaceAllMetadata = true, ImageRefreshMode = ImageRefreshMode.FullRefresh, diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index e7e3323c2b..62d424696b 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Providers _fileSystem = fileSystem; } - public DirectoryService(IFileSystem fileSystem) + public DirectoryService(IFileSystem fileSystem) : this(new NullLogger(), fileSystem) { } @@ -108,12 +108,20 @@ namespace MediaBrowser.Controller.Providers return null; } - var dict = GetFileSystemDictionary(directory, false); + try + { + var dict = GetFileSystemDictionary(directory, false); - FileSystemMetadata entry; - dict.TryGetValue(path, out entry); + FileSystemMetadata entry; + dict.TryGetValue(path, out entry); - return entry; + return entry; + } + catch (Exception ex) + { + _logger.ErrorException("Error in GetFileSystemDictionary. Directory: :{0}. Original path: {1}", ex, directory, path); + return null; + } } public IEnumerable GetDirectories(string path) diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs index 9427b2afd7..87c3b36a27 100644 --- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -1,5 +1,6 @@ using System.Linq; using CommonIO; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; namespace MediaBrowser.Controller.Providers @@ -19,7 +20,7 @@ namespace MediaBrowser.Controller.Providers public bool ForceSave { get; set; } public MetadataRefreshOptions(IFileSystem fileSystem) - : this(new DirectoryService(fileSystem)) + : this(new DirectoryService(new NullLogger(), fileSystem)) { } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 0f0745d1bc..25b9b4fd5e 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -298,7 +298,7 @@ namespace MediaBrowser.Providers.Manager { var options = GetMetadataOptions(item); - return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_fileSystem)), includeDisabled).OfType(); + return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType(); } private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem) @@ -488,7 +488,7 @@ namespace MediaBrowser.Providers.Manager ItemType = typeof(T).Name }; - var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_fileSystem)), true).ToList(); + var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList(); AddMetadataPlugins(summary.Plugins, dummy, options); AddImagePlugins(summary.Plugins, dummy, imageProviders); diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 764cb73177..a57e7d2c0c 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -254,7 +254,7 @@ namespace MediaBrowser.Providers.Subtitles _monitor.ReportFileSystemChangeComplete(path, false); } - return _libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + return _libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) { ImageRefreshMode = ImageRefreshMode.ValidationOnly, MetadataRefreshMode = MetadataRefreshMode.ValidationOnly diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index afa1abbbb9..a12402f4ff 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.TV { foreach (var series in group) { - var directoryService = new DirectoryService(_fileSystem); + var directoryService = new DirectoryService(_logger, _fileSystem); await series.RefreshMetadata(new MetadataRefreshOptions(directoryService), cancellationToken).ConfigureAwait(false); From 7f0d4c72109e4e647f6388dc2286891e749db268 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 00:50:24 -0400 Subject: [PATCH 084/220] 3.1.91 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 07028185d1..e35552d6a6 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.90")] +[assembly: AssemblyVersion("3.1.91")] From 7d5a4c078d5e440e0e21baf607b13f313e0efe97 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 10:07:44 -0400 Subject: [PATCH 085/220] update components --- MediaBrowser.sln | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.sln b/MediaBrowser.sln index a55ae200a8..c6068f5364 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Performance3.psess = Performance3.psess Performance4.psess = Performance4.psess Performance5.psess = Performance5.psess + Performance6.psess = Performance6.psess + Performance7.psess = Performance7.psess EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget (2)", ".nuget (2)", "{E60FB157-87E2-4A41-8B04-27EA49B63B4D}" @@ -63,6 +65,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms From 24003580e7977b5336661921f55a919a62a3194f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 10:08:38 -0400 Subject: [PATCH 086/220] improve stopping of progressive streams --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- .../BaseProgressiveStreamingService.cs | 20 +++++++-- .../Progressive/ProgressiveStreamWriter.cs | 42 ++++++++++++------- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index dbc1179e22..1a7f4a2b12 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -349,7 +349,7 @@ namespace MediaBrowser.Api return; } - var timerDuration = 1000; + var timerDuration = 10000; if (job.Type != TranscodingJobType.Progressive) { diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 449100fc42..4649499c46 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -142,7 +142,8 @@ namespace MediaBrowser.Api.Playback.Progressive var outputPath = state.OutputFilePath; var outputPathExists = FileSystem.FileExists(outputPath); - var isTranscodeCached = outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive); + var transcodingJob = ApiEntryPoint.Instance.GetTranscodingJob(outputPath, TranscodingJobType.Progressive); + var isTranscodeCached = outputPathExists && transcodingJob != null; AddDlnaHeaders(state, responseHeaders, request.Static || isTranscodeCached); @@ -159,6 +160,7 @@ namespace MediaBrowser.Api.Playback.Progressive ContentType = contentType, IsHeadRequest = isHeadRequest, Path = state.MediaPath + }).ConfigureAwait(false); } } @@ -170,13 +172,25 @@ namespace MediaBrowser.Api.Playback.Progressive try { + if (transcodingJob != null) + { + ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob); + } + return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { ResponseHeaders = responseHeaders, ContentType = contentType, IsHeadRequest = isHeadRequest, Path = outputPath, - FileShare = FileShare.ReadWrite + FileShare = FileShare.ReadWrite, + OnComplete = () => + { + if (transcodingJob != null) + { + ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob); + } + } }).ConfigureAwait(false); } @@ -348,7 +362,7 @@ namespace MediaBrowser.Api.Playback.Progressive outputHeaders[item.Key] = item.Value; } - Func streamWriter = stream => new ProgressiveFileCopier(FileSystem, job, Logger).StreamFile(outputPath, stream, CancellationToken.None); + Func streamWriter = stream => new ProgressiveFileCopier(FileSystem, job, Logger).StreamFile(outputPath, stream, CancellationToken.None); return ResultFactory.GetAsyncStreamWriter(streamWriter, outputHeaders); } diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 2019b73c86..63d71b85ef 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -27,31 +27,41 @@ namespace MediaBrowser.Api.Playback.Progressive public async Task StreamFile(string path, Stream outputStream, CancellationToken cancellationToken) { - var eofCount = 0; - - using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) + try { - while (eofCount < 15) + var eofCount = 0; + + using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) { - var bytesRead = await CopyToAsyncInternal(fs, outputStream, BufferSize, cancellationToken).ConfigureAwait(false); + while (eofCount < 15) + { + var bytesRead = await CopyToAsyncInternal(fs, outputStream, BufferSize, cancellationToken).ConfigureAwait(false); - //var position = fs.Position; - //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); + //var position = fs.Position; + //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); - if (bytesRead == 0) - { - if (_job == null || _job.HasExited) + if (bytesRead == 0) { - eofCount++; + if (_job == null || _job.HasExited) + { + eofCount++; + } + await Task.Delay(100, cancellationToken).ConfigureAwait(false); + } + else + { + eofCount = 0; } - await Task.Delay(100, cancellationToken).ConfigureAwait(false); - } - else - { - eofCount = 0; } } } + finally + { + if (_job != null) + { + ApiEntryPoint.Instance.OnTranscodeEndRequest(_job); + } + } } private async Task CopyToAsyncInternal(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken) From c3d8115bc8aa37fe0fae60b05c5f273d06627b8e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 10:09:03 -0400 Subject: [PATCH 087/220] update directory service --- .../Providers/DirectoryService.cs | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index 62d424696b..ca9038439e 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -100,28 +100,29 @@ namespace MediaBrowser.Controller.Providers public FileSystemMetadata GetFile(string path) { - var directory = Path.GetDirectoryName(path); - - if (string.IsNullOrWhiteSpace(directory)) - { - _logger.Debug("Parent path is null for {0}", path); - return null; - } - - try - { - var dict = GetFileSystemDictionary(directory, false); - - FileSystemMetadata entry; - dict.TryGetValue(path, out entry); - - return entry; - } - catch (Exception ex) - { - _logger.ErrorException("Error in GetFileSystemDictionary. Directory: :{0}. Original path: {1}", ex, directory, path); - return null; - } + return _fileSystem.GetFileInfo(path); + //var directory = Path.GetDirectoryName(path); + + //if (string.IsNullOrWhiteSpace(directory)) + //{ + // _logger.Debug("Parent path is null for {0}", path); + // return null; + //} + + //try + //{ + // var dict = GetFileSystemDictionary(directory, false); + + // FileSystemMetadata entry; + // dict.TryGetValue(path, out entry); + + // return entry; + //} + //catch (Exception ex) + //{ + // _logger.ErrorException("Error in GetFileSystemDictionary. Directory: :{0}. Original path: {1}", ex, directory, path); + // return null; + //} } public IEnumerable GetDirectories(string path) From a571ee38ceafc0a1f30ded3f5bd2c6aba1d940da Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 10:11:47 -0400 Subject: [PATCH 088/220] 3.1.92 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index e35552d6a6..ac12faf1cd 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.91")] +[assembly: AssemblyVersion("3.1.92")] From 7b00ad316c4f717d17e8aa819a62277ae2afe6f1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 15:56:35 -0400 Subject: [PATCH 089/220] update SocketHttpListener --- .../Library/Validators/PeopleValidator.cs | 4 ++-- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 8430809501..aa993d1768 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -125,7 +125,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 90; - performFullRefresh = false; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh @@ -138,7 +137,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var options = new MetadataRefreshOptions(_fileSystem) { MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly, - ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly + ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly, + ForceSave = performFullRefresh }; await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 6c7c2ed283..dca7531934 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -73,8 +73,8 @@ ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True - - ..\packages\SocketHttpListener.1.0.0.37\lib\net45\SocketHttpListener.dll + + ..\packages\SocketHttpListener.1.0.0.38\lib\net45\SocketHttpListener.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index f8b0ab41db..8f4795d532 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -9,5 +9,5 @@ - + \ No newline at end of file From 7835d3d629a8a39b2830fa906a0479c19b3e6321 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 16:59:31 -0400 Subject: [PATCH 090/220] fix artist case sensitivity searches --- MediaBrowser.Api/StartupWizardService.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 1bebd42eb1..ef898eb53e 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Api config.EnableStandaloneMusicKeys = true; config.EnableCaseSensitiveItemIds = true; //config.EnableFolderView = true; - config.SchemaVersion = 108; + config.SchemaVersion = 109; } public void Post(UpdateStartupConfiguration request) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 21785bcbd2..b4f8245ed8 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 108; + public const int LatestSchemaVersion = 109; /// /// Initializes a new instance of the class. @@ -915,7 +915,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - _saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics(); + _saveItemCommand.GetParameter(index++).Value = GetCleanValue(item.Name); } _saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey; @@ -2763,13 +2763,13 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!string.IsNullOrWhiteSpace(query.Name)) { whereClauses.Add("CleanName=@Name"); - cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = query.Name.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = GetCleanValue(query.Name); } if (!string.IsNullOrWhiteSpace(query.NameContains)) { whereClauses.Add("CleanName like @NameContains"); - cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains.RemoveDiacritics() + "%"; + cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + GetCleanValue(query.NameContains) + "%"; } if (!string.IsNullOrWhiteSpace(query.NameStartsWith)) { @@ -2877,7 +2877,7 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var artist in query.ArtistNames) { clauses.Add("@ArtistName" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)"); - cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = GetCleanValue(artist); index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2894,7 +2894,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (artistItem != null) { clauses.Add("@ExcludeArtistName" + index + " not in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)"); - cmd.Parameters.Add(cmd, "@ExcludeArtistName" + index, DbType.String).Value = artistItem.Name.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@ExcludeArtistName" + index, DbType.String).Value = GetCleanValue(artistItem.Name); index++; } } @@ -2915,7 +2915,7 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var item in query.Genres) { clauses.Add("@Genre" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=2)"); - cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = GetCleanValue(item); index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2929,7 +2929,7 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var item in query.Tags) { clauses.Add("@Tag" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=4)"); - cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = GetCleanValue(item); index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2949,7 +2949,7 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var item in query.Studios) { clauses.Add("@Studio" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=3)"); - cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = GetCleanValue(item); index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2963,7 +2963,7 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var item in query.Keywords) { clauses.Add("@Keyword" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=5)"); - cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item.RemoveDiacritics(); + cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = GetCleanValue(item); index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -3298,6 +3298,16 @@ namespace MediaBrowser.Server.Implementations.Persistence return whereClauses; } + private string GetCleanValue(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return value; + } + + return value.RemoveDiacritics().ToLower(); + } + private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query) { if (!query.GroupByPresentationUniqueKey) @@ -4024,7 +4034,7 @@ namespace MediaBrowser.Server.Implementations.Persistence ? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult) : CommandBehavior.SequentialAccess; - //Logger.Debug("GetItemValues: " + cmd.CommandText); + Logger.Debug("GetItemValues: " + cmd.CommandText); using (var reader = cmd.ExecuteReader(commandBehavior)) { @@ -4268,7 +4278,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - _saveItemValuesCommand.GetParameter(3).Value = pair.Item2.RemoveDiacritics(); + _saveItemValuesCommand.GetParameter(3).Value = GetCleanValue(pair.Item2); } _saveItemValuesCommand.Transaction = transaction; From 894d87fabb812152c76443afcf1739fda7c578ff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 17:10:18 -0400 Subject: [PATCH 091/220] add file cache --- .../Providers/DirectoryService.cs | 41 ++++++++----------- .../Manager/MetadataService.cs | 30 -------------- 2 files changed, 17 insertions(+), 54 deletions(-) diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index ca9038439e..ee2b28c60a 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -16,7 +16,10 @@ namespace MediaBrowser.Controller.Providers private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); - public DirectoryService(ILogger logger, IFileSystem fileSystem) + private readonly ConcurrentDictionary _fileCache = + new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + + public DirectoryService(ILogger logger, IFileSystem fileSystem) { _logger = logger; _fileSystem = fileSystem; @@ -100,29 +103,19 @@ namespace MediaBrowser.Controller.Providers public FileSystemMetadata GetFile(string path) { - return _fileSystem.GetFileInfo(path); - //var directory = Path.GetDirectoryName(path); - - //if (string.IsNullOrWhiteSpace(directory)) - //{ - // _logger.Debug("Parent path is null for {0}", path); - // return null; - //} - - //try - //{ - // var dict = GetFileSystemDictionary(directory, false); - - // FileSystemMetadata entry; - // dict.TryGetValue(path, out entry); - - // return entry; - //} - //catch (Exception ex) - //{ - // _logger.ErrorException("Error in GetFileSystemDictionary. Directory: :{0}. Original path: {1}", ex, directory, path); - // return null; - //} + FileSystemMetadata file; + if (!_fileCache.TryGetValue(path, out file)) + { + file = _fileSystem.GetFileInfo(path); + + if (file != null) + { + _fileCache.TryAdd(path, file); + } + } + + return file; + //return _fileSystem.GetFileInfo(path); } public IEnumerable GetDirectories(string path) diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 9c108ac7d3..ac942d1a76 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -349,9 +349,6 @@ namespace MediaBrowser.Providers.Manager if (!runAllProviders) { - // Avoid implicitly captured closure - var currentItem = item; - var providersWithChanges = providers .Where(i => { @@ -361,12 +358,6 @@ namespace MediaBrowser.Providers.Manager return HasChanged(item, hasFileChangeMonitor, options.DirectoryService); } - var hasChangeMonitor = i as IHasChangeMonitor; - if (hasChangeMonitor != null) - { - return HasChanged(item, hasChangeMonitor, currentItem.DateLastSaved, options.DirectoryService); - } - return false; }) .ToList(); @@ -726,27 +717,6 @@ namespace MediaBrowser.Providers.Manager return false; } } - - private bool HasChanged(IHasMetadata item, IHasChangeMonitor changeMonitor, DateTime date, IDirectoryService directoryService) - { - try - { - var hasChanged = changeMonitor.HasChanged(item, directoryService, date); - - //if (hasChanged) - //{ - // Logger.Debug("{0} reports change to {1} since {2}", changeMonitor.GetType().Name, - // item.Path ?? item.Name, date); - //} - - return hasChanged; - } - catch (Exception ex) - { - Logger.ErrorException("Error in {0}.HasChanged", ex, changeMonitor.GetType().Name); - return false; - } - } } public class RefreshResult From 1640bcb28904bccb0c31a00377a9399925cf327d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Aug 2016 17:11:43 -0400 Subject: [PATCH 092/220] 3.1.93 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index ac12faf1cd..ed6157b188 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.92")] +[assembly: AssemblyVersion("3.1.93")] From 433254c498d2e43acfd34e5c4fcee2fdcc2e767b Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 5 Aug 2016 06:08:11 +0200 Subject: [PATCH 093/220] Async stream handling: Use interface instead of Func No functional changes --- .../BaseProgressiveStreamingService.cs | 4 +- .../Progressive/ProgressiveStreamWriter.cs | 23 ++- .../MediaBrowser.Controller.csproj | 1 + .../Net/IAsyncStreamSource.cs | 18 +++ .../Net/IHttpResultFactory.cs | 2 +- ...reamWriterFunc.cs => AsyncStreamWriter.cs} | 35 ++-- .../HttpServer/AsyncStreamWriterEx.cs | 153 ++++++++++++++++++ .../HttpServer/HttpResultFactory.cs | 9 +- ...MediaBrowser.Server.Implementations.csproj | 3 +- 9 files changed, 223 insertions(+), 25 deletions(-) create mode 100644 MediaBrowser.Controller/Net/IAsyncStreamSource.cs rename MediaBrowser.Server.Implementations/HttpServer/{AsyncStreamWriterFunc.cs => AsyncStreamWriter.cs} (50%) create mode 100644 MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 4649499c46..5a5cb80000 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -362,9 +362,9 @@ namespace MediaBrowser.Api.Playback.Progressive outputHeaders[item.Key] = item.Value; } - Func streamWriter = stream => new ProgressiveFileCopier(FileSystem, job, Logger).StreamFile(outputPath, stream, CancellationToken.None); + var streamSource = new ProgressiveFileCopier(FileSystem, outputPath, outputHeaders, job, Logger, CancellationToken.None); - return ResultFactory.GetAsyncStreamWriter(streamWriter, outputHeaders); + return ResultFactory.GetAsyncStreamWriter(streamSource); } finally { diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 63d71b85ef..8c4e23a397 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -4,28 +4,45 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Net; +using System.Collections.Generic; +using ServiceStack.Web; namespace MediaBrowser.Api.Playback.Progressive { - public class ProgressiveFileCopier + public class ProgressiveFileCopier : IAsyncStreamSource, IHasOptions { private readonly IFileSystem _fileSystem; private readonly TranscodingJob _job; private readonly ILogger _logger; + private readonly string _path; + private readonly CancellationToken _cancellationToken; + private readonly Dictionary _outputHeaders; // 256k private const int BufferSize = 81920; private long _bytesWritten = 0; - public ProgressiveFileCopier(IFileSystem fileSystem, TranscodingJob job, ILogger logger) + public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary outputHeaders, TranscodingJob job, ILogger logger, CancellationToken cancellationToken) { _fileSystem = fileSystem; + _path = path; + _outputHeaders = outputHeaders; _job = job; _logger = logger; + _cancellationToken = cancellationToken; } - public async Task StreamFile(string path, Stream outputStream, CancellationToken cancellationToken) + public IDictionary Options + { + get + { + return _outputHeaders; + } + } + + public async Task WriteToAsync(Stream outputStream) { try { diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 0462117cb5..e7eaa1dc0b 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -236,6 +236,7 @@ + diff --git a/MediaBrowser.Controller/Net/IAsyncStreamSource.cs b/MediaBrowser.Controller/Net/IAsyncStreamSource.cs new file mode 100644 index 0000000000..0f41f60a55 --- /dev/null +++ b/MediaBrowser.Controller/Net/IAsyncStreamSource.cs @@ -0,0 +1,18 @@ +using ServiceStack.Web; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Interface IAsyncStreamSource + /// Enables asynchronous writing to http resonse streams + /// + public interface IAsyncStreamSource + { + /// + /// Asynchronously write to the response stream. + /// + Task WriteToAsync(Stream responseStream); + } +} diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index 49d4614d81..8fdb1ce37e 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Net /// System.Object. object GetResult(object content, string contentType, IDictionary responseHeaders = null); - object GetAsyncStreamWriter(Func streamWriter, IDictionary responseHeaders = null); + object GetAsyncStreamWriter(IAsyncStreamSource streamSource); /// /// Gets the optimized result. diff --git a/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterFunc.cs b/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriter.cs similarity index 50% rename from MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterFunc.cs rename to MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriter.cs index 5aa01c7062..e44b0c6af1 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterFunc.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriter.cs @@ -4,38 +4,41 @@ using System.IO; using System.Threading.Tasks; using ServiceStack; using ServiceStack.Web; +using MediaBrowser.Controller.Net; namespace MediaBrowser.Server.Implementations.HttpServer { - public class AsyncStreamWriterFunc : IStreamWriter, IAsyncStreamWriter, IHasOptions + public class AsyncStreamWriter : IStreamWriter, IAsyncStreamWriter, IHasOptions { /// /// Gets or sets the source stream. /// /// The source stream. - private Func Writer { get; set; } - - /// - /// Gets the options. - /// - /// The options. - public IDictionary Options { get; private set; } + private IAsyncStreamSource _source; public Action OnComplete { get; set; } public Action OnError { get; set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public AsyncStreamWriterFunc(Func writer, IDictionary headers) + public AsyncStreamWriter(IAsyncStreamSource source) { - Writer = writer; + _source = source; + } - if (headers == null) + public IDictionary Options + { + get { - headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + var hasOptions = _source as IHasOptions; + if (hasOptions != null) + { + return hasOptions.Options; + } + + return new Dictionary(StringComparer.OrdinalIgnoreCase); } - Options = headers; } /// @@ -44,13 +47,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// The response stream. public void WriteTo(Stream responseStream) { - var task = Writer(responseStream); + var task = _source.WriteToAsync(responseStream); Task.WaitAll(task); } public async Task WriteToAsync(Stream responseStream) { - await Writer(responseStream).ConfigureAwait(false); + await _source.WriteToAsync(responseStream).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs b/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs new file mode 100644 index 0000000000..b98addb317 --- /dev/null +++ b/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using ServiceStack; +using ServiceStack.Web; +using MediaBrowser.Controller.Net; + +namespace MediaBrowser.Server.Implementations.HttpServer +{ + public class AsyncStreamWriterEx : AsyncStreamWriter, IHttpResult + { + /// + /// Gets or sets the source stream. + /// + /// The source stream. + private IAsyncStreamSource _source; + + /// + /// Initializes a new instance of the class. + /// + public AsyncStreamWriterEx(IAsyncStreamSource source) : base(source) + { + _source = source; + } + + public string ContentType + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public List Cookies + { + get { throw new NotImplementedException(); } + } + + public Dictionary Headers + { + get { throw new NotImplementedException(); } + } + + public int PaddingLength + { + get + { + return Result.PaddingLength; + } + set + { + Result.PaddingLength = value; + } + } + + public IRequest RequestContext + { + get + { + return Result.RequestContext; + } + set + { + Result.RequestContext = value; + } + } + + public object Response + { + get + { + return Result.Response; + } + set + { + Result.Response = value; + } + } + + public IContentTypeWriter ResponseFilter + { + get + { + return Result.ResponseFilter; + } + set + { + Result.ResponseFilter = value; + } + } + + public Func ResultScope + { + get + { + return Result.ResultScope; + } + set + { + Result.ResultScope = value; + } + } + + public int Status + { + get + { + return Result.Status; + } + set + { + Result.Status = value; + } + } + + public System.Net.HttpStatusCode StatusCode + { + get + { + return Result.StatusCode; + } + set + { + Result.StatusCode = value; + } + } + + public string StatusDescription + { + get + { + return Result.StatusDescription; + } + set + { + Result.StatusDescription = value; + } + } + + private IHttpResult Result + { + get + { + return _source as IHttpResult; + } + } + } +} diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index c0a2a5eb35..f234674d82 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -704,9 +704,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer throw error; } - public object GetAsyncStreamWriter(Func streamWriter, IDictionary responseHeaders = null) + public object GetAsyncStreamWriter(IAsyncStreamSource streamSource) { - return new AsyncStreamWriterFunc(streamWriter, responseHeaders); + if (streamSource as IHttpResult != null) + { + return new AsyncStreamWriterEx(streamSource); + } + + return new AsyncStreamWriter(streamSource); } } } \ 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 dca7531934..8025e3594e 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -156,7 +156,8 @@ - + + From 7d16988b1b81cc73608c07d61eabb83f8fcbbb05 Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 5 Aug 2016 19:07:43 +0200 Subject: [PATCH 094/220] Remove handling IHttpResult --- .../HttpServer/AsyncStreamWriterEx.cs | 153 ------------------ .../HttpServer/HttpResultFactory.cs | 5 - ...MediaBrowser.Server.Implementations.csproj | 1 - 3 files changed, 159 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs diff --git a/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs b/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs deleted file mode 100644 index b98addb317..0000000000 --- a/MediaBrowser.Server.Implementations/HttpServer/AsyncStreamWriterEx.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using ServiceStack; -using ServiceStack.Web; -using MediaBrowser.Controller.Net; - -namespace MediaBrowser.Server.Implementations.HttpServer -{ - public class AsyncStreamWriterEx : AsyncStreamWriter, IHttpResult - { - /// - /// Gets or sets the source stream. - /// - /// The source stream. - private IAsyncStreamSource _source; - - /// - /// Initializes a new instance of the class. - /// - public AsyncStreamWriterEx(IAsyncStreamSource source) : base(source) - { - _source = source; - } - - public string ContentType - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - - public List Cookies - { - get { throw new NotImplementedException(); } - } - - public Dictionary Headers - { - get { throw new NotImplementedException(); } - } - - public int PaddingLength - { - get - { - return Result.PaddingLength; - } - set - { - Result.PaddingLength = value; - } - } - - public IRequest RequestContext - { - get - { - return Result.RequestContext; - } - set - { - Result.RequestContext = value; - } - } - - public object Response - { - get - { - return Result.Response; - } - set - { - Result.Response = value; - } - } - - public IContentTypeWriter ResponseFilter - { - get - { - return Result.ResponseFilter; - } - set - { - Result.ResponseFilter = value; - } - } - - public Func ResultScope - { - get - { - return Result.ResultScope; - } - set - { - Result.ResultScope = value; - } - } - - public int Status - { - get - { - return Result.Status; - } - set - { - Result.Status = value; - } - } - - public System.Net.HttpStatusCode StatusCode - { - get - { - return Result.StatusCode; - } - set - { - Result.StatusCode = value; - } - } - - public string StatusDescription - { - get - { - return Result.StatusDescription; - } - set - { - Result.StatusDescription = value; - } - } - - private IHttpResult Result - { - get - { - return _source as IHttpResult; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index f234674d82..b26cf5b769 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -706,11 +706,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer public object GetAsyncStreamWriter(IAsyncStreamSource streamSource) { - if (streamSource as IHttpResult != null) - { - return new AsyncStreamWriterEx(streamSource); - } - return new AsyncStreamWriter(streamSource); } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 8025e3594e..07cb9fa0d7 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -156,7 +156,6 @@ - From 05b53d1f30bf5bf52fc36a351a2a9b4619341b68 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sat, 30 Jul 2016 05:58:15 +0200 Subject: [PATCH 095/220] Avoid frequent Exception --- .../Connect/ConnectManager.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 4e913cf994..45cb2f57d5 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -65,12 +65,11 @@ namespace MediaBrowser.Server.Implementations.Connect if (!string.IsNullOrWhiteSpace(address)) { - try - { - address = new Uri(address).Host; - } - catch + Uri newUri; + + if (Uri.TryCreate(address, UriKind.Absolute, out newUri)) { + address = newUri.Host; } } From 0b13c335be77e694ea96f24c3a9990325b59aecd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 02:15:03 -0400 Subject: [PATCH 096/220] update dialogs --- MediaBrowser.Dlna/DlnaManager.cs | 3 +-- MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs | 6 +++--- MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 42e976ce8b..931cc208f5 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -248,8 +248,7 @@ namespace MediaBrowser.Dlna //_logger.Debug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch); return isMatch; case HeaderMatchType.Regex: - // Reports of IgnoreCase not working on linux so try it a couple different ways. - return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase) || Regex.IsMatch(value.ToUpper(), header.Value.ToUpper(), RegexOptions.IgnoreCase); + return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase); default: throw new ArgumentException("Unrecognized HeaderMatchType"); } diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs index c117d030f9..1cfd96f362 100644 --- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs @@ -21,8 +21,8 @@ namespace MediaBrowser.Dlna.Profiles new HttpHeaderInfo { Name = "User-Agent", - Value = @".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*.", - Match = HeaderMatchType.Regex + Value = @"SEC_", + Match = HeaderMatchType.Substring } } }; @@ -349,4 +349,4 @@ namespace MediaBrowser.Dlna.Profiles }; } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index c806c1238b..6c1b405890 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -4,7 +4,7 @@ samsung.com - + Emby From e9bd472281aa2b3bba49f0b463469d22c89a0caa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 02:36:48 -0400 Subject: [PATCH 097/220] update SocketHttpListener --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- MediaBrowser.sln | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index dca7531934..52723688fb 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -73,8 +73,8 @@ ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True - - ..\packages\SocketHttpListener.1.0.0.38\lib\net45\SocketHttpListener.dll + + ..\packages\SocketHttpListener.1.0.0.39\lib\net45\SocketHttpListener.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 8f4795d532..bac5a7c5d0 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -9,5 +9,5 @@ - + \ No newline at end of file diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c6068f5364..cf4a5428c2 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -65,9 +65,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms From dd013bf622759e3ca13a1236d3f016dc5051ce47 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 02:40:05 -0400 Subject: [PATCH 098/220] 3.1.94 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index ed6157b188..9596e1d73d 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.93")] +[assembly: AssemblyVersion("3.1.94")] From 792da5967eec466200a79788ac115da2946374b0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 14:46:11 -0400 Subject: [PATCH 099/220] remove unused strings --- .../ConsistencyTests/StringUsageReporter.cs | 14 +++++++------- MediaBrowser.sln | 3 +++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs index bea709c5c8..5234f7857e 100644 --- a/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs +++ b/MediaBrowser.Tests/ConsistencyTests/StringUsageReporter.cs @@ -71,7 +71,7 @@ namespace MediaBrowser.Tests.ConsistencyTests /// /// List of file extension to search. /// - public static string[] TargetExtensions = new[] { "js", "html" }; + public static string[] TargetExtensions = new[] { ".js", ".html" }; /// /// List of paths to exclude from search. @@ -96,11 +96,11 @@ namespace MediaBrowser.Tests.ConsistencyTests } } - [TestMethod] - public void ReportStringUsage() - { - this.CheckDashboardStrings(false); - } + //[TestMethod] + //public void ReportStringUsage() + //{ + // this.CheckDashboardStrings(false); + //} [TestMethod] public void ReportUnusedStrings() @@ -135,7 +135,7 @@ namespace MediaBrowser.Tests.ConsistencyTests var allFiles = rootFolderInfo.GetFiles("*", SearchOption.AllDirectories); - var filteredFiles1 = allFiles.Where(f => TargetExtensions.Any(e => f.Name.EndsWith(e))); + var filteredFiles1 = allFiles.Where(f => TargetExtensions.Any(e => string.Equals(e, f.Extension, StringComparison.OrdinalIgnoreCase))); var filteredFiles2 = filteredFiles1.Where(f => !ExcludePaths.Any(p => f.FullName.Contains(p))); var selectedFiles = filteredFiles2.OrderBy(f => f.FullName).ToList(); diff --git a/MediaBrowser.sln b/MediaBrowser.sln index cf4a5428c2..c6068f5364 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -65,6 +65,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms From 7daf34f048c162f0fc2e5b4d28935f0c93c3c281 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 16:13:30 -0400 Subject: [PATCH 100/220] quote ffmpeg params --- MediaBrowser.Api/Playback/Progressive/VideoService.cs | 6 +++--- MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 3 ++- MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs | 4 ++-- .../LiveTv/EmbyTV/EncodedRecorder.cs | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 3fd67c51ea..21e8845f5f 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -149,11 +149,11 @@ namespace MediaBrowser.Api.Playback.Progressive { args += " -copyts -avoid_negative_ts disabled -start_at_zero"; } - + return args; } - var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", 5.ToString(UsCulture)); args += keyFrameArg; @@ -237,4 +237,4 @@ namespace MediaBrowser.Api.Playback.Progressive return args; } } -} +} \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 5d3db612f6..a450097fd2 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -87,6 +87,7 @@ namespace MediaBrowser.MediaEncoding.Encoder "h264_nvenc", "h264_qsv", "h264_omx", + "h264_vaapi", "ac3" }; @@ -156,4 +157,4 @@ namespace MediaBrowser.MediaEncoding.Encoder } } } -} +} \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs index d65e057834..457fbe2c26 100644 --- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs @@ -84,7 +84,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return args; } - var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", 5.ToString(UsCulture)); args += keyFrameArg; @@ -192,4 +192,4 @@ namespace MediaBrowser.MediaEncoding.Encoder get { return true; } } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 5e428e6f01..fc3a507d17 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { var maxBitrate = 25000000; videoArgs = string.Format( - "-codec:v:0 libx264 -force_key_frames expr:gte(t,n_forced*5) {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41", + "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41", GetOutputSizeParam(), maxBitrate.ToString(CultureInfo.InvariantCulture)); } @@ -354,4 +354,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } } -} +} \ No newline at end of file From 2eeae1c5500e01b319da4075ac62d0d2def022ad Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 16:17:46 -0400 Subject: [PATCH 101/220] 3.1.95 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 9596e1d73d..f10a805344 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.94")] +[assembly: AssemblyVersion("3.1.95")] From 55630d54cc897031ba743824e0c42b481dfe4833 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 17:17:40 -0400 Subject: [PATCH 102/220] restore version --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index f10a805344..7ffbc0f475 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.95")] +[assembly: AssemblyVersion("3.0.6030")] From 2481838b4a855d48bf0a7f1267893bbccf51c497 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 17:57:46 -0400 Subject: [PATCH 103/220] fix people refresh progress display --- .../Library/Validators/PeopleValidator.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index aa993d1768..191c7ef282 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -115,6 +115,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators _logger.Debug("Will refresh {0} people", dict.Count); + var numPeople = dict.Count; + foreach (var person in dict) { cancellationToken.ThrowIfCancellationRequested(); @@ -124,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var item = _libraryManager.GetPerson(person.Key); var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 90; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 60; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh @@ -155,7 +157,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators // Update progress numComplete++; double percent = numComplete; - percent /= people.Count; + percent /= numPeople; progress.Report(100 * percent); } From 90858d44d078174760a9ba2548d82c03a024301d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 18:34:28 -0400 Subject: [PATCH 104/220] 3.0.6040 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 7ffbc0f475..255be1dff7 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6030")] +[assembly: AssemblyVersion("3.0.6040")] From 1d14c98ec8fbbccfd53a9fda726c241feb0c35b3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Aug 2016 20:01:50 -0400 Subject: [PATCH 105/220] 3.0.6050 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 255be1dff7..9b3db66689 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6040")] +[assembly: AssemblyVersion("3.0.6050")] From 0741d7aa3f07b02e623ac91b5f22fd8b81e7002b Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 8 Aug 2016 00:26:52 -0400 Subject: [PATCH 106/220] update mac project --- .../Emby.Server.Mac.csproj | 117 ------------------ 1 file changed, 117 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index dc19921b67..349cc94452 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -3183,36 +3183,6 @@ Resources\dashboard-ui\bower_components\paper-checkbox\test\index.html - - Resources\dashboard-ui\bower_components\paper-fab\.bower.json - - - Resources\dashboard-ui\bower_components\paper-fab\.gitignore - - - Resources\dashboard-ui\bower_components\paper-fab\README.md - - - Resources\dashboard-ui\bower_components\paper-fab\bower.json - - - Resources\dashboard-ui\bower_components\paper-fab\index.html - - - Resources\dashboard-ui\bower_components\paper-fab\paper-fab.html - - - Resources\dashboard-ui\bower_components\paper-fab\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-fab\test\a11y.html - - - Resources\dashboard-ui\bower_components\paper-fab\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-fab\test\index.html - Resources\dashboard-ui\bower_components\paper-icon-button\.bower.json @@ -3339,93 +3309,6 @@ Resources\dashboard-ui\bower_components\paper-input\test\paper-textarea.html - - Resources\dashboard-ui\bower_components\paper-item\.bower.json - - - Resources\dashboard-ui\bower_components\paper-item\.gitignore - - - Resources\dashboard-ui\bower_components\paper-item\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-item\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-item\README.md - - - Resources\dashboard-ui\bower_components\paper-item\all-imports.html - - - Resources\dashboard-ui\bower_components\paper-item\bower.json - - - Resources\dashboard-ui\bower_components\paper-item\index.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-icon-item.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-behavior.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-body.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item-shared-styles.html - - - Resources\dashboard-ui\bower_components\paper-item\paper-item.html - - - Resources\dashboard-ui\bower_components\paper-item\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-item\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-item\test\index.html - - - Resources\dashboard-ui\bower_components\paper-item\test\paper-item.html - - - Resources\dashboard-ui\bower_components\paper-material\.bower.json - - - Resources\dashboard-ui\bower_components\paper-material\.gitignore - - - Resources\dashboard-ui\bower_components\paper-material\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-material\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-material\README.md - - - Resources\dashboard-ui\bower_components\paper-material\bower.json - - - Resources\dashboard-ui\bower_components\paper-material\index.html - - - Resources\dashboard-ui\bower_components\paper-material\paper-material-shared-styles.html - - - Resources\dashboard-ui\bower_components\paper-material\paper-material.html - - - Resources\dashboard-ui\bower_components\paper-material\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-material\test\index.html - - - Resources\dashboard-ui\bower_components\paper-material\test\paper-material.html - Resources\dashboard-ui\bower_components\paper-progress\.bower.json From ce26f24ec7e7a1828e1bfa4c5d6377a37da433b9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 8 Aug 2016 00:35:21 -0400 Subject: [PATCH 107/220] remove X-Powered-By header --- .../HttpServer/HttpListenerHost.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 5cf0a246fe..90055d8ec1 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -81,6 +81,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer {typeof (ApplicationException), 500} }; + HostConfig.Instance.GlobalResponseHeaders = new Dictionary(); HostConfig.Instance.DebugMode = false; HostConfig.Instance.LogFactory = LogManager.LogFactory; From d71a468388335d407ef73e933bddb59c4f2b4d1d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 8 Aug 2016 14:14:05 -0400 Subject: [PATCH 108/220] fix played filter for series --- MediaBrowser.Controller/Entities/Folder.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index bb3d4f73df..c1728ce389 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -13,6 +13,7 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Channels; namespace MediaBrowser.Controller.Entities @@ -882,6 +883,15 @@ namespace MediaBrowser.Controller.Entities return true; } + if (query.IsPlayed.HasValue) + { + if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(typeof(Series).Name)) + { + Logger.Debug("Query requires post-filtering due to IsPlayed"); + return true; + } + } + return false; } From e652b996b6d4ea46d897fa670309e15bbbef158b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 8 Aug 2016 14:18:32 -0400 Subject: [PATCH 109/220] 3.1.96 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index f10a805344..6d6ac0ab63 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.95")] +[assembly: AssemblyVersion("3.1.96")] From b309e06cb8741b7b697a57e230bd9f6ee452e8d9 Mon Sep 17 00:00:00 2001 From: softworkz Date: Mon, 8 Aug 2016 20:49:31 +0200 Subject: [PATCH 110/220] FileRefresher.IsFileLocked: Don't log Exceptions in case of no write permission --- MediaBrowser.Server.Implementations/IO/FileRefresher.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index f48beacb57..5c72ac9c7e 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -254,6 +254,11 @@ namespace MediaBrowser.Server.Implementations.IO // File may have been deleted return false; } + catch (UnauthorizedAccessException) + { + Logger.Debug("No write permission for: {0}.", path); + return false; + } catch (IOException) { //the file is unavailable because it is: From bb0618f6083bb7dc8f5f7de7a65e2b8aa50f629b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 8 Aug 2016 18:15:37 -0400 Subject: [PATCH 111/220] fixes #2041 - Error when altering and saving user settings --- .../Serialization/XmlSerializer.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs index 756741e0da..77f65b0c7a 100644 --- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.Xml; using CommonIO; @@ -24,13 +25,22 @@ namespace MediaBrowser.Common.Implementations.Serialization // Need to cache these // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html - private readonly ConcurrentDictionary _serializers = - new ConcurrentDictionary(); + private readonly Dictionary _serializers = + new Dictionary(); private System.Xml.Serialization.XmlSerializer GetSerializer(Type type) { var key = type.FullName; - return _serializers.GetOrAdd(key, k => new System.Xml.Serialization.XmlSerializer(type)); + lock (_serializers) + { + System.Xml.Serialization.XmlSerializer serializer; + if (!_serializers.TryGetValue(key, out serializer)) + { + serializer = new System.Xml.Serialization.XmlSerializer(type); + _serializers[key] = serializer; + } + return serializer; + } } /// From cbb6a9495db893211bced8f9c8ca845f91f2bc02 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 01:08:21 -0400 Subject: [PATCH 112/220] exclude people from dynamic images --- .../UserViews/DynamicImageProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index ea4da19b20..3c75c8a487 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.UserViews User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, CollapseBoxSetItems = false, Recursive = recursive, - ExcludeItemTypes = new[] { "UserView", "CollectionFolder" } + ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Person" }, }).ConfigureAwait(false); From 112d5d63481f2002a08d5532072cee84df01116b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 01:08:36 -0400 Subject: [PATCH 113/220] try to detect 3d type --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 6 ++++++ MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index f37e223ded..9e9bc0780e 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -168,6 +168,12 @@ namespace MediaBrowser.MediaEncoding.Probing } ExtractTimestamp(info); + + var stereoMode = GetDictionaryValue(tags, "stereo_mode"); + if (string.Equals(stereoMode, "left_right", StringComparison.OrdinalIgnoreCase)) + { + info.Video3DFormat = Video3DFormat.FullSideBySide; + } } return info; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index e1ab61cbbe..c208235356 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -231,6 +231,8 @@ namespace MediaBrowser.Providers.MediaInfo video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle); video.Timestamp = mediaInfo.Timestamp; + video.Video3DFormat = video.Video3DFormat ?? mediaInfo.Video3DFormat; + await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false); if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || From e52759786ff626d930ff3aa7375546d8efb5b975 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 01:10:17 -0400 Subject: [PATCH 114/220] fix layout quirks --- MediaBrowser.Api/ApiEntryPoint.cs | 11 ++- .../BaseProgressiveStreamingService.cs | 68 +++++++++---------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 1a7f4a2b12..bb9d2b8645 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -63,6 +63,15 @@ namespace MediaBrowser.Api Instance = this; _sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress; + _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; + } + + private void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) + { + if (!string.IsNullOrWhiteSpace(e.PlaySessionId)) + { + PingTranscodingJob(e.PlaySessionId, e.IsPaused); + } } void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e) @@ -401,7 +410,7 @@ namespace MediaBrowser.Api } } - Logger.Debug("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId); + Logger.Info("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId); KillTranscodingJob(job, true, path => true); } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 4649499c46..d6dea0fe52 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -165,40 +165,40 @@ namespace MediaBrowser.Api.Playback.Progressive } } - // Not static but transcode cache file exists - if (isTranscodeCached) - { - var contentType = state.GetMimeType(outputPath); - - try - { - if (transcodingJob != null) - { - ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob); - } - - return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions - { - ResponseHeaders = responseHeaders, - ContentType = contentType, - IsHeadRequest = isHeadRequest, - Path = outputPath, - FileShare = FileShare.ReadWrite, - OnComplete = () => - { - if (transcodingJob != null) - { - ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob); - } - } - - }).ConfigureAwait(false); - } - finally - { - state.Dispose(); - } - } + //// Not static but transcode cache file exists + //if (isTranscodeCached && state.VideoRequest == null) + //{ + // var contentType = state.GetMimeType(outputPath); + + // try + // { + // if (transcodingJob != null) + // { + // ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob); + // } + + // return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + // { + // ResponseHeaders = responseHeaders, + // ContentType = contentType, + // IsHeadRequest = isHeadRequest, + // Path = outputPath, + // FileShare = FileShare.ReadWrite, + // OnComplete = () => + // { + // if (transcodingJob != null) + // { + // ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob); + // } + // } + + // }).ConfigureAwait(false); + // } + // finally + // { + // state.Dispose(); + // } + //} // Need to start ffmpeg try From bfdd9e8936557fbeb9147f81c18b2b967cd7fb4a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 01:13:23 -0400 Subject: [PATCH 115/220] 3.1.97 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 6d6ac0ab63..6dfb8bc40e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.96")] +[assembly: AssemblyVersion("3.1.97")] From 94a4f11464700c0fb73b58b2515730224441d641 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 13:31:31 -0400 Subject: [PATCH 116/220] update components --- MediaBrowser.Model/ApiClient/IApiClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 904beb7365..2e9f570876 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -302,6 +302,8 @@ namespace MediaBrowser.Model.ApiClient /// Task{ItemsResult}. Task GetSeasonsAsync(SeasonQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task GetRegistrationInfo(); + /// /// Queries for items /// From 9935397d12020c5a52afe9f8f390b5581bef5d03 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 14:23:12 -0400 Subject: [PATCH 117/220] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 9b3db66689..6dfb8bc40e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6050")] +[assembly: AssemblyVersion("3.1.97")] From 2ce8b8207765a5fb60e089ece9af2e32fc9d3311 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 9 Aug 2016 14:24:11 -0400 Subject: [PATCH 118/220] 3.0.6060 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 6dfb8bc40e..a81b44de7a 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.1.97")] +[assembly: AssemblyVersion("3.0.6060")] From ac8c4ccc3ce53a4eafbd0493e9fe333d95b28730 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 9 Aug 2016 16:40:07 -0400 Subject: [PATCH 119/220] update mac project --- MediaBrowser.Server.Mac/Emby.Server.Mac.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 349cc94452..236b0879f9 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -1179,6 +1179,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\peoplecardbuilder.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\cardbuilder\roundcard.css + Resources\dashboard-ui\bower_components\emby-webcomponents\collectioneditor\collectioneditor.js From 9349cc5bebf1196bfc9f90e3838e89acb95d41d4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 10 Aug 2016 15:15:41 -0400 Subject: [PATCH 120/220] update thread count on image extraction --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 08ab99f9b2..c8a28e832a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -874,8 +874,8 @@ namespace MediaBrowser.MediaEncoding.Encoder var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case. - var args = useIFrame ? string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg) : - string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg); + var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg) : + string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg); var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol); @@ -980,7 +980,7 @@ namespace MediaBrowser.MediaEncoding.Encoder FileSystem.CreateDirectory(targetDirectory); var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); - var args = string.Format("-i {0} -threads 1 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); + var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); var probeSize = GetProbeSizeArgument(new[] { inputArgument }, protocol); From 438507b53d554f110cc092e98cc9659766b9224b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 10 Aug 2016 15:15:57 -0400 Subject: [PATCH 121/220] don't throttle when using hardware encoding --- .../Playback/BaseStreamingService.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 164d607d28..59dfd87ecd 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1118,22 +1118,23 @@ namespace MediaBrowser.Api.Playback private void StartThrottler(StreamState state, TranscodingJob transcodingJob) { - if (EnableThrottling(state) && state.InputProtocol == MediaProtocol.File && - state.RunTimeTicks.HasValue && - state.VideoType == VideoType.VideoFile && - !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + if (EnableThrottling(state) && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { - if (state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && state.IsInputVideo) - { - transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager); - state.TranscodingThrottler.Start(); - } + transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager); + state.TranscodingThrottler.Start(); } } protected virtual bool EnableThrottling(StreamState state) { - return true; + // do not use throttling with hardware encoders + return state.InputProtocol == MediaProtocol.File && + state.RunTimeTicks.HasValue && + state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && + state.IsInputVideo && + state.VideoType == VideoType.VideoFile && + !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && + string.Equals(GetVideoEncoder(state), "libx264", StringComparison.OrdinalIgnoreCase); } private async Task StartStreamingLog(TranscodingJob transcodingJob, StreamState state, Stream source, Stream target) From 00307b9a44e6940a7c8c547cf0ffa6232f805cca Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 10 Aug 2016 15:16:09 -0400 Subject: [PATCH 122/220] updated inherited parental rating value --- .../Persistence/SqliteItemRepository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index b4f8245ed8..0836560fc2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2230,7 +2230,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } if (string.Equals(name, ItemSortBy.OfficialRating, StringComparison.OrdinalIgnoreCase)) { - return new Tuple("ParentalRatingValue", false); + return new Tuple("InheritedParentalRatingValue", false); } if (string.Equals(name, ItemSortBy.Studio, StringComparison.OrdinalIgnoreCase)) { @@ -3473,7 +3473,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; + cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(InheritedParentalRatingValue, (select COALESCE(MAX(InheritedParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { From 6f20a8ca059f4266082e41b0fd58eae5d0229940 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 10 Aug 2016 23:56:01 -0400 Subject: [PATCH 123/220] don't restart timer if disposed --- MediaBrowser.Server.Implementations/IO/FileRefresher.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index f48beacb57..742585143f 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -61,6 +61,11 @@ namespace MediaBrowser.Server.Implementations.IO public void RestartTimer() { + if (_disposed) + { + return; + } + lock (_timerLock) { if (_timer == null) @@ -281,8 +286,10 @@ namespace MediaBrowser.Server.Implementations.IO } } + private bool _disposed; public void Dispose() { + _disposed = true; DisposeTimer(); } } From de0f97159b72ed43b59316ad108781759b623ec9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 10 Aug 2016 23:56:14 -0400 Subject: [PATCH 124/220] check item path for null/empty --- MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 11280cff21..e36be54191 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -171,10 +171,13 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (!string.IsNullOrWhiteSpace(item.Path)) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } if (item.SupportsLocalMetadata) From cb0d6cc8c780fb4ac41f4ce7b87ee82112f65cc8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Aug 2016 01:38:17 -0400 Subject: [PATCH 125/220] moved icons --- .../MediaBrowser.WebDashboard.csproj | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index cc064dc813..2917ec2ced 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -233,10 +233,7 @@ PreserveNewest - - PreserveNewest - - + PreserveNewest @@ -1196,13 +1193,13 @@ - + PreserveNewest - + PreserveNewest - + PreserveNewest From 72f9a4e4780a9b242822cd21494c0372e7a31295 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Aug 2016 01:38:40 -0400 Subject: [PATCH 126/220] update app manifest --- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index b7b1f1dfd7..4913faab35 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -372,12 +372,12 @@ namespace MediaBrowser.WebDashboard.Api sb.Append(""); // http://developer.apple.com/library/ios/#DOCUMENTATION/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html - sb.Append(""); - sb.Append(""); - sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append(""); sb.Append(""); sb.Append(""); - sb.Append(""); + sb.Append(""); sb.Append(""); sb.Append(""); From c929fb187e5927ee46359a41f8ecf146ba293d57 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Aug 2016 01:38:53 -0400 Subject: [PATCH 127/220] add endpoint to get file list --- .../Api/DashboardService.cs | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 34ad32111b..ce6369ec5e 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -58,6 +58,11 @@ namespace MediaBrowser.WebDashboard.Api { } + [Route("/web/cachefiles", "GET")] + public class GetCacheFiles + { + } + /// /// Class GetDashboardResource /// @@ -140,6 +145,22 @@ namespace MediaBrowser.WebDashboard.Api return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false)); } + public object Get(GetCacheFiles request) + { + var creator = GetPackageCreator(); + var directory = creator.DashboardUIPath; + + var skipExtensions = GetUndeployedExtensions(); + + var allFiles = + Directory.GetFiles(directory, "*", SearchOption.AllDirectories) + .Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + .Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString()) + .ToList(); + + return ResultFactory.GetOptimizedResult(Request, _jsonSerializer.SerializeToString(allFiles)); + } + /// /// Gets the specified request. /// @@ -274,6 +295,21 @@ namespace MediaBrowser.WebDashboard.Api return new PackageCreator(_fileSystem, _localization, Logger, _serverConfigurationManager, _jsonSerializer); } + private List GetUndeployedExtensions() + { + var list = new List(); + + list.Add(".log"); + list.Add(".txt"); + list.Add(".map"); + list.Add(".md"); + list.Add(".gz"); + list.Add(".bat"); + list.Add(".sh"); + + return list; + } + public async Task Get(GetDashboardPackage request) { var path = Path.Combine(_serverConfigurationManager.ApplicationPaths.ProgramDataPath, @@ -313,14 +349,9 @@ namespace MediaBrowser.WebDashboard.Api //bowerPath = versionedBowerPath; } - DeleteFilesByExtension(bowerPath, ".log"); - DeleteFilesByExtension(bowerPath, ".txt"); - DeleteFilesByExtension(bowerPath, ".map"); - DeleteFilesByExtension(bowerPath, ".md"); + GetUndeployedExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i)); + DeleteFilesByExtension(bowerPath, ".json", "strings\\"); - DeleteFilesByExtension(bowerPath, ".gz"); - DeleteFilesByExtension(bowerPath, ".bat"); - DeleteFilesByExtension(bowerPath, ".sh"); DeleteFilesByName(bowerPath, "copying", true); DeleteFilesByName(bowerPath, "license", true); DeleteFilesByName(bowerPath, "license-mit", true); @@ -359,13 +390,11 @@ namespace MediaBrowser.WebDashboard.Api //DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "meteor"); //DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "st"); //DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src"); - + if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { // Delete things that are unneeded in an attempt to keep the output as trim as possible _fileSystem.DeleteDirectory(Path.Combine(path, "css", "images", "tour"), true); - - _fileSystem.DeleteFile(Path.Combine(path, "thirdparty", "jquerymobile-1.4.5", "jquery.mobile-1.4.5.min.map")); } else { From 071f455d58514636d5eb0630b44a16903ac738cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Aug 2016 16:28:49 -0400 Subject: [PATCH 128/220] update card layouts --- .../Api/DashboardService.cs | 20 ++++++++++--------- .../Api/PackageCreator.cs | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index ce6369ec5e..4e4a980605 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.WebDashboard.Api { } - [Route("/web/cachefiles", "GET")] + [Route("/web/staticfiles", "GET")] public class GetCacheFiles { } @@ -146,19 +146,24 @@ namespace MediaBrowser.WebDashboard.Api } public object Get(GetCacheFiles request) + { + var allFiles = GetCacheFileList(); + + return ResultFactory.GetOptimizedResult(Request, _jsonSerializer.SerializeToString(allFiles)); + } + + private List GetCacheFileList() { var creator = GetPackageCreator(); var directory = creator.DashboardUIPath; var skipExtensions = GetUndeployedExtensions(); - var allFiles = + return Directory.GetFiles(directory, "*", SearchOption.AllDirectories) .Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase)) .Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString()) .ToList(); - - return ResultFactory.GetOptimizedResult(Request, _jsonSerializer.SerializeToString(allFiles)); } /// @@ -332,12 +337,9 @@ namespace MediaBrowser.WebDashboard.Api var appVersion = _appHost.ApplicationVersion.ToString(); - var mode = request.Mode; + File.WriteAllText(Path.Combine(path, "staticfiles"), _jsonSerializer.SerializeToString(GetCacheFileList())); - if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) - { - _fileSystem.DeleteFile(Path.Combine(path, "scripts", "registrationservices.js")); - } + var mode = request.Mode; // Try to trim the output size a bit var bowerPath = Path.Combine(path, "bower_components"); diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 4913faab35..c5af1cee7b 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -431,7 +431,7 @@ namespace MediaBrowser.WebDashboard.Api var files = new List(); - files.Add("bower_components/requirejs/require.js"); + files.Add("bower_components/requirejs/require.js" + versionString); files.Add("scripts/site.js" + versionString); From b399ce8dbc8def3c99ab7489af2856db49e4b088 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Aug 2016 18:41:25 -0400 Subject: [PATCH 129/220] rework series timer page --- MediaBrowser.Dlna/DlnaManager.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 931cc208f5..a01d73451e 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -73,8 +73,13 @@ namespace MediaBrowser.Dlna lock (_profiles) { var list = _profiles.Values.ToList(); - return list.Select(i => i.Item2).OrderBy(i => i.Name); + return list + .OrderBy(i => i.Item1.Info.Type == DeviceProfileType.User ? 0 : 1) + .ThenBy(i => i.Item1.Info.Name) + .Select(i => i.Item2) + .ToList(); } + } public DeviceProfile GetDefaultProfile() From 75513170751d0213fc0e6c9121c383f83c14ed06 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 12 Aug 2016 11:54:37 -0400 Subject: [PATCH 130/220] update sync menus --- .../Library/Validators/PeopleValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 191c7ef282..d90b9615ba 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var item = _libraryManager.GetPerson(person.Key); var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 60; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh From d9ee4f81fdd161af7bd27f5dba420341e266262d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 12 Aug 2016 15:11:45 -0400 Subject: [PATCH 131/220] rework storage of PresentationUniqueKey --- .../Entities/Audio/MusicArtist.cs | 8 ++--- .../Entities/Audio/MusicGenre.cs | 8 ++--- MediaBrowser.Controller/Entities/BaseItem.cs | 11 +++++-- MediaBrowser.Controller/Entities/GameGenre.cs | 7 ++-- MediaBrowser.Controller/Entities/Genre.cs | 8 ++--- MediaBrowser.Controller/Entities/Person.cs | 8 ++--- MediaBrowser.Controller/Entities/Studio.cs | 8 ++--- MediaBrowser.Controller/Entities/TV/Season.cs | 18 ++++------ MediaBrowser.Controller/Entities/TV/Series.cs | 33 ++++++++++++------- .../Entities/UserViewBuilder.cs | 2 +- MediaBrowser.Controller/Entities/Video.cs | 14 +++----- .../Persistence/SqliteItemRepository.cs | 11 +++++-- .../TV/TVSeriesManager.cs | 2 +- 13 files changed, 66 insertions(+), 72 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 6790a1bcf1..56f9a5b888 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -169,13 +169,9 @@ namespace MediaBrowser.Controller.Entities.Audio list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics()); return list; } - - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return "Artist-" + (Name ?? string.Empty).RemoveDiacritics(); - } + return "Artist-" + (Name ?? string.Empty).RemoveDiacritics(); } protected override bool GetBlockUnratedValue(UserPolicy config) { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 798bc79fbb..9aa5625fac 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -18,13 +18,9 @@ namespace MediaBrowser.Controller.Entities.Audio list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); return list; } - - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return GetUserDataKeys()[0]; - } + return GetUserDataKeys()[0]; } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 8d00f38beb..1d623c3acc 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1194,10 +1194,17 @@ namespace MediaBrowser.Controller.Entities get { return null; } } + public virtual string CreatePresentationUniqueKey() + { + return Id.ToString("N"); + } + [IgnoreDataMember] - public virtual string PresentationUniqueKey + public string PresentationUniqueKey { get; set; } + + public string GetPresentationUniqueKey() { - get { return Id.ToString("N"); } + return PresentationUniqueKey ?? CreatePresentationUniqueKey(); } public virtual bool RequiresRefresh() diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 45e766c0f0..5d66bf3abc 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -16,12 +16,9 @@ namespace MediaBrowser.Controller.Entities return list; } - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return GetUserDataKeys()[0]; - } + return GetUserDataKeys()[0]; } /// diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index cc5aebb2a4..c7fe25a962 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -19,13 +19,9 @@ namespace MediaBrowser.Controller.Entities list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); return list; } - - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return GetUserDataKeys()[0]; - } + return GetUserDataKeys()[0]; } /// diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 8ef0d70bf9..4ee140b2b1 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -26,13 +26,9 @@ namespace MediaBrowser.Controller.Entities list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); return list; } - - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return GetUserDataKeys()[0]; - } + return GetUserDataKeys()[0]; } public PersonLookupInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 762798b553..7e3d6fe8e1 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -18,13 +18,9 @@ namespace MediaBrowser.Controller.Entities list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); return list; } - - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - return GetUserDataKeys()[0]; - } + return GetUserDataKeys()[0]; } /// diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index f6ca19005b..c64de399f2 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -114,22 +114,18 @@ namespace MediaBrowser.Controller.Entities.TV } } - [IgnoreDataMember] - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get + if (IndexNumber.HasValue) { - if (IndexNumber.HasValue) + var series = Series; + if (series != null) { - var series = Series; - if (series != null) - { - return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000"); - } + return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000"); } - - return base.PresentationUniqueKey; } + + return base.CreatePresentationUniqueKey(); } /// diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index ad35b3d369..3297c2c6a6 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -96,19 +96,30 @@ namespace MediaBrowser.Controller.Entities.TV } } - [IgnoreDataMember] - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get - { - var userdatakeys = GetUserDataKeys(); + var userdatakeys = GetUserDataKeys(); - if (userdatakeys.Count > 1) - { - return userdatakeys[0]; - } - return base.PresentationUniqueKey; + if (userdatakeys.Count > 1) + { + return AddLibrariesToPresentationUniqueKey(userdatakeys[0]); } + return base.CreatePresentationUniqueKey(); + } + + private string AddLibrariesToPresentationUniqueKey(string key) + { + return key; + //var folders = LibraryManager.GetCollectionFolders(this) + // .Select(i => i.Id.ToString("N")) + // .ToArray(); + + //if (folders.Length == 0) + //{ + // return key; + //} + + //return key + "-" + string.Join("-", folders); } private static string GetUniqueSeriesKey(BaseItem series) @@ -117,7 +128,7 @@ namespace MediaBrowser.Controller.Entities.TV { return series.Id.ToString("N"); } - return series.PresentationUniqueKey; + return series.GetPresentationUniqueKey(); } public override int GetChildCount(User user) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 11ed269317..d0f7efa8c8 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1198,7 +1198,7 @@ namespace MediaBrowser.Controller.Entities { var user = query.User; - items = items.DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase); + items = items.DistinctBy(i => i.GetPresentationUniqueKey(), StringComparer.OrdinalIgnoreCase); if (query.SortBy.Length > 0) { diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index eba1e466a2..7110b76cc6 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -44,18 +44,14 @@ namespace MediaBrowser.Controller.Entities } } - [IgnoreDataMember] - public override string PresentationUniqueKey + public override string CreatePresentationUniqueKey() { - get + if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) { - if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) - { - return PrimaryVersionId; - } - - return base.PresentationUniqueKey; + return PrimaryVersionId; } + + return base.CreatePresentationUniqueKey(); } [IgnoreDataMember] diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 0836560fc2..c01261d738 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -412,7 +412,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "SeasonName", "SeasonId", "SeriesId", - "SeriesSortName" + "SeriesSortName", + "PresentationUniqueKey" }; private readonly string[] _mediaStreamSaveColumns = @@ -918,7 +919,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = GetCleanValue(item.Name); } - _saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey; + _saveItemCommand.GetParameter(index++).Value = item.GetPresentationUniqueKey(); _saveItemCommand.GetParameter(index++).Value = item.SlugName; _saveItemCommand.GetParameter(index++).Value = item.OriginalTitle; @@ -1454,6 +1455,12 @@ namespace MediaBrowser.Server.Implementations.Persistence } index++; + if (!reader.IsDBNull(index)) + { + item.PresentationUniqueKey = reader.GetString(index); + } + index++; + return item; } diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index ddc1de9cdb..03e8a9178e 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.TV { return series.Id.ToString("N"); } - return series.PresentationUniqueKey; + return series.GetPresentationUniqueKey(); } /// From e0e6c98e43047caa3869dd8bf69204c9ee8f4d7e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 12 Aug 2016 15:30:04 -0400 Subject: [PATCH 132/220] limit series pooling to common libraries --- .../Entities/IHasMetadata.cs | 8 ++++++- MediaBrowser.Controller/Entities/TV/Series.cs | 17 +++++++-------- .../Manager/MetadataService.cs | 7 +++++++ .../TV/SeasonMetadataService.cs | 21 ++++++------------- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 378c4a390b..c7a3c7778e 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Entities /// /// The date last refreshed. DateTime DateLastRefreshed { get; set; } - + /// /// This is called before any metadata refresh and returns true or false indicating if changes were made /// @@ -53,5 +53,11 @@ namespace MediaBrowser.Controller.Entities bool RequiresRefresh(); bool EnableForceSaveOnDateModifiedChange { get; } + + string PresentationUniqueKey { get; set; } + + string GetPresentationUniqueKey(); + string CreatePresentationUniqueKey(); + } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 3297c2c6a6..f01eddcebb 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -109,17 +109,16 @@ namespace MediaBrowser.Controller.Entities.TV private string AddLibrariesToPresentationUniqueKey(string key) { - return key; - //var folders = LibraryManager.GetCollectionFolders(this) - // .Select(i => i.Id.ToString("N")) - // .ToArray(); + var folders = LibraryManager.GetCollectionFolders(this) + .Select(i => i.Id.ToString("N")) + .ToArray(); - //if (folders.Length == 0) - //{ - // return key; - //} + if (folders.Length == 0) + { + return key; + } - //return key + "-" + string.Join("-", folders); + return key + "-" + string.Join("-", folders); } private static string GetUniqueSeriesKey(BaseItem series) diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index ac942d1a76..0a70a2cc43 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -284,6 +284,13 @@ namespace MediaBrowser.Providers.Manager updateType |= SaveCumulativeRunTimeTicks(item, isFullRefresh, currentUpdateType); updateType |= SaveDateLastMediaAdded(item, isFullRefresh, currentUpdateType); + var presentationUniqueKey = item.CreatePresentationUniqueKey(); + if (!string.Equals(item.PresentationUniqueKey, presentationUniqueKey, StringComparison.Ordinal)) + { + item.PresentationUniqueKey = presentationUniqueKey; + updateType |= ItemUpdateType.MetadataImport; + } + return updateType; } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index addab3918e..cf04a14184 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -35,26 +35,17 @@ namespace MediaBrowser.Providers.TV updateType |= SaveIsVirtualItem(item, episodes); } - if (updateType <= ItemUpdateType.None) + if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal)) { - if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal)) - { - updateType |= ItemUpdateType.MetadataImport; - } + updateType |= ItemUpdateType.MetadataImport; } - if (updateType <= ItemUpdateType.None) + if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal)) { - if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal)) - { - updateType |= ItemUpdateType.MetadataImport; - } + updateType |= ItemUpdateType.MetadataImport; } - if (updateType <= ItemUpdateType.None) + if (item.SeriesId != item.FindSeriesId()) { - if (item.SeriesId != item.FindSeriesId()) - { - updateType |= ItemUpdateType.MetadataImport; - } + updateType |= ItemUpdateType.MetadataImport; } return updateType; From 93346830eb28c430477c6cdf6285bcbbea1f2f2a Mon Sep 17 00:00:00 2001 From: Softworkz Date: Sat, 13 Aug 2016 04:24:21 +0200 Subject: [PATCH 133/220] Fix incorrect calculation of content length --- .../Playback/Progressive/BaseProgressiveStreamingService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index d6dea0fe52..f4cc9f4bc6 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -383,7 +383,7 @@ namespace MediaBrowser.Api.Playback.Progressive if (totalBitrate > 0 && state.RunTimeTicks.HasValue) { - return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds); + return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds / 8); } return null; From 319dcda4beb5cde9cd858a33a9603f0cff54d831 Mon Sep 17 00:00:00 2001 From: Softworkz Date: Sat, 13 Aug 2016 06:57:21 +0200 Subject: [PATCH 134/220] Fix: ETag-Values MUST be quoted according to W3C spec --- .../HttpServer/HttpResultFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index c0a2a5eb35..194904320c 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -275,7 +275,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// System.Object. private object GetCachedResult(IRequest requestContext, IDictionary responseHeaders, Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType) { - responseHeaders["ETag"] = cacheKeyString; + responseHeaders["ETag"] = string.Format("\"{0}\"", cacheKeyString); if (IsNotModified(requestContext, cacheKey, lastDateModified, cacheDuration)) { From 68d1b609647d0a592afc7d994fad2dedcb135f6b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 13 Aug 2016 01:49:00 -0400 Subject: [PATCH 135/220] stub out objects for per library settings --- .../Library/LibraryStructureService.cs | 7 +- .../Playback/BaseStreamingService.cs | 6 +- .../Configuration/LibraryOptions.cs | 14 ++++ .../Entities/Audio/Audio.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 6 +- MediaBrowser.Controller/Entities/Book.cs | 2 +- .../Entities/CollectionFolder.cs | 60 ++++++++++++++ MediaBrowser.Controller/Entities/Folder.cs | 4 +- MediaBrowser.Controller/Entities/Game.cs | 2 +- .../Entities/IHasMetadata.cs | 2 +- .../Entities/Movies/BoxSet.cs | 13 ++++ MediaBrowser.Controller/Entities/Photo.cs | 2 +- MediaBrowser.Controller/Entities/Video.cs | 7 +- .../Library/ILibraryManager.cs | 18 +++-- .../Library/ItemResolveArgs.cs | 8 ++ .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Controller/Playlists/Playlist.cs | 6 ++ .../Configuration/ServerConfiguration.cs | 2 - .../Manager/MetadataService.cs | 2 +- .../MediaInfo/FFProbeProvider.cs | 2 +- .../MediaInfo/VideoImageProvider.cs | 9 ++- .../Library/LibraryManager.cs | 78 ++++++++++++++----- .../Library/Resolvers/Audio/AudioResolver.cs | 6 +- .../Resolvers/Audio/MusicAlbumResolver.cs | 30 +++---- .../Resolvers/Audio/MusicArtistResolver.cs | 2 +- .../Library/Resolvers/BaseVideoResolver.cs | 2 +- .../Library/Resolvers/PhotoResolver.cs | 7 +- .../Library/Resolvers/TV/SeriesResolver.cs | 6 +- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 2 +- .../Playlists/ManualPlaylistsFolder.cs | 2 +- .../ApplicationHost.cs | 1 + 32 files changed, 234 insertions(+), 79 deletions(-) create mode 100644 MediaBrowser.Controller/Configuration/LibraryOptions.cs diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 3cf0d5d937..3af2134937 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Api.Library { @@ -52,6 +53,8 @@ namespace MediaBrowser.Api.Library /// /// The path. public string[] Paths { get; set; } + + public LibraryOptions LibraryOptions { get; set; } } [Route("/Library/VirtualFolders", "DELETE")] @@ -190,7 +193,9 @@ namespace MediaBrowser.Api.Library /// The request. public void Post(AddVirtualFolder request) { - _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, request.RefreshLibrary); + var libraryOptions = request.LibraryOptions ?? new LibraryOptions(); + + _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, libraryOptions, request.RefreshLibrary); } /// diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 59dfd87ecd..a9489cecce 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1055,14 +1055,14 @@ namespace MediaBrowser.Api.Playback var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments; Logger.Info(commandLineLogMessage); - var logFilePrefix = "transcode"; + var logFilePrefix = "ffmpeg-transcode"; if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) { - logFilePrefix = "directstream"; + logFilePrefix = "ffmpeg-directstream"; } else if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { - logFilePrefix = "remux"; + logFilePrefix = "ffmpeg-remux"; } var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt"); diff --git a/MediaBrowser.Controller/Configuration/LibraryOptions.cs b/MediaBrowser.Controller/Configuration/LibraryOptions.cs new file mode 100644 index 0000000000..1a824c08bf --- /dev/null +++ b/MediaBrowser.Controller/Configuration/LibraryOptions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Configuration +{ + public class LibraryOptions + { + public bool EnableAudioArchiveFiles { get; set; } + public bool EnableVideoArchiveFiles { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 1897511af7..6326bbd4f4 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1d623c3acc..cc3646cdcb 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -455,7 +455,7 @@ namespace MediaBrowser.Controller.Entities public DateTime DateLastRefreshed { get; set; } [IgnoreDataMember] - public virtual bool EnableForceSaveOnDateModifiedChange + public virtual bool EnableRefreshOnDateModifiedChange { get { return false; } } @@ -951,7 +951,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase)) ); - return LibraryManager.ResolvePaths(files, directoryService, null) + return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions()) .OfType() .Select(audio => { @@ -981,7 +981,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => directoryService.GetFiles(i.FullName)); - return LibraryManager.ResolvePaths(files, directoryService, null) + return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions()) .OfType public class CollectionFolder : Folder, ICollectionFolder { + public static IXmlSerializer XmlSerializer { get; set; } + public CollectionFolder() { PhysicalLocationsList = new List(); @@ -39,6 +44,61 @@ namespace MediaBrowser.Controller.Entities public string CollectionType { get; set; } + private readonly Dictionary _libraryOptions = new Dictionary(); + public LibraryOptions GetLibraryOptions() + { + lock (_libraryOptions) + { + LibraryOptions options; + if (!_libraryOptions.TryGetValue(Path, out options)) + { + options = LoadLibraryOptions(); + _libraryOptions[Path] = options; + } + + return options; + } + } + + private LibraryOptions LoadLibraryOptions() + { + try + { + var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(Path)) as LibraryOptions; + + if (result == null) + { + return new LibraryOptions(); + } + + return result; + } + catch (FileNotFoundException) + { + return new LibraryOptions(); + } + catch (DirectoryNotFoundException) + { + return new LibraryOptions(); + } + catch (Exception ex) + { + Logger.ErrorException("Error loading library options", ex); + + return new LibraryOptions(); + } + } + + private static string GetLibraryOptionsPath(string path) + { + return System.IO.Path.Combine(path, "options.xml"); + } + + public static void SaveLibraryOptions(string path, LibraryOptions options) + { + XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); + } + /// /// Allow different display preferences for each collection folder /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index c1728ce389..bf04c643ce 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -273,6 +273,7 @@ namespace MediaBrowser.Controller.Entities /// protected virtual IEnumerable LoadChildren() { + //Logger.Debug("Loading children from {0} {1}", Id, Path); //just load our children from the repo - the library will be validated and maintained in other processes return GetCachedChildren(); } @@ -643,8 +644,9 @@ namespace MediaBrowser.Controller.Entities protected virtual IEnumerable GetNonCachedChildren(IDirectoryService directoryService) { var collectionType = LibraryManager.GetContentType(this); + var libraryOptions = LibraryManager.GetLibraryOptions(this); - return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType); + return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, libraryOptions, collectionType); } /// diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 54386a1795..24910498f5 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index c7a3c7778e..d5891c6552 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities bool RequiresRefresh(); - bool EnableForceSaveOnDateModifiedChange { get; } + bool EnableRefreshOnDateModifiedChange { get; } string PresentationUniqueKey { get; set; } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 4effc162e4..ba50a1e0de 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -62,6 +62,19 @@ namespace MediaBrowser.Controller.Entities.Movies return UnratedItem.Movie; } + protected override IEnumerable LoadChildren() + { + var first = LinkedChildren.FirstOrDefault(); + + if (first != null && first.Type == LinkedChildType.Shortcut) + { + return base.LoadChildren(); + } + + // Save a trip to the database + return new List(); + } + [IgnoreDataMember] public override bool IsPreSorted { diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 804ea04a59..965616eb53 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 7110b76cc6..830747d3c9 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -55,9 +55,12 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { - get { return true; } + get + { + return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso; + } } public int? TotalBitrate { get; set; } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index ff7f2fe678..edbacb5e70 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Dto; namespace MediaBrowser.Controller.Library @@ -32,15 +33,11 @@ namespace MediaBrowser.Controller.Library /// /// Resolves a set of files into a list of BaseItem /// - /// The files. - /// The directory service. - /// The parent. - /// Type of the collection. - /// List{``0}. IEnumerable ResolvePaths(IEnumerable files, IDirectoryService directoryService, - Folder parent, string - collectionType = null); + Folder parent, + LibraryOptions libraryOptions, + string collectionType = null); /// /// Gets the root folder. @@ -397,6 +394,9 @@ namespace MediaBrowser.Controller.Library /// true if [is audio file] [the specified path]; otherwise, false. bool IsAudioFile(string path); + bool IsAudioFile(string path, LibraryOptions libraryOptions); + bool IsVideoFile(string path, LibraryOptions libraryOptions); + /// /// Gets the season number from path. /// @@ -453,6 +453,8 @@ namespace MediaBrowser.Controller.Library /// IEnumerable<Folder>. IEnumerable GetCollectionFolders(BaseItem item); + LibraryOptions GetLibraryOptions(BaseItem item); + /// /// Gets the people. /// @@ -551,7 +553,7 @@ namespace MediaBrowser.Controller.Library /// true if XXXX, false otherwise. bool IgnoreFile(FileSystemMetadata file, BaseItem parent); - void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, bool refreshLibrary); + void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary); void RemoveVirtualFolder(string name, bool refreshLibrary); void AddMediaPath(string virtualFolderName, string path); void RemoveMediaPath(string virtualFolderName, string path); diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index ea3199b318..56ec0a2138 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Controller.Library { @@ -51,6 +52,13 @@ namespace MediaBrowser.Controller.Library } } + public LibraryOptions LibraryOptions { get; set; } + + public LibraryOptions GetLibraryOptions() + { + return LibraryOptions ?? (LibraryOptions = (Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent))); + } + /// /// Gets or sets the file system dictionary. /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 0462117cb5..e621eafded 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -98,6 +98,7 @@ + diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 5ffe3d5daf..3e706f1fa7 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -58,6 +58,12 @@ namespace MediaBrowser.Controller.Playlists return true; } + protected override IEnumerable LoadChildren() + { + // Save a trip to the database + return new List(); + } + public override IEnumerable GetChildren(User user, bool includeLinkedChildren) { return GetPlayableItems(user).Result; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 58b74ba64a..303ba1acf7 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -180,8 +180,6 @@ namespace MediaBrowser.Model.Configuration public NameValuePair[] ContentTypes { get; set; } - public bool EnableAudioArchiveFiles { get; set; } - public bool EnableVideoArchiveFiles { get; set; } public int RemoteClientBitrateLimit { get; set; } public AutoOnOff EnableLibraryMonitor { get; set; } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 0a70a2cc43..0483a74ed1 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -149,7 +149,7 @@ namespace MediaBrowser.Providers.Manager if (file != null) { var fileLastWriteTime = file.LastWriteTimeUtc; - if (item.EnableForceSaveOnDateModifiedChange && fileLastWriteTime != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && fileLastWriteTime != item.DateModified) { Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, fileLastWriteTime, item.Id); requiresRefresh = true; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index e36be54191..0df8b6c4b7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (!string.IsNullOrWhiteSpace(item.Path)) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path)) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index fb08f00c19..280e92beb9 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -194,10 +194,13 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 055fde504b..b00303f295 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -556,7 +556,12 @@ namespace MediaBrowser.Server.Implementations.Library return ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), null, parent); } - private BaseItem ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, IItemResolver[] resolvers, Folder parent = null, string collectionType = null) + private BaseItem ResolvePath(FileSystemMetadata fileInfo, + IDirectoryService directoryService, + IItemResolver[] resolvers, + Folder parent = null, + string collectionType = null, + LibraryOptions libraryOptions = null) { if (fileInfo == null) { @@ -575,7 +580,8 @@ namespace MediaBrowser.Server.Implementations.Library Parent = parent, Path = fullPath, FileInfo = fileInfo, - CollectionType = collectionType + CollectionType = collectionType, + LibraryOptions = libraryOptions }; // Return null if ignore rules deem that we should do so @@ -653,12 +659,17 @@ namespace MediaBrowser.Server.Implementations.Library return !args.ContainsFileSystemEntryByName(".ignore"); } - public IEnumerable ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent, string collectionType) + public IEnumerable ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType) { - return ResolvePaths(files, directoryService, parent, collectionType, EntityResolvers); + return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers); } - public IEnumerable ResolvePaths(IEnumerable files, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers) + public IEnumerable ResolvePaths(IEnumerable files, + IDirectoryService directoryService, + Folder parent, + LibraryOptions libraryOptions, + string collectionType, + IItemResolver[] resolvers) { var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList(); @@ -679,22 +690,27 @@ namespace MediaBrowser.Server.Implementations.Library { ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService); } - items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers)); + items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers, libraryOptions)); return items; } } } - return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers); + return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers, libraryOptions); } - private IEnumerable ResolveFileList(IEnumerable fileList, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers) + private IEnumerable ResolveFileList(IEnumerable fileList, + IDirectoryService directoryService, + Folder parent, + string collectionType, + IItemResolver[] resolvers, + LibraryOptions libraryOptions) { return fileList.Select(f => { try { - return ResolvePath(f, directoryService, resolvers, parent, collectionType); + return ResolvePath(f, directoryService, resolvers, parent, collectionType, libraryOptions); } catch (Exception ex) { @@ -1891,6 +1907,15 @@ namespace MediaBrowser.Server.Implementations.Library .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase)); } + public LibraryOptions GetLibraryOptions(BaseItem item) + { + var collectionFolder = GetCollectionFolders(item) + .OfType() + .FirstOrDefault(); + + return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions(); + } + public string GetContentType(BaseItem item) { string configuredContentType = GetConfiguredContentType(item, false); @@ -2242,18 +2267,28 @@ namespace MediaBrowser.Server.Implementations.Library return item; } - public bool IsVideoFile(string path) + public bool IsVideoFile(string path, LibraryOptions libraryOptions) { - var resolver = new VideoResolver(GetNamingOptions(), new PatternsLogger()); + var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new PatternsLogger()); return resolver.IsVideoFile(path); } - public bool IsAudioFile(string path) + public bool IsVideoFile(string path) + { + return IsVideoFile(path, new LibraryOptions()); + } + + public bool IsAudioFile(string path, LibraryOptions libraryOptions) { - var parser = new AudioFileParser(GetNamingOptions()); + var parser = new AudioFileParser(GetNamingOptions(libraryOptions)); return parser.IsAudioFile(path); } + public bool IsAudioFile(string path) + { + return IsAudioFile(path, new LibraryOptions()); + } + public int? GetSeasonNumberFromPath(string path) { return new SeasonPathParser(GetNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber; @@ -2379,6 +2414,11 @@ namespace MediaBrowser.Server.Implementations.Library } public NamingOptions GetNamingOptions() + { + return GetNamingOptions(new LibraryOptions()); + } + + public NamingOptions GetNamingOptions(LibraryOptions libraryOptions) { var options = new ExtendedNamingOptions(); @@ -2386,13 +2426,13 @@ namespace MediaBrowser.Server.Implementations.Library options.AudioFileExtensions.Remove(".m3u"); options.AudioFileExtensions.Remove(".wpl"); - if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles) + if (!libraryOptions.EnableAudioArchiveFiles) { options.AudioFileExtensions.Remove(".rar"); options.AudioFileExtensions.Remove(".zip"); } - if (!ConfigurationManager.Configuration.EnableVideoArchiveFiles) + if (!libraryOptions.EnableVideoArchiveFiles) { options.VideoFileExtensions.Remove(".rar"); options.VideoFileExtensions.Remove(".zip"); @@ -2443,7 +2483,7 @@ namespace MediaBrowser.Server.Implementations.Library new GenericVideoResolver(this) }; - return ResolvePaths(files, directoryService, null, null, resolvers) + return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers) .OfType() .Select(video => { @@ -2487,7 +2527,7 @@ namespace MediaBrowser.Server.Implementations.Library files.AddRange(currentVideo.Extras.Where(i => !string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path))); } - return ResolvePaths(files, directoryService, null, null) + return ResolvePaths(files, directoryService, null, new LibraryOptions(), null) .OfType /// The game count. public int GameCount { get; set; } + public int ArtistCount { get; set; } /// /// Gets or sets the game system count. /// diff --git a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs index 1161ab005f..d8ec04ff64 100644 --- a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs +++ b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Model.Entities { @@ -25,6 +26,8 @@ namespace MediaBrowser.Model.Entities /// The type of the collection. public string CollectionType { get; set; } + public LibraryOptions LibraryOptions { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index e3c1e52a53..db70b86063 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -95,6 +95,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index cc165da6a7..4f903a2c28 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -408,12 +408,19 @@ namespace MediaBrowser.Server.Implementations.Dto private void SetItemByNameInfo(BaseItem item, BaseItemDto dto, List taggedItems, User user = null) { - if (item is MusicArtist || item is MusicGenre) + if (item is MusicArtist) { dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo); dto.SongCount = taggedItems.Count(i => i is Audio); } + else if (item is MusicGenre) + { + dto.ArtistCount = taggedItems.Count(i => i is MusicArtist); + dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); + dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo); + dto.SongCount = taggedItems.Count(i => i is Audio); + } else if (item is GameGenre) { dto.GameCount = taggedItems.Count(i => i is Game); @@ -422,6 +429,7 @@ namespace MediaBrowser.Server.Implementations.Dto { // This populates them all and covers Genre, Person, Studio, Year + dto.ArtistCount = taggedItems.Count(i => i is MusicArtist); dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); dto.EpisodeCount = taggedItems.Count(i => i is Episode); dto.GameCount = taggedItems.Count(i => i is Game); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index b00303f295..52961668d0 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1223,7 +1223,7 @@ namespace MediaBrowser.Server.Implementations.Library .Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders)); } - private VirtualFolderInfo GetVirtualFolderInfo(string dir, List collectionFolders) + private VirtualFolderInfo GetVirtualFolderInfo(string dir, List allCollectionFolders) { var info = new VirtualFolderInfo { @@ -1237,7 +1237,7 @@ namespace MediaBrowser.Server.Implementations.Library CollectionType = GetCollectionType(dir) }; - var libraryFolder = collectionFolders.FirstOrDefault(i => string.Equals(i.Path, dir, StringComparison.OrdinalIgnoreCase)); + var libraryFolder = allCollectionFolders.FirstOrDefault(i => string.Equals(i.Path, dir, StringComparison.OrdinalIgnoreCase)); if (libraryFolder != null && libraryFolder.HasImage(ImageType.Primary)) { @@ -1249,6 +1249,12 @@ namespace MediaBrowser.Server.Implementations.Library info.ItemId = libraryFolder.Id.ToString("N"); } + var collectionFolder = libraryFolder as CollectionFolder; + if (collectionFolder != null) + { + info.LibraryOptions = collectionFolder.GetLibraryOptions(); + } + return info; } @@ -2426,13 +2432,13 @@ namespace MediaBrowser.Server.Implementations.Library options.AudioFileExtensions.Remove(".m3u"); options.AudioFileExtensions.Remove(".wpl"); - if (!libraryOptions.EnableAudioArchiveFiles) + if (!libraryOptions.EnableArchiveMediaFiles) { options.AudioFileExtensions.Remove(".rar"); options.AudioFileExtensions.Remove(".zip"); } - if (!libraryOptions.EnableVideoArchiveFiles) + if (!libraryOptions.EnableArchiveMediaFiles) { options.VideoFileExtensions.Remove(".rar"); options.VideoFileExtensions.Remove(".zip"); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 546f64d3c3..1a8295800f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.IO; using CommonIO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 09a9a3b4e9..78df465b13 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using CommonIO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index f1bbc1f327..aefb29f1a6 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -13,6 +13,7 @@ using System.IO; using System.Linq; using CommonIO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 4c9b2a4d97..3d8e7a3d6d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -28,6 +28,7 @@ using CommonIO; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.Configuration; using Microsoft.Win32; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index bbb36b46e1..0e36ede7ac 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3975,7 +3975,8 @@ namespace MediaBrowser.Server.Implementations.Persistence AlbumArtistStartsWithOrGreater = query.AlbumArtistStartsWithOrGreater, Tags = query.Tags, OfficialRatings = query.OfficialRatings, - Genres = query.GenreIds, + GenreIds = query.GenreIds, + Genres = query.Genres, Years = query.Years }; @@ -4128,6 +4129,10 @@ namespace MediaBrowser.Server.Implementations.Persistence { counts.AlbumCount = value; } + else if (string.Equals(typeName, typeof(MusicArtist).FullName, StringComparison.OrdinalIgnoreCase)) + { + counts.ArtistCount = value; + } else if (string.Equals(typeName, typeof(Audio).FullName, StringComparison.OrdinalIgnoreCase)) { counts.SongCount = value; From 6e9828ddadd6a86e8422d863afecc8a2fb4a88a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 13 Aug 2016 18:27:14 -0400 Subject: [PATCH 140/220] add remuxing permission --- MediaBrowser.Api/Playback/MediaInfoService.cs | 14 ++++++++++++++ MediaBrowser.Model/Dlna/ResolutionNormalizer.cs | 5 +++-- MediaBrowser.Model/Users/UserPolicy.cs | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 0b989784c0..91e62b4e32 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -284,6 +284,13 @@ namespace MediaBrowser.Api.Playback options.ForceDirectPlay = true; } } + else if (item is Video) + { + if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) + { + options.ForceDirectPlay = true; + } + } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? @@ -315,6 +322,13 @@ namespace MediaBrowser.Api.Playback options.ForceDirectStream = true; } } + else if (item is Video) + { + if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) + { + options.ForceDirectStream = true; + } + } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs index ed18fed655..fb353b016b 100644 --- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs +++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Model.Dlna { @@ -59,8 +60,8 @@ namespace MediaBrowser.Model.Dlna private static double GetVideoBitrateScaleFactor(string codec) { - if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) || - string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(codec, "h265") || + StringHelper.EqualsIgnoreCase(codec, "hevc")) { return .5; } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 16b4b673d9..3917b1662d 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -41,6 +41,7 @@ namespace MediaBrowser.Model.Users public bool EnableMediaPlayback { get; set; } public bool EnableAudioPlaybackTranscoding { get; set; } public bool EnableVideoPlaybackTranscoding { get; set; } + public bool EnablePlaybackRemuxing { get; set; } public bool EnableContentDeletion { get; set; } public bool EnableContentDownloading { get; set; } @@ -76,6 +77,7 @@ namespace MediaBrowser.Model.Users EnableMediaPlayback = true; EnableAudioPlaybackTranscoding = true; EnableVideoPlaybackTranscoding = true; + EnablePlaybackRemuxing = true; EnableLiveTvManagement = true; EnableLiveTvAccess = true; From 7dbeeadea6edff204276bf87c03c85886d0ff321 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 13 Aug 2016 20:52:32 -0400 Subject: [PATCH 141/220] fix lastmodified header --- .../HttpServer/HttpResultFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index 194904320c..27065d0f5c 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -534,7 +534,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (lastDateModified.HasValue && (string.IsNullOrEmpty(cacheKey) || cacheDuration.HasValue)) { AddAgeHeader(responseHeaders, lastDateModified); - responseHeaders["LastModified"] = lastDateModified.Value.ToString("r"); + responseHeaders["Last-Modified"] = lastDateModified.Value.ToString("r"); } if (cacheDuration.HasValue) From 89dd4f0be1721ef8f8357051cafea2703ab38b2e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 13 Aug 2016 23:12:26 -0400 Subject: [PATCH 142/220] save library options on dialog close --- .../Library/LibraryStructureService.cs | 24 +++++++++++++++---- .../Entities/CollectionFolder.cs | 12 +++++++++- .../Entities/Movies/BoxSet.cs | 3 +-- .../Collections/CollectionsDynamicFolder.cs | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index dd3c7211a4..72966a7cdc 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Api.Library @@ -140,6 +141,14 @@ namespace MediaBrowser.Api.Library public bool RefreshLibrary { get; set; } } + [Route("/Library/VirtualFolders/LibraryOptions", "POST")] + public class UpdateLibraryOptions : IReturnVoid + { + public string Id { get; set; } + + public LibraryOptions LibraryOptions { get; set; } + } + /// /// Class LibraryStructureService /// @@ -188,6 +197,13 @@ namespace MediaBrowser.Api.Library return ToOptimizedSerializedResultUsingCache(result); } + public void Post(UpdateLibraryOptions request) + { + var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(request.Id); + + collectionFolder.UpdateLibraryOptions(request.LibraryOptions); + } + /// /// Posts the specified request. /// @@ -220,12 +236,12 @@ namespace MediaBrowser.Api.Library var currentPath = Path.Combine(rootFolderPath, request.Name); var newPath = Path.Combine(rootFolderPath, request.NewName); - if (!_fileSystem.DirectoryExists(currentPath)) + if (!_fileSystem.DirectoryExists(currentPath)) { throw new DirectoryNotFoundException("The media collection does not exist"); } - if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && _fileSystem.DirectoryExists(newPath)) + if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && _fileSystem.DirectoryExists(newPath)) { throw new ArgumentException("There is already a media collection with the name " + newPath + "."); } @@ -240,11 +256,11 @@ namespace MediaBrowser.Api.Library //Create an unique name var temporaryName = Guid.NewGuid().ToString(); var temporaryPath = Path.Combine(rootFolderPath, temporaryName); - _fileSystem.MoveDirectory(currentPath, temporaryPath); + _fileSystem.MoveDirectory(currentPath, temporaryPath); currentPath = temporaryPath; } - _fileSystem.MoveDirectory(currentPath, newPath); + _fileSystem.MoveDirectory(currentPath, newPath); } finally { diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index b81f021da9..e120f2e23d 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -95,9 +95,19 @@ namespace MediaBrowser.Controller.Entities return System.IO.Path.Combine(path, "options.xml"); } + public void UpdateLibraryOptions(LibraryOptions options) + { + SaveLibraryOptions(Path, options); + } + public static void SaveLibraryOptions(string path, LibraryOptions options) { - XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); + lock (LibraryOptions) + { + LibraryOptions[path] = options; + + XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); + } } /// diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 742ade2009..caf440a83f 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -110,8 +110,7 @@ namespace MediaBrowser.Controller.Entities.Movies { get { - // TODO - return false; + return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path); } } diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs b/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs index cb95bfd147..6cd9e96205 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Server.Implementations.Collections public class CollectionsDynamicFolder : IVirtualFolderCreator { private readonly IApplicationPaths _appPaths; - private IFileSystem _fileSystem; + private readonly IFileSystem _fileSystem; public CollectionsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem) { From fb779d89d22bfe0c2930d277d817956e956db30c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 14 Aug 2016 02:41:53 -0400 Subject: [PATCH 143/220] update translations --- .../MediaBrowser.WebDashboard.csproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index f1b234b903..9b51fd489c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -116,6 +116,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -1557,6 +1563,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 325a3cc844e338dfac2dd136aa49c05ad9517388 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 14 Aug 2016 12:39:23 -0400 Subject: [PATCH 144/220] cache ids in UserRootFolder --- .../Entities/UserRootFolder.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index a62c67c4fe..d043cba47f 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -18,20 +18,20 @@ namespace MediaBrowser.Controller.Entities { private List _childrenIds = null; private readonly object _childIdsLock = new object(); - //protected override IEnumerable LoadChildren() - //{ - // lock (_childIdsLock) - // { - // if (_childrenIds == null) - // { - // var list = base.LoadChildren().ToList(); - // _childrenIds = list.Select(i => i.Id).ToList(); - // return list; - // } - - // return _childrenIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); - // } - //} + protected override IEnumerable LoadChildren() + { + lock (_childIdsLock) + { + if (_childrenIds == null) + { + var list = base.LoadChildren().ToList(); + _childrenIds = list.Select(i => i.Id).ToList(); + return list; + } + + return _childrenIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); + } + } private void ResetCachedChildren() { From 1adcfaadef7436a4ec6252927bffd477415d7145 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 14 Aug 2016 17:29:35 -0400 Subject: [PATCH 145/220] refresh people on demand, when needed --- .../UserLibrary/UserLibraryService.cs | 39 ++++++++++++++++++- MediaBrowser.Controller/Entities/BaseItem.cs | 9 +++++ .../Entities/IHasMetadata.cs | 2 +- .../Entities/Movies/Movie.cs | 10 +++++ MediaBrowser.Controller/Entities/TV/Series.cs | 10 +++++ MediaBrowser.Controller/Entities/Trailer.cs | 10 +++++ .../Manager/MetadataService.cs | 2 +- 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 3be11bdc56..eba17e7763 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -12,6 +12,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using CommonIO; +using MediaBrowser.Controller.Providers; namespace MediaBrowser.Api.UserLibrary { @@ -262,14 +264,16 @@ namespace MediaBrowser.Api.UserLibrary private readonly ILibraryManager _libraryManager; private readonly IDtoService _dtoService; private readonly IUserViewManager _userViewManager; + private readonly IFileSystem _fileSystem; - public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, IUserViewManager userViewManager) + public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, IUserViewManager userViewManager, IFileSystem fileSystem) { _userManager = userManager; _libraryManager = libraryManager; _userDataRepository = userDataRepository; _dtoService = dtoService; _userViewManager = userViewManager; + _fileSystem = fileSystem; } /// @@ -426,12 +430,14 @@ namespace MediaBrowser.Api.UserLibrary /// /// The request. /// System.Object. - public object Get(GetItem request) + public async Task Get(GetItem request) { var user = _userManager.GetUserById(request.UserId); var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id); + await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false); + var dtoOptions = GetDtoOptions(request); var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); @@ -439,6 +445,35 @@ namespace MediaBrowser.Api.UserLibrary return ToOptimizedSerializedResultUsingCache(result); } + private async Task RefreshItemOnDemandIfNeeded(BaseItem item) + { + if (item is Person) + { + var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview) && item.HasImage(ImageType.Primary); + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 7; + + if (!hasMetdata) + { + var defaultMetadataRefreshMode = performFullRefresh + ? MetadataRefreshMode.FullRefresh + : MetadataRefreshMode.Default; + + var imageRefreshMode = performFullRefresh + ? ImageRefreshMode.FullRefresh + : ImageRefreshMode.Default; + + var options = new MetadataRefreshOptions(_fileSystem) + { + MetadataRefreshMode = defaultMetadataRefreshMode, + ImageRefreshMode = imageRefreshMode, + ForceSave = performFullRefresh + }; + + await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); + } + } + } + /// /// Gets the specified request. /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cc3646cdcb..cbbb9a89a3 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2213,6 +2213,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public virtual bool StopRefreshIfLocalMetadataFound + { + get + { + return true; + } + } + public virtual IEnumerable GetIdsForAncestorQuery() { return new[] { Id }; diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index d5891c6552..26f425ff0b 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -58,6 +58,6 @@ namespace MediaBrowser.Controller.Entities string GetPresentationUniqueKey(); string CreatePresentationUniqueKey(); - + bool StopRefreshIfLocalMetadataFound { get; } } } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index c7a833c58f..f0270497c0 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -179,5 +179,15 @@ namespace MediaBrowser.Controller.Entities.Movies return list; } + + [IgnoreDataMember] + public override bool StopRefreshIfLocalMetadataFound + { + get + { + // Need people id's from internet metadata + return false; + } + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index f01eddcebb..757c052bb4 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -519,5 +519,15 @@ namespace MediaBrowser.Controller.Entities.TV return list; } + + [IgnoreDataMember] + public override bool StopRefreshIfLocalMetadataFound + { + get + { + // Need people id's from internet metadata + return false; + } + } } } diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 6604be977d..306ce35ece 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -124,5 +124,15 @@ namespace MediaBrowser.Controller.Entities return list; } + + [IgnoreDataMember] + public override bool StopRefreshIfLocalMetadataFound + { + get + { + // Need people id's from internet metadata + return false; + } + } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 0483a74ed1..04437cff79 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -532,7 +532,7 @@ namespace MediaBrowser.Providers.Manager } // Local metadata is king - if any is found don't run remote providers - if (!options.ReplaceAllMetadata && (!hasLocalMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh)) + if (!options.ReplaceAllMetadata && (!hasLocalMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || !item.StopRefreshIfLocalMetadataFound)) { var remoteResult = await ExecuteRemoteProviders(temp, logName, id, providers.OfType>(), cancellationToken) .ConfigureAwait(false); From 51411fff8278b5c05e0fe46057a83f83585e6528 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 14 Aug 2016 17:45:36 -0400 Subject: [PATCH 146/220] add on demand people refresh --- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index eba17e7763..bbccef6dea 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -450,22 +450,14 @@ namespace MediaBrowser.Api.UserLibrary if (item is Person) { var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview) && item.HasImage(ImageType.Primary); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 7; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 3; if (!hasMetdata) { - var defaultMetadataRefreshMode = performFullRefresh - ? MetadataRefreshMode.FullRefresh - : MetadataRefreshMode.Default; - - var imageRefreshMode = performFullRefresh - ? ImageRefreshMode.FullRefresh - : ImageRefreshMode.Default; - var options = new MetadataRefreshOptions(_fileSystem) { - MetadataRefreshMode = defaultMetadataRefreshMode, - ImageRefreshMode = imageRefreshMode, + MetadataRefreshMode = MetadataRefreshMode.FullRefresh, + ImageRefreshMode = ImageRefreshMode.FullRefresh, ForceSave = performFullRefresh }; From caab8299d1c8ebb7db7de1c83fc7a26070309a6e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 Aug 2016 00:36:17 -0400 Subject: [PATCH 147/220] add setting for photo libraries --- MediaBrowser.Model/Configuration/LibraryOptions.cs | 6 ++++++ .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/PhotoResolver.cs | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index c6f7bbb9da..e15df37c1a 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -3,5 +3,11 @@ public class LibraryOptions { public bool EnableArchiveMediaFiles { get; set; } + public bool EnablePhotos { get; set; } + + public LibraryOptions() + { + EnablePhotos = true; + } } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 52961668d0..a19f70e68c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -364,7 +364,7 @@ namespace MediaBrowser.Server.Implementations.Library if (item.IsFolder) { - if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel)) + if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder)) { if (item.SourceType != SourceType.Library) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 78df465b13..3f9475480a 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -34,8 +34,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers // Must be an image file within a photo collection var collectionType = args.GetCollectionType(); + if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase) || - string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase)) + (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) && args.GetLibraryOptions().EnablePhotos)) { if (IsImageFile(args.Path, _imageProcessor)) { From 8bd8282a115bc9f679e28d814bce451b29c7721e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 Aug 2016 14:18:05 -0400 Subject: [PATCH 148/220] update docked tabs --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 9b51fd489c..b9d647c367 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -101,6 +101,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest From 6186e3a4ff6614552e008d93add8fdcd744ae018 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 Aug 2016 17:02:43 -0400 Subject: [PATCH 149/220] reduce dlna chatter --- MediaBrowser.Dlna/PlayTo/Device.cs | 39 ++++++++++++++++++++ MediaBrowser.Dlna/PlayTo/PlayToController.cs | 24 ++++++++---- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 1ec7a4ce09..6ad5899da1 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Net; using System.Security; using System.Threading; using System.Threading.Tasks; @@ -91,6 +92,7 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IServerConfigurationManager _config; public DateTime DateLastActivity { get; private set; } + public Action OnDeviceUnavailable { get; set; } public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config) { @@ -134,6 +136,9 @@ namespace MediaBrowser.Dlna.PlayTo private async void RefreshVolume() { + if (_disposed) + return; + try { await GetVolume().ConfigureAwait(false); @@ -149,6 +154,9 @@ namespace MediaBrowser.Dlna.PlayTo private bool _timerActive; private void RestartTimer() { + if (_disposed) + return; + if (!_timerActive) { lock (_timerLock) @@ -169,6 +177,9 @@ namespace MediaBrowser.Dlna.PlayTo /// private void RestartTimerInactive() { + if (_disposed) + return; + if (_timerActive) { lock (_timerLock) @@ -398,6 +409,7 @@ namespace MediaBrowser.Dlna.PlayTo #region Get data private int _successiveStopCount; + private int _connectFailureCount; private async void TimerCallback(object sender) { if (_disposed) @@ -435,6 +447,8 @@ namespace MediaBrowser.Dlna.PlayTo } } + _connectFailureCount = 0; + if (_disposed) return; @@ -455,8 +469,33 @@ namespace MediaBrowser.Dlna.PlayTo } } } + catch (WebException ex) + { + if (_disposed) + return; + + _logger.ErrorException("Error updating device info for {0}", ex, Properties.Name); + + _successiveStopCount++; + _connectFailureCount++; + + if (_successiveStopCount >= maxSuccessiveStopReturns) + { + RestartTimerInactive(); + } + if (_connectFailureCount >= maxSuccessiveStopReturns) + { + if (OnDeviceUnavailable != null) + { + OnDeviceUnavailable(); + } + } + } catch (Exception ex) { + if (_disposed) + return; + _logger.ErrorException("Error updating device info for {0}", ex, Properties.Name); _successiveStopCount++; diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 873ae5ae41..7429330bd6 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -103,11 +103,25 @@ namespace MediaBrowser.Dlna.PlayTo _device.PlaybackProgress += _device_PlaybackProgress; _device.PlaybackStopped += _device_PlaybackStopped; _device.MediaChanged += _device_MediaChanged; + _device.OnDeviceUnavailable = OnDeviceUnavailable; + _device.Start(); _deviceDiscovery.DeviceLeft += _deviceDiscovery_DeviceLeft; } + private void OnDeviceUnavailable() + { + try + { + _sessionManager.ReportSessionEnded(_session.Id); + } + catch + { + // Could throw if the session is already gone + } + } + void _deviceDiscovery_DeviceLeft(object sender, SsdpMessageEventArgs e) { string nts; @@ -125,14 +139,7 @@ namespace MediaBrowser.Dlna.PlayTo if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1 || nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1) { - try - { - _sessionManager.ReportSessionEnded(_session.Id); - } - catch - { - // Could throw if the session is already gone - } + OnDeviceUnavailable(); } } } @@ -647,6 +654,7 @@ namespace MediaBrowser.Dlna.PlayTo _device.PlaybackStopped -= _device_PlaybackStopped; _device.MediaChanged -= _device_MediaChanged; _deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft; + _device.OnDeviceUnavailable = null; _device.Dispose(); } From ec111eebd3ac70bed57e7645fd562960c7c72030 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 Aug 2016 20:22:59 -0400 Subject: [PATCH 150/220] fix folder caching --- .../Progressive/ProgressiveStreamWriter.cs | 6 ++--- .../Entities/AggregateFolder.cs | 27 ++++++++++--------- .../Entities/UserRootFolder.cs | 15 ++++++++--- MediaBrowser.Model/Dlna/StreamBuilder.cs | 13 ++++++--- .../Persistence/SqliteItemRepository.cs | 2 +- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 8c4e23a397..0a9a446412 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -48,11 +48,11 @@ namespace MediaBrowser.Api.Playback.Progressive { var eofCount = 0; - using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) + using (var fs = _fileSystem.GetFileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) { while (eofCount < 15) { - var bytesRead = await CopyToAsyncInternal(fs, outputStream, BufferSize, cancellationToken).ConfigureAwait(false); + var bytesRead = await CopyToAsyncInternal(fs, outputStream, BufferSize, _cancellationToken).ConfigureAwait(false); //var position = fs.Position; //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path); @@ -63,7 +63,7 @@ namespace MediaBrowser.Api.Playback.Progressive { eofCount++; } - await Task.Delay(100, cancellationToken).ConfigureAwait(false); + await Task.Delay(100, _cancellationToken).ConfigureAwait(false); } else { diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 4aa99ae87b..b1e5a2135c 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -5,6 +5,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using System.Threading; +using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Providers; @@ -84,7 +86,7 @@ namespace MediaBrowser.Controller.Entities } } - private void ResetCachedChildren() + private void ClearCache() { lock (_childIdsLock) { @@ -114,7 +116,7 @@ namespace MediaBrowser.Controller.Entities public override bool BeforeMetadataRefresh() { - ResetCachedChildren(); + ClearCache(); var changed = base.BeforeMetadataRefresh() || _requiresRefresh; _requiresRefresh = false; @@ -123,7 +125,7 @@ namespace MediaBrowser.Controller.Entities private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations) { - ResetCachedChildren(); + ClearCache(); var path = ContainingFolderPath; @@ -165,6 +167,16 @@ namespace MediaBrowser.Controller.Entities return args; } + protected override async Task ValidateChildrenInternal(IProgress progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) + { + ClearCache(); + + await base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService) + .ConfigureAwait(false); + + ClearCache(); + } + /// /// Adds the virtual child. /// @@ -180,15 +192,6 @@ namespace MediaBrowser.Controller.Entities _virtualChildren.Add(child); } - /// - /// Get the children of this folder from the actual file system - /// - /// IEnumerable{BaseItem}. - protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) - { - return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren); - } - /// /// Finds the virtual child. /// diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index d043cba47f..bd25d3a6ae 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Entities } } - private void ResetCachedChildren() + private void ClearCache() { lock (_childIdsLock) { @@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Entities public override bool BeforeMetadataRefresh() { - ResetCachedChildren(); + ClearCache(); var hasChanges = base.BeforeMetadataRefresh(); @@ -107,13 +107,22 @@ namespace MediaBrowser.Controller.Entities return hasChanges; } + protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) + { + ClearCache(); + + return base.GetNonCachedChildren(directoryService); + } + protected override async Task ValidateChildrenInternal(IProgress progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { - ResetCachedChildren(); + ClearCache(); await base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService) .ConfigureAwait(false); + ClearCache(); + // Not the best way to handle this, but it solves an issue // CollectionFolders aren't always getting saved after changes // This means that grabbing the item by Id may end up returning the old one diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 80e81a41a4..0710417c85 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -570,7 +570,7 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); + int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); int? maxBitrateSetting = options.GetMaxBitrate(); @@ -593,7 +593,7 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private int GetAudioBitrate(int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) + private int GetAudioBitrate(string subProtocol, int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) { var defaultBitrate = 128000; if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) @@ -611,7 +611,14 @@ namespace MediaBrowser.Model.Dlna { if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) { - defaultBitrate = Math.Max(448000, defaultBitrate); + if (string.Equals(subProtocol, "hls", StringComparison.OrdinalIgnoreCase)) + { + defaultBitrate = Math.Max(384000, defaultBitrate); + } + else + { + defaultBitrate = Math.Max(448000, defaultBitrate); + } } else { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 0e36ede7ac..cf8e2fe36c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2152,7 +2152,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { if (query.User != null) { - query.SortBy = new[] { ItemSortBy.IsPlayed, "SimilarityScore", ItemSortBy.Random }; + query.SortBy = new[] { "SimilarityScore", ItemSortBy.Random }; } else { From ea62399fe8f46797a85ee65f7e6612aedfcaa785 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 Aug 2016 22:40:29 -0400 Subject: [PATCH 151/220] use shared headroom --- MediaBrowser.Controller/Entities/AggregateFolder.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index b1e5a2135c..efc4502481 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -167,6 +167,11 @@ namespace MediaBrowser.Controller.Entities return args; } + protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) + { + return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren); + } + protected override async Task ValidateChildrenInternal(IProgress progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) { ClearCache(); From c1e8d85bca08a6bd08d3234d249b3d72f80c772d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 00:12:12 -0400 Subject: [PATCH 152/220] update local sync --- MediaBrowser.Api/Sync/SyncService.cs | 2 +- SharedVersion.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index a15ce216f2..4f6aced57d 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Api.Sync public string Id { get; set; } } - [Route("/Sync/{TargetId}/Items", "DELETE", Summary = "Cancels items from a sync target")] + [Route("/Sync/Items/Cancel", "POST", Summary = "Cancels items from a sync target")] public class CancelItems : IReturnVoid { [ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "Items")] diff --git a/SharedVersion.cs b/SharedVersion.cs index a81b44de7a..ded2038b03 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.1.*")] -[assembly: AssemblyVersion("3.0.6060")] +[assembly: AssemblyVersion("3.1.*")] +//[assembly: AssemblyVersion("3.0.6060")] From cff77c7359f38001674d0d15a005bfac91f438fb Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 16 Aug 2016 00:15:09 -0400 Subject: [PATCH 153/220] update mac project --- .../Emby.Server.Mac.csproj | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 236b0879f9..9422b7fa36 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -639,6 +639,18 @@ Resources\dashboard-ui\syncsettings.html + + Resources\dashboard-ui\touchicon.png + + + Resources\dashboard-ui\touchicon114.png + + + Resources\dashboard-ui\touchicon144.png + + + Resources\dashboard-ui\touchicon72.png + Resources\dashboard-ui\tv.html @@ -1005,8 +1017,11 @@ Resources\dashboard-ui\bower_components\emby-apiclient\apiclient.js - - Resources\dashboard-ui\bower_components\emby-apiclient\appstorage.js + + Resources\dashboard-ui\bower_components\emby-apiclient\appstorage-localstorage.js + + + Resources\dashboard-ui\bower_components\emby-apiclient\appstorage-memory.js Resources\dashboard-ui\bower_components\emby-apiclient\bower.json @@ -1050,9 +1065,6 @@ Resources\dashboard-ui\bower_components\emby-apiclient\sync\serversync.js - - Resources\dashboard-ui\bower_components\emby-icons\emby-icons.html - Resources\dashboard-ui\bower_components\emby-webcomponents\.bower.json @@ -1251,6 +1263,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\emby-slider\emby-slider.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-tabs\emby-tabs.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-tabs\emby-tabs.js + Resources\dashboard-ui\bower_components\emby-webcomponents\emby-textarea\emby-textarea.css @@ -3603,6 +3621,12 @@ Resources\dashboard-ui\components\viewcontainer-lite.js + + Resources\dashboard-ui\components\appfooter\appfooter.css + + + Resources\dashboard-ui\components\appfooter\appfooter.js + Resources\dashboard-ui\components\channelmapper\channelmapper.js @@ -3612,6 +3636,12 @@ Resources\dashboard-ui\components\directorybrowser\directorybrowser.js + + Resources\dashboard-ui\components\dockedtabs\dockedtabs.css + + + Resources\dashboard-ui\components\dockedtabs\dockedtabs.js + Resources\dashboard-ui\components\fileorganizer\fileorganizer.js @@ -3657,6 +3687,12 @@ Resources\dashboard-ui\components\imageuploader\imageuploader.template.html + + Resources\dashboard-ui\components\libraryoptionseditor\libraryoptionseditor.js + + + Resources\dashboard-ui\components\libraryoptionseditor\libraryoptionseditor.template.html + Resources\dashboard-ui\components\medialibrarycreator\medialibrarycreator.js @@ -3750,9 +3786,6 @@ Resources\dashboard-ui\css\images\logo.png - - Resources\dashboard-ui\css\images\logo536.png - Resources\dashboard-ui\css\images\mblogoicon.png @@ -3762,18 +3795,6 @@ Resources\dashboard-ui\css\images\rotten.png - - Resources\dashboard-ui\css\images\touchicon.png - - - Resources\dashboard-ui\css\images\touchicon114.png - - - Resources\dashboard-ui\css\images\touchicon144.png - - - Resources\dashboard-ui\css\images\touchicon72.png - Resources\dashboard-ui\css\images\userflyoutdefault.png @@ -4434,6 +4455,9 @@ Resources\dashboard-ui\strings\ar.json + + Resources\dashboard-ui\strings\be-BY.json + Resources\dashboard-ui\strings\bg-BG.json From f450ce4e14d722221224b21ec383daf6a44b70c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 01:34:36 -0400 Subject: [PATCH 154/220] update sync --- MediaBrowser.Api/Sync/SyncService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 4f6aced57d..b9544d71ba 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -67,6 +67,7 @@ namespace MediaBrowser.Api.Sync } [Route("/Sync/Items/Cancel", "POST", Summary = "Cancels items from a sync target")] + [Route("/Sync/{TargetId}/Items", "DELETE", Summary = "Cancels items from a sync target")] public class CancelItems : IReturnVoid { [ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "Items")] @@ -211,7 +212,7 @@ namespace MediaBrowser.Api.Sync return ToOptimizedResult(result); } - public void Delete(CancelItems request) + public void Any(CancelItems request) { var itemIds = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); From b55c02f25d2aa7fd2901b42df4789b2c838896d8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 01:36:41 -0400 Subject: [PATCH 155/220] target 4.6.2 --- MediaBrowser.ServerApplication/App.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.ServerApplication/App.config b/MediaBrowser.ServerApplication/App.config index 6d840c1910..fa7bc9f895 100644 --- a/MediaBrowser.ServerApplication/App.config +++ b/MediaBrowser.ServerApplication/App.config @@ -17,7 +17,7 @@ - + diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index b01d8c43f6..9c5470358e 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -9,7 +9,7 @@ Properties MediaBrowser.ServerApplication MediaBrowser.ServerApplication - v4.6 + v4.6.2 512 ..\ From 14be817766fe55cfeeb3184f3e1a999ce5759188 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 01:48:03 -0400 Subject: [PATCH 156/220] update WebMarkupMin --- MediaBrowser.WebDashboard/Api/DashboardService.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 2 -- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 +++--- MediaBrowser.WebDashboard/packages.config | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 4e4a980605..601ebfba73 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -17,7 +17,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using CommonIO; -using WebMarkupMin.Core.Minifiers; +using WebMarkupMin.Core; namespace MediaBrowser.WebDashboard.Api { diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index c5af1cee7b..65e7fa5d39 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -11,8 +11,6 @@ using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Net; using WebMarkupMin.Core; -using WebMarkupMin.Core.Minifiers; -using WebMarkupMin.Core.Settings; namespace MediaBrowser.WebDashboard.Api { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index b9d647c367..50e1cfbbea 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -63,9 +63,9 @@ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll - - False - ..\packages\WebMarkupMin.Core.1.0.1\lib\net40\WebMarkupMin.Core.dll + + ..\packages\WebMarkupMin.Core.2.1.0\lib\net40-client\WebMarkupMin.Core.dll + True diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index a2d13fdf5f..3637c6c84e 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file From 184d4470239fcec3a46b602f44c742d32a7c2ac1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 02:13:54 -0400 Subject: [PATCH 157/220] update series queries --- MediaBrowser.Controller/Entities/TV/Series.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 757c052bb4..38ddb89ca7 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -243,24 +243,30 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired) { - IEnumerable seasons; + var seriesKey = GetUniqueSeriesKey(this); - seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) + Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey); + var seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), + AncestorWithPresentationUniqueKey = seriesKey, IncludeItemTypes = new[] { typeof(Season).Name }, SortBy = new[] { ItemSortBy.SortName } - }).Cast(); + }).Cast().ToList(); + + Logger.Debug("GetSeasons returned {0} items from database", seasons.Count); if (!includeMissingSeasons) { - seasons = seasons.Where(i => !(i.IsMissingSeason)); + seasons = seasons.Where(i => !(i.IsMissingSeason)).ToList(); } + Logger.Debug("GetSeasons has {0} items after includeMissingSeasons filter", seasons.Count); + if (!includeVirtualUnaired) { - seasons = seasons.Where(i => !i.IsVirtualUnaired); + seasons = seasons.Where(i => !i.IsVirtualUnaired).ToList(); } + Logger.Debug("GetSeasons has {0} items after includeVirtualUnaired filter", seasons.Count); return seasons; } From 8a7b24000da7a9e917ea041095b55fc95e98a17c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 13:08:37 -0400 Subject: [PATCH 158/220] update season queries --- MediaBrowser.Api/TvShowsService.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 11 ++++++++- MediaBrowser.Controller/Entities/TV/Season.cs | 8 +++++-- MediaBrowser.Controller/Entities/TV/Series.cs | 24 +++++++++++-------- .../Dto/DtoService.cs | 2 +- .../IO/LibraryMonitor.cs | 14 +++++++++-- 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 3f248ea8f0..92189c2458 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -490,7 +490,7 @@ namespace MediaBrowser.Api } else { - episodes = series.GetEpisodes(user, season); + episodes = series.GetSeasonEpisodes(user, season); } } else diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 23055690ca..f8eb414b60 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -13,6 +13,7 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Channels; @@ -1427,7 +1428,7 @@ namespace MediaBrowser.Controller.Entities itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount; } - double recursiveItemCount = allItemsQueryResult.TotalRecordCount; + var recursiveItemCount = allItemsQueryResult.TotalRecordCount; double unplayedCount = unplayedQueryResult.TotalRecordCount; if (recursiveItemCount > 0) @@ -1437,6 +1438,14 @@ namespace MediaBrowser.Controller.Entities dto.Played = dto.PlayedPercentage.Value >= 100; dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount; } + + if (itemDto != null) + { + if (this is Season || this is MusicAlbum) + { + itemDto.ChildCount = recursiveItemCount; + } + } } } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index c64de399f2..66fe1cc756 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -85,7 +85,11 @@ namespace MediaBrowser.Controller.Entities.TV public override int GetChildCount(User user) { - return GetChildren(user, true).Count(); + Logger.Debug("Season {0} getting child cound", (Path ?? Name)); + var result = GetChildren(user, true).Count(); + Logger.Debug("Season {0} child cound: ", result); + + return result; } /// @@ -192,7 +196,7 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes) { - return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes); + return series.GetSeasonEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes); } public IEnumerable GetEpisodes() diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 38ddb89ca7..02ac42b2af 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -254,19 +254,16 @@ namespace MediaBrowser.Controller.Entities.TV }).Cast().ToList(); - Logger.Debug("GetSeasons returned {0} items from database", seasons.Count); if (!includeMissingSeasons) { seasons = seasons.Where(i => !(i.IsMissingSeason)).ToList(); } - Logger.Debug("GetSeasons has {0} items after includeMissingSeasons filter", seasons.Count); if (!includeVirtualUnaired) { seasons = seasons.Where(i => !i.IsVirtualUnaired).ToList(); } - Logger.Debug("GetSeasons has {0} items after includeVirtualUnaired filter", seasons.Count); return seasons; } @@ -280,14 +277,19 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired) { + var seriesKey = GetUniqueSeriesKey(this); + Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey); + var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), + AncestorWithPresentationUniqueKey = seriesKey, IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }, SortBy = new[] { ItemSortBy.SortName } }).ToList(); + Logger.Debug("GetEpisodes return {0} items from database", allItems.Count); + var allSeriesEpisodes = allItems.OfType().ToList(); var allEpisodes = allItems.OfType() @@ -368,11 +370,11 @@ namespace MediaBrowser.Controller.Entities.TV progress.Report(100); } - public IEnumerable GetEpisodes(User user, Season season) + public IEnumerable GetSeasonEpisodes(User user, Season season) { var config = user.Configuration; - return GetEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); + return GetSeasonEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); } private IEnumerable GetAllEpisodes(User user) @@ -386,20 +388,22 @@ namespace MediaBrowser.Controller.Entities.TV }).Cast(); } - public IEnumerable GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) + public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) { IEnumerable episodes = GetAllEpisodes(user); - return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); + return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); } - public IEnumerable GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes) + public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes) { if (allSeriesEpisodes == null) { - return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes); + Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null"); + return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes); } + Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason"); var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons); if (!includeMissingEpisodes) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 4f903a2c28..b646605ed4 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -458,7 +458,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); - if (item.SourceType == SourceType.Library) + if (!dto.ChildCount.HasValue && item.SourceType == SourceType.Library) { dto.ChildCount = GetChildCount(folder, user); } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 8c2b927e3a..dea0a978bf 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -38,7 +38,6 @@ namespace MediaBrowser.Server.Implementations.IO /// private readonly IReadOnlyList _alwaysIgnoreFiles = new List { - "thumbs.db", "small.jpg", "albumart.jpg", @@ -47,6 +46,15 @@ namespace MediaBrowser.Server.Implementations.IO "TempSBE" }; + private readonly IReadOnlyList _alwaysIgnoreExtensions = new List + { + // thumbs.db + ".db", + + // bts sync files + ".bts" + }; + /// /// Add the path to our temporary ignore list. Use when writing to a path within our listening scope. /// @@ -411,7 +419,9 @@ namespace MediaBrowser.Server.Implementations.IO var filename = Path.GetFileName(path); - var monitorPath = !(!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase)); + var monitorPath = !string.IsNullOrEmpty(filename) && + !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && + !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase); // Ignore certain files var tempIgnorePaths = _tempIgnoredPaths.Keys.ToList(); From 1d37f9ad0e8281a612580c438f0130c5796ff8c4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 14:45:57 -0400 Subject: [PATCH 159/220] fix music brainz album search results --- .../Music/MusicBrainzAlbumProvider.cs | 100 +++++++++--------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index 1710ec2b0f..a0ce806105 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -81,46 +81,24 @@ namespace MediaBrowser.Providers.Music private IEnumerable GetResultsFromResponse(XmlDocument doc) { - var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", MusicBrainzBaseUrl + "/ns/mmd-2.0#"); - - var list = new List(); - - var nodes = doc.SelectNodes("//mb:release-list/mb:release", ns); - - if (nodes != null) + return ReleaseResult.Parse(doc).Select(i => { - foreach (var node in nodes.Cast()) + var result = new RemoteSearchResult { - if (node.Attributes != null) - { - string name = null; - - string mbzId = node.Attributes["id"].Value; - - var nameNode = node.SelectSingleNode("//mb:title", ns); - - if (nameNode != null) - { - name = nameNode.InnerText; - } - - if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name)) - { - var result = new RemoteSearchResult - { - Name = name - }; - - result.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbzId); + Name = i.Title + }; - list.Add(result); - } - } + if (!string.IsNullOrWhiteSpace(i.ReleaseId)) + { + result.SetProviderId(MetadataProviders.MusicBrainzAlbum, i.ReleaseId); + } + if (!string.IsNullOrWhiteSpace(i.ReleaseGroupId)) + { + result.SetProviderId(MetadataProviders.MusicBrainzAlbum, i.ReleaseGroupId); } - } - return list; + return result; + }); } public async Task> GetMetadata(AlbumInfo id, CancellationToken cancellationToken) @@ -208,7 +186,7 @@ namespace MediaBrowser.Providers.Music var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); - return ReleaseResult.Parse(doc); + return ReleaseResult.Parse(doc, 1).FirstOrDefault(); } private async Task GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken) @@ -219,32 +197,32 @@ namespace MediaBrowser.Providers.Music var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); - return ReleaseResult.Parse(doc); + return ReleaseResult.Parse(doc, 1).FirstOrDefault(); } private class ReleaseResult { public string ReleaseId; public string ReleaseGroupId; + public string Title; - public static ReleaseResult Parse(XmlDocument doc) + public static List Parse(XmlDocument doc, int? limit = null) { var docElem = doc.DocumentElement; + var list = new List(); if (docElem == null) { - return new ReleaseResult(); + return list; } var releaseList = docElem.FirstChild; if (releaseList == null) { - return new ReleaseResult(); + return list; } var nodes = releaseList.ChildNodes; - string releaseId = null; - string releaseGroupId = null; if (nodes != null) { @@ -252,18 +230,42 @@ namespace MediaBrowser.Providers.Music { if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase)) { - releaseId = node.Attributes["id"].Value; - releaseGroupId = GetReleaseGroupIdFromReleaseNode(node); - break; + var releaseId = node.Attributes["id"].Value; + var releaseGroupId = GetReleaseGroupIdFromReleaseNode(node); + + list.Add(new ReleaseResult + { + ReleaseId = releaseId, + ReleaseGroupId = releaseGroupId, + Title = GetTitleFromReleaseNode(node) + }); + + if (limit.HasValue && list.Count >= limit.Value) + { + break; + } } } } - return new ReleaseResult + return list; + } + + private static string GetTitleFromReleaseNode(XmlNode node) + { + var subNodes = node.ChildNodes; + if (subNodes != null) { - ReleaseId = releaseId, - ReleaseGroupId = releaseGroupId - }; + foreach (var subNode in subNodes.Cast()) + { + if (string.Equals(subNode.Name, "title", StringComparison.OrdinalIgnoreCase)) + { + return subNode.InnerText; + } + } + } + + return null; } private static string GetReleaseGroupIdFromReleaseNode(XmlNode node) From ae887d9157335db66bf569ab31f274fc24503146 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 14:46:12 -0400 Subject: [PATCH 160/220] remove readinputatnativeframerate --- .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 5b83e7cbe8..5c508aacd3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts RequiresOpening = false, RequiresClosing = false, - ReadAtNativeFramerate = true + ReadAtNativeFramerate = false }; return new List { mediaSource }; From 1dc5911f068e2c3a7035081ee3fdbbedc4f09225 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Aug 2016 16:54:13 -0400 Subject: [PATCH 161/220] update multi-select --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 50e1cfbbea..61facf8ec4 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -173,6 +173,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 1c815d2e720b95e93cc993fbbdba71551f7bd214 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 01:29:05 -0400 Subject: [PATCH 162/220] update sync display --- MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index dea0a978bf..ea9e58ee47 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -52,7 +52,8 @@ namespace MediaBrowser.Server.Implementations.IO ".db", // bts sync files - ".bts" + ".bts", + ".sync" }; /// From a69f8ecb3dd9267d9b94d8b6ab60e7193c21cf7c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 01:33:30 -0400 Subject: [PATCH 163/220] update logging --- MediaBrowser.Controller/Entities/TV/Season.cs | 3 +++ MediaBrowser.Controller/Entities/TV/Series.cs | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 66fe1cc756..78a974bf76 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -170,10 +170,13 @@ namespace MediaBrowser.Controller.Entities.TV Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + Logger.Debug("Season.GetItemsInternal entering GetEpisodes"); var items = GetEpisodes(user).Where(filter); + Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort"); var result = PostFilterAndSort(items, query); + Logger.Debug("Season.GetItemsInternal complete"); return Task.FromResult(result); } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 02ac42b2af..30c06b2442 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -379,13 +379,19 @@ namespace MediaBrowser.Controller.Entities.TV private IEnumerable GetAllEpisodes(User user) { - return LibraryManager.GetItemList(new InternalItemsQuery(user) + Logger.Debug("Series.GetAllEpisodes entering GetItemList"); + + var result = LibraryManager.GetItemList(new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName } - }).Cast(); + }).Cast().ToList(); + + Logger.Debug("Series.GetAllEpisodes returning {0} episodes", result.Count); + + return result; } public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) From fd6aa72dac2fe4a118603eebab192b46b8f7401e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 15:28:43 -0400 Subject: [PATCH 164/220] add guide optimizations --- MediaBrowser.Api/BaseApiService.cs | 4 +++ MediaBrowser.Api/IHasDtoOptions.cs | 1 + MediaBrowser.Api/LiveTv/LiveTvService.cs | 27 +++++++++++++- MediaBrowser.Api/PlaylistService.cs | 14 +++++++- MediaBrowser.Api/SimilarItemsHelper.cs | 14 +++++++- MediaBrowser.Api/Sync/SyncHelper.cs | 4 +-- MediaBrowser.Api/TvShowsService.cs | 14 ++++++++ .../UserLibrary/BaseItemsRequest.cs | 3 ++ .../UserLibrary/UserLibraryService.cs | 3 ++ MediaBrowser.Controller/Dto/DtoOptions.cs | 4 +++ MediaBrowser.Model/Dto/BaseItemDto.cs | 13 +++++-- .../LiveTv/LiveTvChannelQuery.cs | 6 ++++ MediaBrowser.Model/LiveTv/ProgramQuery.cs | 2 ++ MediaBrowser.Model/Sync/SyncJobQuery.cs | 1 + .../Dto/DtoService.cs | 36 +++++++++++++------ .../LiveTv/LiveTvManager.cs | 36 +++++++++++++++---- .../Sync/SyncRepository.cs | 14 ++++++++ 17 files changed, 172 insertions(+), 24 deletions(-) diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 44a367be09..3ff432d741 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -139,6 +139,10 @@ namespace MediaBrowser.Api { options.ImageTypeLimit = hasDtoOptions.ImageTypeLimit.Value; } + if (hasDtoOptions.EnableUserData.HasValue) + { + options.EnableUserData = hasDtoOptions.EnableUserData.Value; + } if (!string.IsNullOrWhiteSpace(hasDtoOptions.EnableImageTypes)) { diff --git a/MediaBrowser.Api/IHasDtoOptions.cs b/MediaBrowser.Api/IHasDtoOptions.cs index dac366113c..6ed1670c21 100644 --- a/MediaBrowser.Api/IHasDtoOptions.cs +++ b/MediaBrowser.Api/IHasDtoOptions.cs @@ -4,6 +4,7 @@ namespace MediaBrowser.Api public interface IHasDtoOptions : IHasItemFields { bool? EnableImages { get; set; } + bool? EnableUserData { get; set; } int? ImageTypeLimit { get; set; } diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 91157cd11f..545ac162ff 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -82,6 +82,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "AddCurrentProgram", Description = "Optional. Adds current program info to each channel", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool AddCurrentProgram { get; set; } + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + public GetChannels() { AddCurrentProgram = true; @@ -149,6 +152,9 @@ namespace MediaBrowser.Api.LiveTv public bool EnableTotalRecordCount { get; set; } + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + public GetRecordings() { EnableTotalRecordCount = true; @@ -271,6 +277,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + /// /// Fields to return within the items, in addition to basic information /// @@ -331,6 +340,9 @@ namespace MediaBrowser.Api.LiveTv /// 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, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } } [Route("/LiveTv/Programs/{Id}", "GET", Summary = "Gets a live tv program")] @@ -726,7 +738,12 @@ namespace MediaBrowser.Api.LiveTv var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); - var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ConfigureAwait(false)).ToArray(); + var options = GetDtoOptions(request); + RemoveFields(options); + + options.AddCurrentProgram = request.AddCurrentProgram; + + var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, options, user).ConfigureAwait(false)).ToArray(); var result = new QueryResult { @@ -737,6 +754,14 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedSerializedResultUsingCache(result); } + private void RemoveFields(DtoOptions options) + { + options.Fields.Remove(ItemFields.CanDelete); + options.Fields.Remove(ItemFields.CanDownload); + options.Fields.Remove(ItemFields.DisplayPreferencesId); + options.Fields.Remove(ItemFields.Etag); + } + public object Get(GetChannel request) { var user = string.IsNullOrWhiteSpace(request.UserId) ? null : _userManager.GetUserById(request.UserId); diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs index 604227a150..9693992882 100644 --- a/MediaBrowser.Api/PlaylistService.cs +++ b/MediaBrowser.Api/PlaylistService.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Api } [Route("/Playlists/{Id}/Items", "GET", Summary = "Gets the original items of a playlist")] - public class GetPlaylistItems : IReturn>, IHasItemFields + public class GetPlaylistItems : IReturn>, IHasDtoOptions { [ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] public string Id { get; set; } @@ -104,6 +104,18 @@ namespace MediaBrowser.Api /// 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, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } } [Authenticated] diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index a1e47bd8fd..1621c80567 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -29,8 +29,20 @@ namespace MediaBrowser.Api public string ExcludeArtistIds { get; set; } } - public class BaseGetSimilarItems : IReturn, IHasItemFields + public class BaseGetSimilarItems : IReturn, IHasDtoOptions { + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + /// /// Gets or sets the user id. /// diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs index 0d3e8707db..2f857000c0 100644 --- a/MediaBrowser.Api/Sync/SyncHelper.cs +++ b/MediaBrowser.Api/Sync/SyncHelper.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Api.Sync } break; } - if (item.IsFolder && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre) + if (item.IsFolderItem && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre) { options.Add(SyncJobOption.Quality); options.Add(SyncJobOption.Profile); @@ -44,7 +44,7 @@ namespace MediaBrowser.Api.Sync { if (item.SupportsSync ?? false) { - if (item.IsFolder || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson) + if (item.IsFolderItem || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson) { options.Add(SyncJobOption.SyncNewContent); options.Add(SyncJobOption.ItemLimit); diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 92189c2458..e295f3b3a6 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -69,6 +69,9 @@ namespace MediaBrowser.Api [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } } [Route("/Shows/Upcoming", "GET", Summary = "Gets a list of upcoming episodes")] @@ -117,6 +120,9 @@ namespace MediaBrowser.Api [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } } [Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")] @@ -184,6 +190,10 @@ namespace MediaBrowser.Api [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + } [Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")] @@ -226,6 +236,10 @@ namespace MediaBrowser.Api [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + } /// diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index 3e9a541c0c..96acb1f607 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -226,6 +226,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool? EnableImages { get; set; } + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? ImageTypeLimit { get; set; } diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index bbccef6dea..c392ef4634 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -246,6 +246,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + public GetLatestMedia() { Limit = 20; diff --git a/MediaBrowser.Controller/Dto/DtoOptions.cs b/MediaBrowser.Controller/Dto/DtoOptions.cs index d627cc67ae..e69b649488 100644 --- a/MediaBrowser.Controller/Dto/DtoOptions.cs +++ b/MediaBrowser.Controller/Dto/DtoOptions.cs @@ -19,12 +19,16 @@ namespace MediaBrowser.Controller.Dto public bool EnableImages { get; set; } public bool AddProgramRecordingInfo { get; set; } public string DeviceId { get; set; } + public bool EnableUserData { get; set; } + public bool AddCurrentProgram { get; set; } public DtoOptions() { Fields = new List(); ImageTypeLimit = int.MaxValue; EnableImages = true; + EnableUserData = true; + AddCurrentProgram = true; Fields = Enum.GetNames(typeof (ItemFields)) .Select(i => (ItemFields) Enum.Parse(typeof (ItemFields), i, true)) diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 7d69359d1a..348a781ae1 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -346,7 +346,16 @@ namespace MediaBrowser.Model.Dto /// Gets or sets a value indicating whether this instance is folder. /// /// true if this instance is folder; otherwise, false. - public bool IsFolder { get; set; } + public bool? IsFolder { get; set; } + + [IgnoreDataMember] + public bool IsFolderItem + { + get + { + return IsFolder ?? false; + } + } /// /// Gets or sets the parent id. @@ -656,7 +665,7 @@ namespace MediaBrowser.Model.Dto { get { - return RunTimeTicks.HasValue || IsFolder || IsGenre || IsMusicGenre || IsArtist; + return RunTimeTicks.HasValue || IsFolderItem || IsGenre || IsMusicGenre || IsArtist; } } diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index 3a6ad04448..0ece1e4a00 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -59,5 +59,11 @@ namespace MediaBrowser.Model.LiveTv /// /// true if [add current program]; otherwise, false. public bool AddCurrentProgram { get; set; } + public bool EnableUserData { get; set; } + + public LiveTvChannelQuery() + { + EnableUserData = true; + } } } diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index 0141191c18..bf459237a0 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -15,9 +15,11 @@ namespace MediaBrowser.Model.LiveTv SortBy = new string[] { }; Genres = new string[] { }; EnableTotalRecordCount = true; + EnableUserData = true; } public bool EnableTotalRecordCount { get; set; } + public bool EnableUserData { get; set; } /// /// Fields to return within the items, in addition to basic information diff --git a/MediaBrowser.Model/Sync/SyncJobQuery.cs b/MediaBrowser.Model/Sync/SyncJobQuery.cs index e86ec929f2..bb99b5d5f3 100644 --- a/MediaBrowser.Model/Sync/SyncJobQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobQuery.cs @@ -23,6 +23,7 @@ namespace MediaBrowser.Model.Sync /// /// The user identifier. public string UserId { get; set; } + public string ExcludeTargetIds { get; set; } /// /// Gets or sets the status. /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index b646605ed4..3d257d1947 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -329,7 +329,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (user != null) { - await AttachUserSpecificInfo(dto, item, user, fields).ConfigureAwait(false); + await AttachUserSpecificInfo(dto, item, user, options).ConfigureAwait(false); } var hasMediaSources = item as IHasMediaSources; @@ -446,17 +446,18 @@ namespace MediaBrowser.Server.Implementations.Dto /// /// Attaches the user specific info. /// - /// The dto. - /// The item. - /// The user. - /// The fields. - private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields) + private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, DtoOptions dtoOptions) { + var fields = dtoOptions.Fields; + if (item.IsFolder) { var folder = (Folder)item; - dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); + if (dtoOptions.EnableUserData) + { + dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); + } if (!dto.ChildCount.HasValue && item.SourceType == SourceType.Library) { @@ -476,7 +477,10 @@ namespace MediaBrowser.Server.Implementations.Dto else { - dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result; + if (dtoOptions.EnableUserData) + { + dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result; + } } dto.PlayAccess = item.GetPlayAccess(user); @@ -484,7 +488,10 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo)) { var userCanSync = user != null && user.Policy.EnableSync; - dto.SupportsSync = userCanSync && _syncManager.SupportsSync(item); + if (userCanSync && _syncManager.SupportsSync(item)) + { + dto.SupportsSync = true; + } } if (fields.Contains(ItemFields.SeasonUserData)) @@ -969,7 +976,16 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Id = GetDtoId(item); dto.IndexNumber = item.IndexNumber; dto.ParentIndexNumber = item.ParentIndexNumber; - dto.IsFolder = item.IsFolder; + + if (item.IsFolder) + { + dto.IsFolder = true; + } + else if (item is IHasMediaSources) + { + dto.IsFolder = false; + } + dto.MediaType = item.MediaType; dto.LocationType = item.LocationType; if (item.IsHD.HasValue && item.IsHD.Value) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 09d156661d..ccbcb910d3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -951,6 +951,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv var queryResult = _libraryManager.QueryItems(internalQuery); + RemoveFields(options); + var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ConfigureAwait(false)).ToArray(); var result = new QueryResult @@ -1031,6 +1033,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv var user = _userManager.GetUserById(query.UserId); + RemoveFields(options); + var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray(); var result = new QueryResult @@ -1662,6 +1666,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false); + RemoveFields(options); + var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray(); return new QueryResult @@ -1922,7 +1928,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelIds = tuples.Select(i => i.Item2.Id.ToString("N")).Distinct().ToArray(); - var programs = _libraryManager.GetItemList(new InternalItemsQuery(user) + var programs = options.AddCurrentProgram ? _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, ChannelIds = channelIds, @@ -1932,7 +1938,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv SortBy = new[] { "StartDate" }, TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") } - }).ToList(); + }).ToList() : new List(); + + RemoveFields(options); foreach (var tuple in tuples) { @@ -1944,14 +1952,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.ChannelType = channel.ChannelType; dto.ServiceName = GetService(channel).Name; - dto.MediaSources = channel.GetMediaSources(true).ToList(); + if (options.Fields.Contains(ItemFields.MediaSources)) + { + dto.MediaSources = channel.GetMediaSources(true).ToList(); + } var channelIdString = channel.Id.ToString("N"); - var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString)); - - if (currentProgram != null) + if (options.AddCurrentProgram) { - dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, options, user); + var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString)); + + if (currentProgram != null) + { + dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, options, user); + } } } } @@ -2447,6 +2461,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user); } + private void RemoveFields(DtoOptions options) + { + options.Fields.Remove(ItemFields.CanDelete); + options.Fields.Remove(ItemFields.CanDownload); + options.Fields.Remove(ItemFields.DisplayPreferencesId); + options.Fields.Remove(ItemFields.Etag); + } + public async Task GetInternalLiveTvFolder(CancellationToken cancellationToken) { var name = _localization.GetLocalizedString("ViewTypeLiveTV"); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index d7c77e655b..6b7bcfa010 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -414,6 +414,20 @@ namespace MediaBrowser.Server.Implementations.Sync whereClauses.Add("TargetId=@TargetId"); cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; } + if (!string.IsNullOrWhiteSpace(query.ExcludeTargetIds)) + { + var excludeIds = (query.ExcludeTargetIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + if (excludeIds.Length == 1) + { + whereClauses.Add("TargetId<>@ExcludeTargetId"); + cmd.Parameters.Add(cmd, "@ExcludeTargetId", DbType.String).Value = excludeIds[0]; + } + else if (excludeIds.Length > 1) + { + whereClauses.Add("TargetId<>@ExcludeTargetId"); + cmd.Parameters.Add(cmd, "@ExcludeTargetId", DbType.String).Value = excludeIds[0]; + } + } if (!string.IsNullOrWhiteSpace(query.UserId)) { whereClauses.Add("UserId=@UserId"); From acc02aa3c3186a3a99de64a42740e74e03ec0327 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 16:35:39 -0400 Subject: [PATCH 165/220] fix parsing of added value --- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 2e34135a62..0c8501e626 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -231,7 +231,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers DateTime added; if (DateTime.TryParseExact(val, BaseNfoSaver.DateAddedFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out added)) { - item.EndDate = added.ToUniversalTime(); + item.DateCreated = added.ToUniversalTime(); } else if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out added)) { From 43c94884e72b5537cd68928614bf8c9ecdb98844 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 16:45:47 -0400 Subject: [PATCH 166/220] update logging --- MediaBrowser.Controller/Entities/TV/Season.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 78a974bf76..33d4f16a90 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -170,13 +170,15 @@ namespace MediaBrowser.Controller.Entities.TV Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - Logger.Debug("Season.GetItemsInternal entering GetEpisodes"); + var id = Guid.NewGuid().ToString("N"); + + Logger.Debug("Season.GetItemsInternal entering GetEpisodes. Request id: " + id); var items = GetEpisodes(user).Where(filter); - Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort"); + Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort. Request id: " + id); var result = PostFilterAndSort(items, query); - Logger.Debug("Season.GetItemsInternal complete"); + Logger.Debug("Season.GetItemsInternal complete. Request id: " + id); return Task.FromResult(result); } From d6dc6ffe7e6f7a9699c764cba2bf32c996dcd771 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Aug 2016 16:52:16 -0400 Subject: [PATCH 167/220] update season methods --- MediaBrowser.Controller/Entities/Folder.cs | 10 ++++---- MediaBrowser.Controller/Entities/TV/Season.cs | 2 +- MediaBrowser.Controller/Entities/TV/Series.cs | 2 +- .../Entities/UserRootFolder.cs | 2 +- .../Entities/UserViewBuilder.cs | 25 ++++++++++++------- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index f8eb414b60..b19667942d 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -702,7 +702,7 @@ namespace MediaBrowser.Controller.Entities items = GetRecursiveChildren(user, query); } - return PostFilterAndSort(items, query); + return PostFilterAndSort(items, query, true, true); } if (!(this is UserRootFolder) && !(this is AggregateFolder)) @@ -903,7 +903,7 @@ namespace MediaBrowser.Controller.Entities if (query.ItemIds.Length > 0) { var specificItems = query.ItemIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); - return Task.FromResult(PostFilterAndSort(specificItems, query)); + return Task.FromResult(PostFilterAndSort(specificItems, query, true, true)); } return GetItemsInternal(query); @@ -959,12 +959,12 @@ namespace MediaBrowser.Controller.Entities : GetChildren(user, true).Where(filter); } - return PostFilterAndSort(items, query); + return PostFilterAndSort(items, query, true, true); } - protected QueryResult PostFilterAndSort(IEnumerable items, InternalItemsQuery query) + protected QueryResult PostFilterAndSort(IEnumerable items, InternalItemsQuery query, bool collapseBoxSetItems, bool enableSorting) { - return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager); + return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager, collapseBoxSetItems, enableSorting); } public virtual IEnumerable GetChildren(User user, bool includeLinkedChildren) diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 33d4f16a90..628e27c02e 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -176,7 +176,7 @@ namespace MediaBrowser.Controller.Entities.TV var items = GetEpisodes(user).Where(filter); Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort. Request id: " + id); - var result = PostFilterAndSort(items, query); + var result = PostFilterAndSort(items, query, false, false); Logger.Debug("Season.GetItemsInternal complete. Request id: " + id); return Task.FromResult(result); diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 30c06b2442..e48c32a25e 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -237,7 +237,7 @@ namespace MediaBrowser.Controller.Entities.TV Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); var items = GetSeasons(user).Where(filter); - var result = PostFilterAndSort(items, query); + var result = PostFilterAndSort(items, query, false, true); return Task.FromResult(result); } diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index bd25d3a6ae..aff1f5e286 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Entities var user = query.User; Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - return PostFilterAndSort(result.Where(filter), query); + return PostFilterAndSort(result.Where(filter), query, true, true); } public override int GetChildCount(User user) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index d0f7efa8c8..6128192ea2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -424,7 +424,7 @@ namespace MediaBrowser.Controller.Entities query.SortBy = new string[] { }; - return PostFilterAndSort(items, parent, null, query); + return PostFilterAndSort(items, parent, null, query, false, true); } private QueryResult GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query) @@ -780,7 +780,7 @@ namespace MediaBrowser.Controller.Entities { items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager)); - return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config); + return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config, true, true); } public static bool FilterItem(BaseItem item, InternalItemsQuery query) @@ -791,9 +791,11 @@ namespace MediaBrowser.Controller.Entities private QueryResult PostFilterAndSort(IEnumerable items, BaseItem queryParent, int? totalRecordLimit, - InternalItemsQuery query) + InternalItemsQuery query, + bool collapseBoxSetItems, + bool enableSorting) { - return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _config); + return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _config, collapseBoxSetItems, enableSorting); } public static QueryResult PostFilterAndSort(IEnumerable items, @@ -801,7 +803,9 @@ namespace MediaBrowser.Controller.Entities int? totalRecordLimit, InternalItemsQuery query, ILibraryManager libraryManager, - IServerConfigurationManager configurationManager) + IServerConfigurationManager configurationManager, + bool collapseBoxSetItems, + bool enableSorting) { var user = query.User; @@ -810,7 +814,10 @@ namespace MediaBrowser.Controller.Entities query.IsVirtualUnaired, query.IsUnaired); - items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user, configurationManager); + if (collapseBoxSetItems) + { + items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user, configurationManager); + } // This must be the last filter if (!string.IsNullOrEmpty(query.AdjacentTo)) @@ -818,7 +825,7 @@ namespace MediaBrowser.Controller.Entities items = FilterForAdjacency(items, query.AdjacentTo); } - return Sort(items, totalRecordLimit, query, libraryManager); + return SortAndPage(items, totalRecordLimit, query, libraryManager, enableSorting); } public static IEnumerable CollapseBoxSetItemsIfNeeded(IEnumerable items, @@ -1191,10 +1198,10 @@ namespace MediaBrowser.Controller.Entities return items; } - public static QueryResult Sort(IEnumerable items, + public static QueryResult SortAndPage(IEnumerable items, int? totalRecordLimit, InternalItemsQuery query, - ILibraryManager libraryManager) + ILibraryManager libraryManager, bool enableSorting) { var user = query.User; From cc62faa1c2c212d07c556e5368888ecc3ee537eb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 01:56:10 -0400 Subject: [PATCH 168/220] update season queries --- MediaBrowser.Api/TvShowsService.cs | 38 +--- .../Entities/Audio/MusicArtist.cs | 49 +++++ .../Entities/Audio/MusicGenre.cs | 43 +++++ MediaBrowser.Controller/Entities/GameGenre.cs | 43 +++++ MediaBrowser.Controller/Entities/Genre.cs | 43 +++++ .../Entities/InternalItemsQuery.cs | 2 + MediaBrowser.Controller/Entities/Person.cs | 58 ++++++ MediaBrowser.Controller/Entities/Studio.cs | 43 +++++ MediaBrowser.Controller/Entities/TV/Season.cs | 30 +-- MediaBrowser.Controller/Entities/TV/Series.cs | 175 ++++++++++-------- .../Entities/UserViewBuilder.cs | 53 ------ MediaBrowser.Controller/Entities/Year.cs | 43 +++++ .../IServerApplicationPaths.cs | 2 + .../Encoder/MediaEncoder.cs | 8 +- .../Manager/MetadataService.cs | 11 +- .../Dto/DtoService.cs | 116 ++---------- .../Library/LibraryManager.cs | 72 +------ .../Library/SearchEngine.cs | 20 +- .../Persistence/SqliteItemRepository.cs | 11 ++ .../ServerApplicationPaths.cs | 8 + .../Session/SessionManager.cs | 3 +- 21 files changed, 488 insertions(+), 383 deletions(-) diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index e295f3b3a6..daaa6343d1 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -423,23 +423,14 @@ namespace MediaBrowser.Api throw new ResourceNotFoundException("No series exists with Id " + request.Id); } - var seasons = series.GetSeasons(user); - - if (request.IsSpecialSeason.HasValue) + var seasons = (await series.GetItems(new InternalItemsQuery(user) { - var val = request.IsSpecialSeason.Value; - - seasons = seasons.Where(i => i.IsSpecialSeason == val); - } + IsMissing = request.IsMissing, + IsVirtualUnaired = request.IsVirtualUnaired, + IsSpecialSeason = request.IsSpecialSeason, + AdjacentTo = request.AdjacentTo - seasons = FilterVirtualSeasons(request, seasons); - - // This must be the last filter - if (!string.IsNullOrEmpty(request.AdjacentTo)) - { - seasons = UserViewBuilder.FilterForAdjacency(seasons, request.AdjacentTo) - .Cast(); - } + }).ConfigureAwait(false)).Items.OfType(); var dtoOptions = GetDtoOptions(request); @@ -453,23 +444,6 @@ namespace MediaBrowser.Api }; } - private IEnumerable FilterVirtualSeasons(GetSeasons request, IEnumerable items) - { - if (request.IsMissing.HasValue) - { - var val = request.IsMissing.Value; - items = items.Where(i => (i.IsMissingSeason) == val); - } - - if (request.IsVirtualUnaired.HasValue) - { - var val = request.IsVirtualUnaired.Value; - items = items.Where(i => i.IsVirtualUnaired == val); - } - - return items; - } - public async Task Get(GetEpisodes request) { var user = _userManager.GetUserById(request.UserId); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 56f9a5b888..81d1deaa23 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -270,5 +270,54 @@ namespace MediaBrowser.Controller.Entities.Audio return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.ArtistsPath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + if (IsAccessedByName) + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + if (IsAccessedByName) + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 9aa5625fac..bd991d9f47 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -92,5 +92,48 @@ namespace MediaBrowser.Controller.Entities.Audio return LibraryManager.GetItemList(query); } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.MusicGenrePath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 5d66bf3abc..6448828fb3 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -84,5 +84,48 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GameGenrePath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index c7fe25a962..1736ba8c76 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -87,5 +87,48 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GenrePath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 69cab5ec53..deea631127 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -37,6 +37,7 @@ namespace MediaBrowser.Controller.Entities public string[] Genres { get; set; } public string[] Keywords { get; set; } + public bool? IsSpecialSeason { get; set; } public bool? IsMissing { get; set; } public bool? IsUnaired { get; set; } public bool? IsVirtualUnaired { get; set; } @@ -50,6 +51,7 @@ namespace MediaBrowser.Controller.Entities public string PresentationUniqueKey { get; set; } public string Path { get; set; } + public string PathNotStartsWith { get; set; } public string Name { get; set; } public string SlugName { get; set; } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 4ee140b2b1..f21bc0a71e 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -122,6 +122,64 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validFilename = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + string subFolderPrefix = null; + + foreach (char c in validFilename) + { + if (char.IsLetterOrDigit(c)) + { + subFolderPrefix = c.ToString(); + break; + } + } + + var path = ConfigurationManager.ApplicationPaths.PeoplePath; + + return string.IsNullOrEmpty(subFolderPrefix) ? + System.IO.Path.Combine(path, validFilename) : + System.IO.Path.Combine(path, subFolderPrefix, validFilename); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } /// diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 7e3d6fe8e1..04b09b7442 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -85,5 +85,48 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.StudioPath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 628e27c02e..842b2fd602 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -141,24 +141,6 @@ namespace MediaBrowser.Controller.Entities.TV return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name; } - [IgnoreDataMember] - public bool IsMissingSeason - { - get { return (IsVirtualItem) && !IsUnaired; } - } - - [IgnoreDataMember] - public bool IsVirtualUnaired - { - get { return (IsVirtualItem) && IsUnaired; } - } - - [IgnoreDataMember] - public bool IsSpecialSeason - { - get { return (IndexNumber ?? -1) == 0; } - } - protected override Task> GetItemsInternal(InternalItemsQuery query) { if (query.User == null) @@ -189,19 +171,17 @@ namespace MediaBrowser.Controller.Entities.TV /// IEnumerable{Episode}. public IEnumerable GetEpisodes(User user) { - var config = user.Configuration; - - return GetEpisodes(Series, user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); + return GetEpisodes(Series, user); } - public IEnumerable GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) + public IEnumerable GetEpisodes(Series series, User user) { - return GetEpisodes(series, user, includeMissingEpisodes, includeVirtualUnairedEpisodes, null); + return GetEpisodes(series, user, null); } - public IEnumerable GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes) + public IEnumerable GetEpisodes(Series series, User user, IEnumerable allSeriesEpisodes) { - return series.GetSeasonEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes); + return series.GetSeasonEpisodes(user, this, allSeriesEpisodes); } public IEnumerable GetEpisodes() diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index e48c32a25e..4915cfedc7 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -207,7 +207,30 @@ namespace MediaBrowser.Controller.Entities.TV { var config = user.Configuration; - return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); + var seriesKey = GetUniqueSeriesKey(this); + + Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey); + var query = new InternalItemsQuery(user) + { + AncestorWithPresentationUniqueKey = seriesKey, + IncludeItemTypes = new[] {typeof (Season).Name}, + SortBy = new[] {ItemSortBy.SortName} + }; + + if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + { + query.IsVirtualItem = false; + } + else if (!config.DisplayMissingEpisodes) + { + query.IsMissing = false; + } + else if (!config.DisplayUnairedEpisodes) + { + query.IsVirtualUnaired = false; + } + + return LibraryManager.GetItemList(query).Cast(); } protected override Task> GetItemsInternal(InternalItemsQuery query) @@ -241,59 +264,39 @@ namespace MediaBrowser.Controller.Entities.TV return Task.FromResult(result); } - public IEnumerable GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired) + public IEnumerable GetEpisodes(User user) { var seriesKey = GetUniqueSeriesKey(this); + Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey); - Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey); - var seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) + var query = new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = seriesKey, - IncludeItemTypes = new[] { typeof(Season).Name }, - SortBy = new[] { ItemSortBy.SortName } - - }).Cast().ToList(); - - - if (!includeMissingSeasons) + IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name}, + SortBy = new[] {ItemSortBy.SortName} + }; + var config = user.Configuration; + if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) { - seasons = seasons.Where(i => !(i.IsMissingSeason)).ToList(); + query.IsVirtualItem = false; } - - if (!includeVirtualUnaired) + else if (!config.DisplayMissingEpisodes) { - seasons = seasons.Where(i => !i.IsVirtualUnaired).ToList(); + query.IsMissing = false; } - - return seasons; - } - - public IEnumerable GetEpisodes(User user) - { - var config = user.Configuration; - - return GetEpisodes(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); - } - - public IEnumerable GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired) - { - var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey); - - var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user) + else if (!config.DisplayUnairedEpisodes) { - AncestorWithPresentationUniqueKey = seriesKey, - IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }, - SortBy = new[] { ItemSortBy.SortName } + query.IsVirtualUnaired = false; + } - }).ToList(); + var allItems = LibraryManager.GetItemList(query).ToList(); Logger.Debug("GetEpisodes return {0} items from database", allItems.Count); var allSeriesEpisodes = allItems.OfType().ToList(); var allEpisodes = allItems.OfType() - .SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes)) + .SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes)) .Reverse() .ToList(); @@ -370,13 +373,6 @@ namespace MediaBrowser.Controller.Entities.TV progress.Report(100); } - public IEnumerable GetSeasonEpisodes(User user, Season season) - { - var config = user.Configuration; - - return GetSeasonEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); - } - private IEnumerable GetAllEpisodes(User user) { Logger.Debug("Series.GetAllEpisodes entering GetItemList"); @@ -394,62 +390,51 @@ namespace MediaBrowser.Controller.Entities.TV return result; } - public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) + public IEnumerable GetSeasonEpisodes(User user, Season parentSeason) { - IEnumerable episodes = GetAllEpisodes(user); - - return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); - } + var seriesKey = GetUniqueSeriesKey(this); + Logger.Debug("GetSeasonEpisodes seriesKey: {0}", seriesKey); - public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable allSeriesEpisodes) - { - if (allSeriesEpisodes == null) + var query = new InternalItemsQuery(user) { - Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null"); - return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes); + AncestorWithPresentationUniqueKey = seriesKey, + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName } + }; + var config = user.Configuration; + if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + { + query.IsVirtualItem = false; } - - Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason"); - var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons); - - if (!includeMissingEpisodes) + else if (!config.DisplayMissingEpisodes) { - episodes = episodes.Where(i => !i.IsMissingEpisode); + query.IsMissing = false; } - if (!includeVirtualUnairedEpisodes) + else if (!config.DisplayUnairedEpisodes) { - episodes = episodes.Where(i => !i.IsVirtualUnaired); + query.IsVirtualUnaired = false; } - var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder; + var allItems = LibraryManager.GetItemList(query).OfType(); - return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending) - .Cast(); + return GetSeasonEpisodes(user, parentSeason, allItems); } - /// - /// Filters the episodes by season. - /// - public static IEnumerable FilterEpisodesBySeason(IEnumerable episodes, int seasonNumber, bool includeSpecials) + public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, IEnumerable allSeriesEpisodes) { - if (!includeSpecials || seasonNumber < 1) + if (allSeriesEpisodes == null) { - return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber); + Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null"); + return GetSeasonEpisodes(user, parentSeason); } - return episodes.Where(i => - { - var episode = i; - - if (episode != null) - { - var currentSeasonNumber = episode.AiredSeasonNumber; + Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason"); + var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons); - return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber; - } + var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder; - return false; - }); + return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending) + .Cast(); } /// @@ -480,6 +465,32 @@ namespace MediaBrowser.Controller.Entities.TV }); } + /// + /// Filters the episodes by season. + /// + public static IEnumerable FilterEpisodesBySeason(IEnumerable episodes, int seasonNumber, bool includeSpecials) + { + if (!includeSpecials || seasonNumber < 1) + { + return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber); + } + + return episodes.Where(i => + { + var episode = i; + + if (episode != null) + { + var currentSeasonNumber = episode.AiredSeasonNumber; + + return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber; + } + + return false; + }); + } + + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Series); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 6128192ea2..9f3acc3fc3 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1100,8 +1100,6 @@ namespace MediaBrowser.Controller.Entities bool? isVirtualUnaired, bool? isUnaired) { - items = FilterVirtualSeasons(items, isMissing, isVirtualUnaired, isUnaired); - if (isMissing.HasValue) { var val = isMissing.Value; @@ -1147,57 +1145,6 @@ namespace MediaBrowser.Controller.Entities return items; } - private static IEnumerable FilterVirtualSeasons( - IEnumerable items, - bool? isMissing, - bool? isVirtualUnaired, - bool? isUnaired) - { - if (isMissing.HasValue) - { - var val = isMissing.Value; - items = items.Where(i => - { - var e = i as Season; - if (e != null) - { - return (e.IsMissingSeason) == val; - } - return true; - }); - } - - if (isUnaired.HasValue) - { - var val = isUnaired.Value; - items = items.Where(i => - { - var e = i as Season; - if (e != null) - { - return e.IsUnaired == val; - } - return true; - }); - } - - if (isVirtualUnaired.HasValue) - { - var val = isVirtualUnaired.Value; - items = items.Where(i => - { - var e = i as Season; - if (e != null) - { - return e.IsVirtualUnaired == val; - } - return true; - }); - } - - return items; - } - public static QueryResult SortAndPage(IEnumerable items, int? totalRecordLimit, InternalItemsQuery query, diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index db896f1fc7..4197ea93e5 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -112,5 +112,48 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public static string GetPath(string name, bool normalizeName = true) + { + // Trim the period at the end because windows will have a hard time with that + var validName = normalizeName ? + FileSystem.GetValidFilename(name).Trim().TrimEnd('.') : + name; + + return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.YearPath, validName); + } + + private string GetRebasedPath() + { + return GetPath(System.IO.Path.GetFileName(Path), false); + } + + public override bool RequiresRefresh() + { + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath); + return true; + } + return base.RequiresRefresh(); + } + + /// + /// This is called before any metadata refresh and returns true or false indicating if changes were made + /// + public override bool BeforeMetadataRefresh() + { + var hasChanges = base.BeforeMetadataRefresh(); + + var newPath = GetRebasedPath(); + if (!string.Equals(Path, newPath, StringComparison.Ordinal)) + { + Path = newPath; + hasChanges = true; + } + + return hasChanges; + } } } diff --git a/MediaBrowser.Controller/IServerApplicationPaths.cs b/MediaBrowser.Controller/IServerApplicationPaths.cs index c07934d0b1..c89a60a6f8 100644 --- a/MediaBrowser.Controller/IServerApplicationPaths.cs +++ b/MediaBrowser.Controller/IServerApplicationPaths.cs @@ -106,5 +106,7 @@ namespace MediaBrowser.Controller /// /// The internal metadata path. string InternalMetadataPath { get; } + + string ArtistsPath { get; } } } \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c8a28e832a..e90f6bdc36 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -343,14 +343,16 @@ namespace MediaBrowser.MediaEncoding.Encoder // If that doesn't pan out, then do a recursive search var files = Directory.GetFiles(path); - var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); - var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase)); + var excludeExtensions = new[] { ".c" }; + + var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty)); + var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty)); if (string.IsNullOrWhiteSpace(ffmpegPath) || !File.Exists(ffmpegPath)) { files = Directory.GetFiles(path, "*", SearchOption.AllDirectories); - ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); + ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty)); if (!string.IsNullOrWhiteSpace(ffmpegPath)) { diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 04437cff79..2a69948b1a 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -42,6 +42,13 @@ namespace MediaBrowser.Providers.Manager var config = ProviderManager.GetMetadataOptions(item); var updateType = ItemUpdateType.None; + var requiresRefresh = false; + + if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) + { + // TODO: If this returns true, should we instead just change metadata refresh mode to Full? + requiresRefresh = item.RequiresRefresh(); + } var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem); var localImagesFailed = false; @@ -70,14 +77,10 @@ namespace MediaBrowser.Providers.Manager bool hasRefreshedMetadata = true; bool hasRefreshedImages = true; - var requiresRefresh = false; // Next run metadata providers if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) { - // TODO: If this returns true, should we instead just change metadata refresh mode to Full? - requiresRefresh = item.RequiresRefresh(); - var providers = GetProviders(item, refreshOptions, requiresRefresh) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 3d257d1947..be68162caf 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -955,20 +955,23 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Genres = item.Genres; } - dto.ImageTags = new Dictionary(); - - // Prevent implicitly captured closure - var currentItem = item; - foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type)) - .ToList()) + if (options.EnableImages) { - if (options.GetImageLimit(image.Type) > 0) - { - var tag = GetImageCacheTag(item, image); + dto.ImageTags = new Dictionary(); - if (tag != null) + // Prevent implicitly captured closure + var currentItem = item; + foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type)) + .ToList()) + { + if (options.GetImageLimit(image.Type) > 0) { - dto.ImageTags[image.Type] = tag; + var tag = GetImageCacheTag(item, image); + + if (tag != null) + { + dto.ImageTags[image.Type] = tag; + } } } } @@ -1527,97 +1530,6 @@ namespace MediaBrowser.Server.Implementations.Dto } } - /// - /// Since it can be slow to make all of these calculations independently, this method will provide a way to do them all at once - /// - /// The folder. - /// The user. - /// The dto. - /// The fields. - /// The synchronize progress. - /// Task. - private async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields, Dictionary syncProgress) - { - var recursiveItemCount = 0; - var unplayed = 0; - - double totalPercentPlayed = 0; - double totalSyncPercent = 0; - - var children = await folder.GetItems(new InternalItemsQuery - { - IsFolder = false, - Recursive = true, - ExcludeLocationTypes = new[] { LocationType.Virtual }, - User = user - - }).ConfigureAwait(false); - - // Loop through each recursive child - foreach (var child in children.Items) - { - var userdata = _userDataRepository.GetUserData(user, child); - - recursiveItemCount++; - - var isUnplayed = true; - - // Incrememt totalPercentPlayed - if (userdata != null) - { - if (userdata.Played) - { - totalPercentPlayed += 100; - - isUnplayed = false; - } - else if (userdata.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0) - { - double itemPercent = userdata.PlaybackPositionTicks; - itemPercent /= child.RunTimeTicks.Value; - totalPercentPlayed += itemPercent; - } - } - - if (isUnplayed) - { - unplayed++; - } - - double percent = 0; - SyncJobItemStatus syncItemProgress; - if (syncProgress.TryGetValue(child.Id.ToString("N"), out syncItemProgress)) - { - switch (syncItemProgress) - { - case SyncJobItemStatus.Synced: - percent = 100; - break; - case SyncJobItemStatus.Converting: - case SyncJobItemStatus.ReadyToTransfer: - case SyncJobItemStatus.Transferring: - percent = 50; - break; - } - } - totalSyncPercent += percent; - } - - dto.RecursiveItemCount = recursiveItemCount; - dto.UserData.UnplayedItemCount = unplayed; - - if (recursiveItemCount > 0) - { - dto.UserData.PlayedPercentage = totalPercentPlayed / recursiveItemCount; - - var pct = totalSyncPercent / recursiveItemCount; - if (pct > 0) - { - dto.SyncPercent = pct; - } - } - } - /// /// Attaches the primary image aspect ratio. /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a19f70e68c..a5e6c1b92d 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -829,7 +829,7 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Person}. public Person GetPerson(string name) { - return GetItemByName(ConfigurationManager.ApplicationPaths.PeoplePath, name); + return CreateItemByName(Person.GetPath(name), name); } /// @@ -839,7 +839,7 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Studio}. public Studio GetStudio(string name) { - return GetItemByName(ConfigurationManager.ApplicationPaths.StudioPath, name); + return CreateItemByName(Studio.GetPath(name), name); } /// @@ -849,7 +849,7 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Genre}. public Genre GetGenre(string name) { - return GetItemByName(ConfigurationManager.ApplicationPaths.GenrePath, name); + return CreateItemByName(Genre.GetPath(name), name); } /// @@ -859,7 +859,7 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{MusicGenre}. public MusicGenre GetMusicGenre(string name) { - return GetItemByName(ConfigurationManager.ApplicationPaths.MusicGenrePath, name); + return CreateItemByName(MusicGenre.GetPath(name), name); } /// @@ -869,14 +869,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{GameGenre}. public GameGenre GetGameGenre(string name) { - return GetItemByName(ConfigurationManager.ApplicationPaths.GameGenrePath, name); + return CreateItemByName(GameGenre.GetPath(name), name); } - /// - /// The us culture - /// - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - /// /// Gets a Year /// @@ -890,19 +885,9 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentOutOfRangeException("Years less than or equal to 0 are invalid."); } - return GetItemByName(ConfigurationManager.ApplicationPaths.YearPath, value.ToString(UsCulture)); - } + var name = value.ToString(CultureInfo.InvariantCulture); - /// - /// Gets the artists path. - /// - /// The artists path. - public string ArtistsPath - { - get - { - return Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "artists"); - } + return CreateItemByName(Year.GetPath(name), name); } /// @@ -912,48 +897,7 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Genre}. public MusicArtist GetArtist(string name) { - return GetItemByName(ArtistsPath, name); - } - - private T GetItemByName(string path, string name) - where T : BaseItem, new() - { - if (string.IsNullOrWhiteSpace(path)) - { - throw new ArgumentNullException("path"); - } - - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - // Trim the period at the end because windows will have a hard time with that - var validFilename = _fileSystem.GetValidFilename(name) - .Trim() - .TrimEnd('.'); - - string subFolderPrefix = null; - - var type = typeof(T); - - if (type == typeof(Person)) - { - foreach (char c in validFilename) - { - if (char.IsLetterOrDigit(c)) - { - subFolderPrefix = c.ToString(); - break; - } - } - } - - var fullPath = string.IsNullOrEmpty(subFolderPrefix) ? - Path.Combine(path, validFilename) : - Path.Combine(path, subFolderPrefix, validFilename); - - return CreateItemByName(fullPath, name); + return CreateItemByName(MusicArtist.GetPath(name), name); } private T CreateItemByName(string path, string name) diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index cf6f070d03..a6d6b5cb8b 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -166,12 +166,12 @@ namespace MediaBrowser.Server.Implementations.Library ExcludeItemTypes = excludeItemTypes.ToArray(), IncludeItemTypes = includeItemTypes.ToArray(), Limit = query.Limit, - IncludeItemsByName = true - + IncludeItemsByName = true, + IsVirtualItem = false }); // Add search hints based on item name - hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item => + hints.AddRange(mediaItems.Select(item => { var index = GetIndex(item.Name, searchTerm, terms); @@ -187,20 +187,6 @@ namespace MediaBrowser.Server.Implementations.Library return Task.FromResult(returnValue); } - private bool IncludeInSearch(BaseItem item) - { - var episode = item as Episode; - - if (episode != null) - { - if (episode.IsMissingEpisode) - { - return false; - } - } - return true; - } - /// /// Gets the index. /// diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index cf8e2fe36c..8006e2b08d 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3095,6 +3095,17 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("LocationType<>'Virtual'"); } } + if (query.IsSpecialSeason.HasValue) + { + if (query.IsSpecialSeason.Value) + { + whereClauses.Add("IndexNumber = 0"); + } + else + { + whereClauses.Add("IndexNumber <> 0"); + } + } if (query.IsUnaired.HasValue) { if (query.IsUnaired.Value) diff --git a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs index 8a04f29a2c..237d49fdae 100644 --- a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs +++ b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs @@ -88,6 +88,14 @@ namespace MediaBrowser.Server.Implementations } } + public string ArtistsPath + { + get + { + return Path.Combine(ItemsByNamePath, "artists"); + } + } + /// /// Gets the path to the Genre directory /// diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 84aab5e1f8..f495e557a3 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1001,7 +1001,8 @@ namespace MediaBrowser.Server.Implementations.Session var series = episode.Series; if (series != null) { - var episodes = series.GetEpisodes(user, false, false) + var episodes = series.GetEpisodes(user) + .Where(i => !i.IsVirtualItem) .SkipWhile(i => i.Id != episode.Id) .ToList(); From 389487638ec358c975f7573c8b6132525f3925ab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 02:26:47 -0400 Subject: [PATCH 169/220] fixes #1851 - EmbyServer crashes if staticly assigned IP address changes --- .../HttpServer/HttpListenerHost.cs | 50 +++++++++++++++++++ .../ApplicationHost.cs | 35 +------------ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 90055d8ec1..6332087391 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -331,6 +331,46 @@ namespace MediaBrowser.Server.Implementations.HttpServer return url; } + private string NormalizeConfiguredLocalAddress(string address) + { + var index = address.Trim('/').IndexOf('/'); + + if (index != -1) + { + address = address.Substring(index + 1); + } + + return address.Trim('/'); + } + + private bool ValidateHost(Uri url) + { + var hosts = _config + .Configuration + .LocalNetworkAddresses + .Select(NormalizeConfiguredLocalAddress) + .ToList(); + + if (hosts.Count == 0) + { + return true; + } + + var host = url.Host ?? string.Empty; + + _logger.Debug("Validating host {0}", host); + + if (_networkManager.IsInPrivateAddressSpace(host)) + { + hosts.Add("localhost"); + hosts.Add("127.0.0.1"); + + return hosts.Any(i => host.IndexOf(i, StringComparison.OrdinalIgnoreCase) != -1); + } + + return true; + } + /// /// Overridable method that can be used to implement a custom hnandler /// @@ -350,6 +390,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer return ; } + if (!ValidateHost(url)) + { + httpRes.StatusCode = 400; + httpRes.ContentType = "text/plain"; + httpRes.Write("Invalid host"); + + httpRes.Close(); + return; + } + var operationName = httpReq.OperationName; var localPath = url.LocalPath; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 74438abbcf..9eb8a47366 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -821,42 +821,11 @@ namespace MediaBrowser.Server.Startup.Common private string CertificatePath { get; set; } - private string NormalizeConfiguredLocalAddress(string address) - { - var index = address.Trim('/').IndexOf('/'); - - if (index != -1) - { - address = address.Substring(index + 1); - } - - return address.Trim('/'); - } private IEnumerable GetUrlPrefixes() { - var hosts = ServerConfigurationManager - .Configuration - .LocalNetworkAddresses - .Select(NormalizeConfiguredLocalAddress) - .ToList(); + var hosts = new List(); - if (hosts.Count == 0) - { - hosts.Add("+"); - } - - if (!hosts.Contains("+", StringComparer.OrdinalIgnoreCase)) - { - if (!hosts.Contains("localhost", StringComparer.OrdinalIgnoreCase)) - { - hosts.Add("localhost"); - } - - if (!hosts.Contains("127.0.0.1", StringComparer.OrdinalIgnoreCase)) - { - hosts.Add("127.0.0.1"); - } - } + hosts.Add("+"); return hosts.SelectMany(i => { From 845c4a0d62e05b89d0a8bc3900b54e3c2cb75168 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 11:13:18 -0400 Subject: [PATCH 170/220] update item by name validators --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 19 +------- MediaBrowser.Controller/Entities/Folder.cs | 8 ++++ .../Persistence/IItemRepository.cs | 4 ++ .../Probing/ProbeResultNormalizer.cs | 7 +-- .../Resolvers/SpecialFolderResolver.cs | 3 +- .../Library/Validators/ArtistsPostScanTask.cs | 7 ++- .../Library/Validators/ArtistsValidator.cs | 18 ++++---- .../Library/Validators/StudiosPostScanTask.cs | 7 ++- .../Library/Validators/StudiosValidator.cs | 18 ++++---- .../Persistence/SqliteItemRepository.cs | 46 +++++++++++++++++++ 10 files changed, 95 insertions(+), 42 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 97a81b7909..9194cdb354 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -157,24 +157,7 @@ namespace MediaBrowser.Api.UserLibrary folder = user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder(); } - if (!string.IsNullOrEmpty(request.Ids)) - { - request.Recursive = true; - var query = GetItemsQuery(request, user); - var result = await folder.GetItems(query).ConfigureAwait(false); - - if (string.IsNullOrWhiteSpace(request.SortBy)) - { - var ids = query.ItemIds.ToList(); - - // Try to preserve order - result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); - } - - return result; - } - - if (request.Recursive) + if (request.Recursive || !string.IsNullOrEmpty(request.Ids)) { return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b19667942d..b5c76c0ebc 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -903,6 +903,14 @@ namespace MediaBrowser.Controller.Entities if (query.ItemIds.Length > 0) { var specificItems = query.ItemIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); + + if (query.SortBy.Length == 0) + { + var ids = query.ItemIds.ToList(); + + // Try to preserve order + specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToList(); + } return Task.FromResult(PostFilterAndSort(specificItems, query, true, true)); } diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 437f0e157a..edfec902b8 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -170,6 +170,10 @@ namespace MediaBrowser.Controller.Persistence QueryResult> GetArtists(InternalItemsQuery query); QueryResult> GetAlbumArtists(InternalItemsQuery query); QueryResult> GetAllArtists(InternalItemsQuery query); + + List GetStudioNames(); + + List GetAllArtistNames(); } } diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 9e9bc0780e..700af682bf 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Text; using System.Xml; using CommonIO; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; @@ -793,7 +794,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (!string.IsNullOrWhiteSpace(artists)) { audio.Artists = SplitArtists(artists, new[] { '/', ';' }, false) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToList(); } else @@ -806,7 +807,7 @@ namespace MediaBrowser.MediaEncoding.Probing else { audio.Artists = SplitArtists(artist, _nameDelimiters, true) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToList(); } } @@ -828,7 +829,7 @@ namespace MediaBrowser.MediaEncoding.Probing else { audio.AlbumArtists = SplitArtists(albumArtist, _nameDelimiters, true) - .Distinct(StringComparer.OrdinalIgnoreCase) + .DistinctNames() .ToList(); } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index 144f788a72..7bb66ed89d 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -50,7 +50,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers { return new CollectionFolder { - CollectionType = GetCollectionType(args) + CollectionType = GetCollectionType(args), + PhysicalLocationsList = args.PhysicalLocations.ToList() }; } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs index 079867ddd8..91b035a350 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -16,15 +17,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. - public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger) + public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -35,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return new ArtistsValidator(_libraryManager, _logger).Run(progress, cancellationToken); + return new ArtistsValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 353be1a44f..3dcdbeae9d 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -24,16 +25,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// The _logger /// private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. /// The logger. - public ArtistsValidator(ILibraryManager libraryManager, ILogger logger) + public ArtistsValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -44,18 +47,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.GetAllArtists(new InternalItemsQuery()) - .Items - .Select(i => i.Item1) - .ToList(); + var names = _itemRepo.GetAllArtistNames(); var numComplete = 0; - var count = items.Count; + var count = names.Count; - foreach (var item in items) + foreach (var name in names) { try { + var item = _libraryManager.GetArtist(name); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -65,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, item.Name); + _logger.ErrorException("Error refreshing {0}", ex, name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs index 0ff609da15..77c6d51465 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -17,15 +18,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. - public StudiosPostScanTask(ILibraryManager libraryManager, ILogger logger) + public StudiosPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -36,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return new StudiosValidator(_libraryManager, _logger).Run(progress, cancellationToken); + return new StudiosValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index 722b74891e..a19b8158a0 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -15,15 +16,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// private readonly ILibraryManager _libraryManager; + private readonly IItemRepository _itemRepo; /// /// The _logger /// private readonly ILogger _logger; - public StudiosValidator(ILibraryManager libraryManager, ILogger logger) + public StudiosValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -34,18 +37,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.GetStudios(new InternalItemsQuery()) - .Items - .Select(i => i.Item1) - .ToList(); + var names = _itemRepo.GetStudioNames(); var numComplete = 0; - var count = items.Count; + var count = names.Count; - foreach (var item in items) + foreach (var name in names) { try { + var item = _libraryManager.GetStudio(name); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -55,7 +57,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, item.Name); + _logger.ErrorException("Error refreshing {0}", ex, name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 8006e2b08d..f04b9f50a4 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3880,6 +3880,52 @@ namespace MediaBrowser.Server.Implementations.Persistence return GetItemValues(query, new[] { 2 }, typeof(MusicGenre).FullName); } + public List GetStudioNames() + { + return GetItemValueNames(new[] { 3 }); + } + + public List GetAllArtistNames() + { + return GetItemValueNames(new[] { 0, 1 }); + } + + private List GetItemValueNames(int[] itemValueTypes) + { + CheckDisposed(); + + var now = DateTime.UtcNow; + + var typeClause = itemValueTypes.Length == 1 ? + ("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) : + ("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")"); + + var list = new List(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "Select Value From ItemValues where " + typeClause + " Group By CleanValue"; + + var commandBehavior = CommandBehavior.SequentialAccess | CommandBehavior.SingleResult; + + using (var reader = cmd.ExecuteReader(commandBehavior)) + { + LogQueryTime("GetItemValueNames", cmd, now); + + while (reader.Read()) + { + if (!reader.IsDBNull(0)) + { + list.Add(reader.GetString(0)); + } + } + } + + } + + return list; + } + private QueryResult> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType) { if (query == null) From db9c02fffddc15f4660f2462093e72ba257f8acb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 12:45:36 -0400 Subject: [PATCH 171/220] update notifications --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 25 ++++++++++++++----- .../Library/LibraryManager.cs | 7 +++++- .../Persistence/SqliteItemRepository.cs | 6 ++--- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 9194cdb354..ce7905b42f 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -149,6 +149,24 @@ namespace MediaBrowser.Api.UserLibrary item = user == null ? _libraryManager.RootFolder : user.RootFolder; } + if (!string.IsNullOrEmpty(request.Ids)) + { + var query = GetItemsQuery(request, user); + var specificItems = _libraryManager.GetItemList(query).ToArray(); + if (query.SortBy.Length == 0) + { + var ids = query.ItemIds.ToList(); + + // Try to preserve order + specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); + } + return new QueryResult + { + Items = specificItems.ToArray(), + TotalRecordCount = specificItems.Length + }; + } + // Default list type = children var folder = item as Folder; @@ -157,16 +175,11 @@ namespace MediaBrowser.Api.UserLibrary folder = user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder(); } - if (request.Recursive || !string.IsNullOrEmpty(request.Ids)) + if (request.Recursive || !string.IsNullOrEmpty(request.Ids) || user == null) { return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); } - if (user == null) - { - return await folder.GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); - } - var userRoot = item as UserRootFolder; if (userRoot == null) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a5e6c1b92d..cc3a7e41f8 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1465,7 +1465,12 @@ namespace MediaBrowser.Server.Implementations.Library private void AddUserToQuery(InternalItemsQuery query, User user) { - if (query.AncestorIds.Length == 0 && !query.ParentId.HasValue && query.ChannelIds.Length == 0 && query.TopParentIds.Length == 0 && string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey)) + if (query.AncestorIds.Length == 0 && + !query.ParentId.HasValue && + query.ChannelIds.Length == 0 && + query.TopParentIds.Length == 0 && + string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey) + && query.ItemIds.Length == 0) { var userViews = _userviewManager().GetUserViews(new UserViewQuery { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index f04b9f50a4..2ac625ebc7 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3152,17 +3152,17 @@ namespace MediaBrowser.Server.Implementations.Persistence } if (query.ItemIds.Length > 0) { - var excludeIds = new List(); + var includeIds = new List(); var index = 0; foreach (var id in query.ItemIds) { - excludeIds.Add("Guid = @IncludeId" + index); + includeIds.Add("Guid = @IncludeId" + index); cmd.Parameters.Add(cmd, "@IncludeId" + index, DbType.Guid).Value = new Guid(id); index++; } - whereClauses.Add(string.Join(" OR ", excludeIds.ToArray())); + whereClauses.Add(string.Join(" OR ", includeIds.ToArray())); } if (query.ExcludeItemIds.Length > 0) { From 66a80ac6b9fee945631e2f1a0a4b6871b7465950 Mon Sep 17 00:00:00 2001 From: softworkz Date: Thu, 18 Aug 2016 22:05:54 +0200 Subject: [PATCH 172/220] EpisodeFileOrganizer: Improve error handling (alternate approach) Previously some methods were just returning null or empty values in case of encountered errors; as a consequence, the actual reason for failure was never written to the auto-organize log. Instead, only a generic message like "Unable to sort xxx because target path could not be determined." was displayed. After this change, the actual reason for failure will be saved to the auto-organize log or displayed in the UI (when completing the organize dialog). This information is very important for the user. Examples are "No permission", "Target folder not available", "Disk full", etc.. --- .../FileOrganization/EpisodeFileOrganizer.cs | 50 +++++++++++++------ .../FileOrganizationService.cs | 14 +++++- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 2109f8d59e..39992b65dd 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -43,13 +43,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _providerManager = providerManager; } - public Task OrganizeEpisodeFile(string path, CancellationToken cancellationToken) - { - var options = _config.GetAutoOrganizeOptions(); - - return OrganizeEpisodeFile(path, options, false, cancellationToken); - } - public async Task OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); @@ -63,6 +56,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization FileSize = new FileInfo(path).Length }; + try + { if (_libraryMonitor.IsPathLocked(path)) { result.Status = FileSortingStatus.Failure; @@ -148,6 +143,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + result.Status = FileSortingStatus.Failure; + result.StatusMessage = ex.Message; + } return result; } @@ -156,6 +157,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { var result = _organizationService.GetResult(request.ResultId); + try + { Series series = null; if (request.NewSeriesProviderIds.Count > 0) @@ -207,6 +210,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + result.Status = FileSortingStatus.Failure; + result.StatusMessage = ex.Message; + } return result; } @@ -263,16 +272,15 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var originalExtractedSeriesString = result.ExtractedName; + try + { // Proceed to sort the file var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - return; + throw new Exception(msg); } _logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath); @@ -347,6 +355,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } } + } + catch (Exception ex) + { + result.Status = FileSortingStatus.Failure; + result.StatusMessage = ex.Message; + _logger.Warn(ex.Message); + return; + } if (rememberCorrection) { @@ -505,7 +521,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } catch (Exception ex) { - var errorMsg = string.Format("Failed to move file from {0} to {1}", result.OriginalPath, result.TargetPath); + var errorMsg = string.Format("Failed to move file from {0} to {1}: {2}", result.OriginalPath, result.TargetPath, ex.Message); result.Status = FileSortingStatus.Failure; result.StatusMessage = errorMsg; @@ -616,7 +632,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); _logger.Warn(msg); - return null; + throw new Exception(msg); } var episodeName = episode.Name; @@ -715,6 +731,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var pattern = endingEpisodeNumber.HasValue ? options.MultiEpisodeNamePattern : options.EpisodeNamePattern; + if (string.IsNullOrWhiteSpace(pattern)) + { + throw new Exception("GetEpisodeFileName: Configured episode name pattern is empty!"); + } + var result = pattern.Replace("%sn", seriesName) .Replace("%s.n", seriesName.Replace(" ", ".")) .Replace("%s_n", seriesName.Replace(" ", "_")) @@ -759,8 +780,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization // There may be cases where reducing the title length may still not be sufficient to // stay below maxLength var msg = string.Format("Unable to generate an episode file name shorter than {0} characters to constrain to the max path limit", maxLength); - _logger.Warn(msg); - return string.Empty; + throw new Exception(msg); } return result; diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 60d515e120..9e16613e62 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -112,8 +112,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeOptions(), true, CancellationToken.None) + var organizeResult = await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeOptions(), true, CancellationToken.None) .ConfigureAwait(false); + + if (organizeResult.Status != FileSortingStatus.Success) + { + throw new Exception(result.StatusMessage); + } } public Task ClearLog() @@ -126,7 +131,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeWithCorrection(request, GetAutoOrganizeOptions(), CancellationToken.None).ConfigureAwait(false); + var result = await organizer.OrganizeWithCorrection(request, GetAutoOrganizeOptions(), CancellationToken.None).ConfigureAwait(false); + + if (result.Status != FileSortingStatus.Success) + { + throw new Exception(result.StatusMessage); + } } public QueryResult GetSmartMatchInfos(FileOrganizationResultQuery query) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 3d8e7a3d6d..6acb0783eb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1139,7 +1139,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var organize = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - var result = await organize.OrganizeEpisodeFile(path, CancellationToken.None).ConfigureAwait(false); + var result = await organize.OrganizeEpisodeFile(path, _config.GetAutoOrganizeOptions(), false, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { From 9ac5d5417bbc8141c9ce1e8af9e406c65e93119d Mon Sep 17 00:00:00 2001 From: softworkz Date: Tue, 16 Aug 2016 04:43:55 +0200 Subject: [PATCH 173/220] Add accurate bitrate reporting for ffmpeg jobs --- MediaBrowser.Api/ApiEntryPoint.cs | 8 ++++--- .../Playback/BaseStreamingService.cs | 24 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index bb9d2b8645..7c5f7cde40 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -192,13 +192,13 @@ namespace MediaBrowser.Api _activeTranscodingJobs.Add(job); - ReportTranscodingProgress(job, state, null, null, null, null); + ReportTranscodingProgress(job, state, null, null, null, null, null); return job; } } - public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded) + public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate) { var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null; @@ -208,6 +208,7 @@ namespace MediaBrowser.Api job.CompletionPercentage = percentComplete; job.TranscodingPositionTicks = ticks; job.BytesTranscoded = bytesTranscoded; + job.BitRate = bitRate; } var deviceId = state.Request.DeviceId; @@ -219,7 +220,7 @@ namespace MediaBrowser.Api _sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo { - Bitrate = state.TotalOutputBitrate, + Bitrate = bitRate ?? state.TotalOutputBitrate, AudioCodec = audioCodec, VideoCodec = videoCodec, Container = state.OutputContainer, @@ -694,6 +695,7 @@ namespace MediaBrowser.Api public long? BytesDownloaded { get; set; } public long? BytesTranscoded { get; set; } + public int? BitRate { get; set; } public long? TranscodingPositionTicks { get; set; } public long? DownloadPositionTicks { get; set; } diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ac967e1949..39fdc98f51 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1172,6 +1172,7 @@ namespace MediaBrowser.Api.Playback double? percent = null; TimeSpan? transcodingPosition = null; long? bytesTranscoded = null; + int? bitRate = null; var parts = line.Split(' '); @@ -1235,11 +1236,32 @@ namespace MediaBrowser.Api.Playback } } } + else if (part.StartsWith("bitrate=", StringComparison.OrdinalIgnoreCase)) + { + var rate = part.Split(new[] { '=' }, 2).Last(); + + int? scale = null; + if (rate.IndexOf("kbits/s", StringComparison.OrdinalIgnoreCase) != -1) + { + scale = 1024; + rate = rate.Replace("kbits/s", string.Empty, StringComparison.OrdinalIgnoreCase); + } + + if (scale.HasValue) + { + float val; + + if (float.TryParse(rate, NumberStyles.Any, UsCulture, out val)) + { + bitRate = (int)Math.Ceiling(val * scale.Value); + } + } + } } if (framerate.HasValue || percent.HasValue) { - ApiEntryPoint.Instance.ReportTranscodingProgress(transcodingJob, state, transcodingPosition, framerate, percent, bytesTranscoded); + ApiEntryPoint.Instance.ReportTranscodingProgress(transcodingJob, state, transcodingPosition, framerate, percent, bytesTranscoded, bitRate); } } From eb36b009cab033ab339c2cc521f3aeab0dc744fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 20:10:10 -0400 Subject: [PATCH 174/220] update stream start events --- .../Playback/BaseStreamingService.cs | 123 +++++++++++++++++- .../Encoder/MediaEncoder.cs | 12 ++ .../Configuration/ServerConfiguration.cs | 2 + .../ApplicationHost.cs | 3 + 4 files changed, 139 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index ac967e1949..a8992ccbb5 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -22,6 +22,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; namespace MediaBrowser.Api.Playback { @@ -69,6 +71,9 @@ namespace MediaBrowser.Api.Playback protected IZipClient ZipClient { get; private set; } protected IJsonSerializer JsonSerializer { get; private set; } + public static IServerApplicationHost AppHost; + public static IHttpClient HttpClient; + /// /// Initializes a new instance of the class. /// @@ -1112,6 +1117,7 @@ namespace MediaBrowser.Api.Playback } StartThrottler(state, transcodingJob); + ReportUsage(state); return transcodingJob; } @@ -1131,7 +1137,7 @@ namespace MediaBrowser.Api.Playback return state.InputProtocol == MediaProtocol.File && state.RunTimeTicks.HasValue && state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && - state.IsInputVideo && + state.IsInputVideo && state.VideoType == VideoType.VideoFile && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(GetVideoEncoder(state), "libx264", StringComparison.OrdinalIgnoreCase); @@ -2197,6 +2203,121 @@ namespace MediaBrowser.Api.Playback } } + private async void ReportUsage(StreamState state) + { + try + { + await ReportUsageInternal(state).ConfigureAwait(false); + } + catch + { + + } + } + + private Task ReportUsageInternal(StreamState state) + { + if (!ServerConfigurationManager.Configuration.EnableAnonymousUsageReporting) + { + return Task.FromResult(true); + } + + if (!string.Equals(MediaEncoder.EncoderLocationType, "Default", StringComparison.OrdinalIgnoreCase)) + { + return Task.FromResult(true); + } + + var dict = new Dictionary(); + + var outputAudio = GetAudioEncoder(state); + if (!string.IsNullOrWhiteSpace(outputAudio)) + { + dict["outputAudio"] = outputAudio; + } + + var outputVideo = GetVideoEncoder(state); + if (!string.IsNullOrWhiteSpace(outputVideo)) + { + dict["outputVideo"] = outputVideo; + } + + if (ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase) && + ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return Task.FromResult(true); + } + + dict["id"] = AppHost.SystemId; + dict["type"] = state.VideoRequest == null ? "Audio" : "Video"; + + var audioStream = state.AudioStream; + if (audioStream != null && !string.IsNullOrWhiteSpace(audioStream.Codec)) + { + dict["inputAudio"] = audioStream.Codec; + } + + var videoStream = state.VideoStream; + if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec)) + { + dict["inputVideo"] = videoStream.Codec; + } + + var cert = GetType().Assembly.GetModules().First().GetSignerCertificate(); + if (cert != null) + { + dict["assemblySig"] = cert.GetCertHashString(); + dict["certSubject"] = cert.Subject ?? string.Empty; + dict["certIssuer"] = cert.Issuer ?? string.Empty; + } + else + { + return Task.FromResult(true); + } + + if (state.SupportedAudioCodecs.Count > 0) + { + dict["supportedAudioCodecs"] = string.Join(",", state.SupportedAudioCodecs.ToArray()); + } + + var auth = AuthorizationContext.GetAuthorizationInfo(Request); + + dict["appName"] = auth.Client ?? string.Empty; + dict["appVersion"] = auth.Version ?? string.Empty; + dict["device"] = auth.Device ?? string.Empty; + dict["deviceId"] = auth.DeviceId ?? string.Empty; + dict["context"] = "streaming"; + + Logger.Info(JsonSerializer.SerializeToString(dict)); + if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); + list.Add(outputAudio); + ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); + } + + if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); + list.Add(outputVideo); + ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray(); + } + + ServerConfigurationManager.SaveConfiguration(); + + //Logger.Info(JsonSerializer.SerializeToString(dict)); + var options = new HttpRequestOptions() + { + Url = "https://mb3admin.com/admin/service/transcoding/report", + CancellationToken = CancellationToken.None, + LogRequest = false, + LogErrors = false + }; + options.RequestContent = JsonSerializer.SerializeToString(dict); + options.RequestContentType = "application/json"; + + return HttpClient.Post(options); + } + /// /// Adds the dlna headers. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index e90f6bdc36..f488be11a7 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -123,10 +123,22 @@ namespace MediaBrowser.MediaEncoding.Encoder return "System"; } + if (IsDefaultPath(FFMpegPath)) + { + return "Default"; + } + return "Custom"; } } + private bool IsDefaultPath(string path) + { + var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410"); + + return FileSystem.ContainsSubPath(parentPath, path); + } + private bool IsSystemInstalledPath(string path) { if (path.IndexOf("/", StringComparison.Ordinal) == -1 && path.IndexOf("\\", StringComparison.Ordinal) == -1) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 303ba1acf7..63d452bcee 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -202,6 +202,7 @@ namespace MediaBrowser.Model.Configuration public bool DisplaySpecialsWithinSeasons { get; set; } public bool DisplayCollectionsView { get; set; } public string[] LocalNetworkAddresses { get; set; } + public string[] CodecsUsed { get; set; } /// /// Initializes a new instance of the class. @@ -210,6 +211,7 @@ namespace MediaBrowser.Model.Configuration { LocalNetworkAddresses = new string[] { }; Migrations = new string[] { }; + CodecsUsed = new string[] { }; SqliteCacheSize = 0; EnableLocalizedGuids = true; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 9eb8a47366..8cb1d4f0db 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -101,6 +101,7 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Api.Playback; using MediaBrowser.Common.Implementations.Updates; namespace MediaBrowser.Server.Startup.Common @@ -766,6 +767,8 @@ namespace MediaBrowser.Server.Startup.Common BaseItem.CollectionManager = CollectionManager; BaseItem.MediaSourceManager = MediaSourceManager; CollectionFolder.XmlSerializer = XmlSerializer; + BaseStreamingService.AppHost = this; + BaseStreamingService.HttpClient = HttpClient; } /// From dea08933f1e645f364520a01806aaa57e8e61b71 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Aug 2016 23:57:36 -0400 Subject: [PATCH 175/220] update xmltv lib --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- .../MediaBrowser.Server.Implementations.csproj | 2 +- MediaBrowser.Server.Implementations/packages.config | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index fa4be8fc24..f52505c04b 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -2309,7 +2309,7 @@ namespace MediaBrowser.Api.Playback dict["deviceId"] = auth.DeviceId ?? string.Empty; dict["context"] = "streaming"; - Logger.Info(JsonSerializer.SerializeToString(dict)); + //Logger.Info(JsonSerializer.SerializeToString(dict)); if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList(); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 442465430d..7fa9ee32c2 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,7 +46,7 @@ ..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll - ..\packages\Emby.XmlTv.1.0.0.55\lib\net45\Emby.XmlTv.dll + ..\packages\Emby.XmlTv.1.0.0.56\lib\net45\Emby.XmlTv.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index bac5a7c5d0..746dc7f62e 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,7 +1,7 @@  - + From 719ad3971e2fdf51341f388bb1f3cc572d70219a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 01:58:35 -0400 Subject: [PATCH 176/220] update genre validator --- .../Persistence/IItemRepository.cs | 4 +- .../Encoder/AudioEncoder.cs | 5 ++- .../Validators/GameGenresPostScanTask.cs | 7 +++- .../Library/Validators/GameGenresValidator.cs | 21 +++++----- .../Library/Validators/GenresPostScanTask.cs | 7 +++- .../Library/Validators/GenresValidator.cs | 21 +++++----- .../Validators/MusicGenresPostScanTask.cs | 7 +++- .../Validators/MusicGenresValidator.cs | 21 +++++----- .../Persistence/SqliteItemRepository.cs | 39 +++++++++++++++++-- 9 files changed, 87 insertions(+), 45 deletions(-) diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index edfec902b8..87937869d5 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -171,8 +171,10 @@ namespace MediaBrowser.Controller.Persistence QueryResult> GetAlbumArtists(InternalItemsQuery query); QueryResult> GetAllArtists(InternalItemsQuery query); + List GetGameGenreNames(); + List GetMusicGenreNames(); List GetStudioNames(); - + List GetGenreNames(); List GetAllArtistNames(); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs index cd1575fa58..f42582270f 100644 --- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs @@ -51,7 +51,10 @@ namespace MediaBrowser.MediaEncoding.Encoder var metadata = string.Empty; var vn = string.Empty; - if (!string.IsNullOrWhiteSpace(state.AlbumCoverPath)) + var hasArt = !string.IsNullOrWhiteSpace(state.AlbumCoverPath); + hasArt = false; + + if (hasArt) { albumCoverInput = " -i \"" + state.AlbumCoverPath + "\""; mapArgs = " -map 0:a -map 1:v -c:v copy"; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs index 8be2e436fe..f3891180e2 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -16,16 +17,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. /// The logger. - public GameGenresPostScanTask(ILibraryManager libraryManager, ILogger logger) + public GameGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -36,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return new GameGenresValidator(_libraryManager, _logger).Run(progress, cancellationToken); + return new GameGenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index 72864790b8..b06c0b3b9b 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -19,11 +20,13 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// The _logger /// private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; - public GameGenresValidator(ILibraryManager libraryManager, ILogger logger) + public GameGenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -34,21 +37,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.GetGameGenres(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(Game).Name } - }) - .Items - .Select(i => i.Item1) - .ToList(); + var names = _itemRepo.GetGameGenreNames(); var numComplete = 0; - var count = items.Count; + var count = names.Count; - foreach (var item in items) + foreach (var name in names) { try { + var item = _libraryManager.GetGameGenre(name); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -58,7 +57,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, item.Name); + _logger.ErrorException("Error refreshing {0}", ex, name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs index a1c34676c8..ed2429769c 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs @@ -2,6 +2,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Library.Validators @@ -13,16 +14,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. /// The logger. - public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger) + public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -33,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return new GenresValidator(_libraryManager, _logger).Run(progress, cancellationToken); + return new GenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 6a62d7fe47..f35bb51363 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -6,6 +6,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -15,16 +16,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// The _library manager /// private readonly ILibraryManager _libraryManager; + private readonly IItemRepository _itemRepo; /// /// The _logger /// private readonly ILogger _logger; - public GenresValidator(ILibraryManager libraryManager, ILogger logger) + public GenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -35,21 +38,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.GetGenres(new InternalItemsQuery - { - ExcludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Game).Name } - }) - .Items - .Select(i => i.Item1) - .ToList(); + var names = _itemRepo.GetGenreNames(); var numComplete = 0; - var count = items.Count; + var count = names.Count; - foreach (var item in items) + foreach (var name in names) { try { + var item = _libraryManager.GetGenre(name); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -59,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, item.Name); + _logger.ErrorException("Error refreshing {0}", ex, name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs index dbcab0832a..777532ff87 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -16,16 +17,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; /// /// Initializes a new instance of the class. /// /// The library manager. /// The logger. - public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger) + public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -36,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return new MusicGenresValidator(_libraryManager, _logger).Run(progress, cancellationToken); + return new MusicGenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken); } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 2668d84e95..2be99f106e 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Persistence; namespace MediaBrowser.Server.Implementations.Library.Validators { @@ -20,11 +21,13 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// The _logger /// private readonly ILogger _logger; + private readonly IItemRepository _itemRepo; - public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger) + public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo) { _libraryManager = libraryManager; _logger = logger; + _itemRepo = itemRepo; } /// @@ -35,21 +38,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var items = _libraryManager.GetMusicGenres(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name } - }) - .Items - .Select(i => i.Item1) - .ToList(); + var names = _itemRepo.GetMusicGenreNames(); var numComplete = 0; - var count = items.Count; + var count = names.Count; - foreach (var item in items) + foreach (var name in names) { try { + var item = _libraryManager.GetMusicGenre(name); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -59,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } catch (Exception ex) { - _logger.ErrorException("Error refreshing {0}", ex, item.Name); + _logger.ErrorException("Error refreshing {0}", ex, name); } numComplete++; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 2ac625ebc7..c3eee6d354 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -3882,18 +3882,36 @@ namespace MediaBrowser.Server.Implementations.Persistence public List GetStudioNames() { - return GetItemValueNames(new[] { 3 }); + return GetItemValueNames(new[] { 3 }, new List(), new List()); } public List GetAllArtistNames() { - return GetItemValueNames(new[] { 0, 1 }); + return GetItemValueNames(new[] { 0, 1 }, new List(), new List()); } - private List GetItemValueNames(int[] itemValueTypes) + public List GetMusicGenreNames() + { + return GetItemValueNames(new[] { 2 }, new List { "Audio", "MusicVideo", "MusicAlbum", "MusicArtist" }, new List()); + } + + public List GetGameGenreNames() + { + return GetItemValueNames(new[] { 2 }, new List { "Game" }, new List()); + } + + public List GetGenreNames() + { + return GetItemValueNames(new[] { 2 }, new List(), new List { "Audio", "MusicVideo", "MusicAlbum", "MusicArtist", "Game", "GameSystem" }); + } + + private List GetItemValueNames(int[] itemValueTypes, List withItemTypes, List excludeItemTypes) { CheckDisposed(); + withItemTypes = withItemTypes.SelectMany(MapIncludeItemTypes).ToList(); + excludeItemTypes = excludeItemTypes.SelectMany(MapIncludeItemTypes).ToList(); + var now = DateTime.UtcNow; var typeClause = itemValueTypes.Length == 1 ? @@ -3904,7 +3922,20 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "Select Value From ItemValues where " + typeClause + " Group By CleanValue"; + cmd.CommandText = "Select Value From ItemValues where " + typeClause; + + if (withItemTypes.Count > 0) + { + var typeString = string.Join(",", withItemTypes.Select(i => "'" + i + "'").ToArray()); + cmd.CommandText += " AND ItemId In (select guid from typedbaseitems where type in (" + typeString + "))"; + } + if (excludeItemTypes.Count > 0) + { + var typeString = string.Join(",", excludeItemTypes.Select(i => "'" + i + "'").ToArray()); + cmd.CommandText += " AND ItemId not In (select guid from typedbaseitems where type in (" + typeString + "))"; + } + + cmd.CommandText += " Group By CleanValue"; var commandBehavior = CommandBehavior.SequentialAccess | CommandBehavior.SingleResult; From 8f59f39873be3ee54aac1403d561031c459f4845 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 02:22:18 -0400 Subject: [PATCH 177/220] update default dlna profile --- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 20 +++++++++++++++---- MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs | 2 ++ MediaBrowser.Dlna/Profiles/DirectTvProfile.cs | 2 ++ .../Profiles/Foobar2000Profile.cs | 4 +++- MediaBrowser.Dlna/Profiles/LgTvProfile.cs | 2 ++ .../Profiles/LinksysDMA2100Profile.cs | 2 ++ .../Profiles/MediaMonkeyProfile.cs | 2 ++ .../Profiles/PopcornHourProfile.cs | 2 ++ .../Profiles/SonyBlurayPlayer2013Profile.cs | 2 ++ MediaBrowser.Dlna/Profiles/Xml/Default.xml | 10 +++++++--- 10 files changed, 40 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index 76797c0e3a..e4f6d337fe 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -65,14 +65,26 @@ namespace MediaBrowser.Dlna.Profiles { new DirectPlayProfile { - Container = "mp3,wma", - Type = DlnaProfileType.Audio + Container = "m4v,ts,mkv,avi,mpg,mpeg,mp4", + VideoCodec = "h264", + AudioCodec = "aac,mp3,ac3", + Type = DlnaProfileType.Video }, new DirectPlayProfile { - Container = "avi,mp4", - Type = DlnaProfileType.Video + Container = "mp3,wma,aac,wav", + Type = DlnaProfileType.Audio + } + }; + + ResponseProfiles = new[] + { + new ResponseProfile + { + Container = "m4v", + Type = DlnaProfileType.Video, + MimeType = "video/mp4" } }; } diff --git a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs index f8451bdfd8..fb498c4ce4 100644 --- a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs @@ -24,6 +24,8 @@ namespace MediaBrowser.Dlna.Profiles Type = DlnaProfileType.Audio }, }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/DirectTvProfile.cs b/MediaBrowser.Dlna/Profiles/DirectTvProfile.cs index 585f8652e6..c2a007a31a 100644 --- a/MediaBrowser.Dlna/Profiles/DirectTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DirectTvProfile.cs @@ -112,6 +112,8 @@ namespace MediaBrowser.Dlna.Profiles } } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs index 45cbbef6cb..2c1919c00e 100644 --- a/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "foobar2000"; SupportedMediaTypes = "Audio"; - + Identification = new DeviceIdentification { FriendlyName = @"foobar", @@ -70,6 +70,8 @@ namespace MediaBrowser.Dlna.Profiles Type = DlnaProfileType.Audio } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs index ab9a6a51ff..af81fabe43 100644 --- a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs @@ -198,6 +198,8 @@ namespace MediaBrowser.Dlna.Profiles Method = SubtitleDeliveryMethod.External } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs index da00d9e86e..2488cf5423 100644 --- a/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs +++ b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs @@ -30,6 +30,8 @@ namespace MediaBrowser.Dlna.Profiles Type = DlnaProfileType.Video } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/MediaMonkeyProfile.cs b/MediaBrowser.Dlna/Profiles/MediaMonkeyProfile.cs index 7163252db2..eef847852d 100644 --- a/MediaBrowser.Dlna/Profiles/MediaMonkeyProfile.cs +++ b/MediaBrowser.Dlna/Profiles/MediaMonkeyProfile.cs @@ -70,6 +70,8 @@ namespace MediaBrowser.Dlna.Profiles Type = DlnaProfileType.Audio } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs b/MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs index c98609393a..0e1210afbb 100644 --- a/MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs +++ b/MediaBrowser.Dlna/Profiles/PopcornHourProfile.cs @@ -200,6 +200,8 @@ namespace MediaBrowser.Dlna.Profiles } } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs index dbade81705..cfc793c01e 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs @@ -181,6 +181,8 @@ namespace MediaBrowser.Dlna.Profiles } } }; + + ResponseProfiles = new ResponseProfile[] { }; } } } diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index 8fae686325..732b5baded 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -29,8 +29,8 @@ false - - + + @@ -39,6 +39,10 @@ - + + + + + \ No newline at end of file From 6e01e277d41c9a8505cfdea7f65e95de5a72bf03 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 13:43:16 -0400 Subject: [PATCH 178/220] update new episode creation --- MediaBrowser.Providers/TV/DummySeasonProvider.cs | 4 +++- .../Library/Resolvers/TV/EpisodeResolver.cs | 3 +++ .../Library/Resolvers/TV/SeasonResolver.cs | 6 ++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs index baea0a06d2..fe0ad78be3 100644 --- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs +++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs @@ -112,7 +112,9 @@ namespace MediaBrowser.Providers.TV IndexNumber = seasonNumber, Id = _libraryManager.GetNewItemId((series.Id + (seasonNumber ?? -1).ToString(_usCulture) + seasonName), typeof(Season)), IsVirtualItem = isVirtualItem, - SeriesId = series.Id + SeriesId = series.Id, + SeriesName = series.Name, + SeriesSortName = series.SortName }; season.SetParent(series); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 2f940eb1d8..6edc4a009e 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -56,10 +56,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV if (series != null) { episode.SeriesId = series.Id; + episode.SeriesName = series.Name; + episode.SeriesSortName = series.SortName; } if (season != null) { episode.SeasonId = season.Id; + episode.SeasonName = season.Name; } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index eeac1345e8..fc49297482 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -43,9 +43,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV var season = new Season { IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber, - SeriesId = series.Id + SeriesId = series.Id, + SeriesSortName = series.SortName, + SeriesName = series.Name }; - + if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0) { season.Name = _config.Configuration.SeasonZeroDisplayName; From f5ad9186ec3730b92cfdf06947ae6a85912867dc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 14:44:58 -0400 Subject: [PATCH 179/220] update boxset resolver --- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 2 +- .../Library/Resolvers/Movies/MovieResolver.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index caf440a83f..6d5278f1fe 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Controller.Entities.Movies { if (IsLegacyBoxSet) { - return base.LoadChildren(); + return base.GetNonCachedChildren(directoryService); } return new List(); } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 37d1e163f9..6558407538 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -48,6 +48,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies string collectionType, IDirectoryService directoryService) { + if (parent != null && parent.Path != null && parent.Path.IndexOf("disney", StringComparison.OrdinalIgnoreCase) != -1) + { + var b = true; + var a = b; + } + var result = ResolveMultipleInternal(parent, files, collectionType, directoryService); if (result != null) @@ -197,6 +203,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies /// Video. protected override Video Resolve(ItemResolveArgs args) { + if (args.Path != null && args.Path.IndexOf("disney", StringComparison.OrdinalIgnoreCase) != -1) + { + var b = true; + var a = b; + } + var collectionType = args.GetCollectionType(); if (IsInvalid(args.Parent, collectionType)) From d1da8f4449580dd642ae71580e9c40cab8aedbe3 Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 19 Aug 2016 14:51:40 -0400 Subject: [PATCH 180/220] update mac project --- MediaBrowser.Server.Mac/Emby.Server.Mac.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 9422b7fa36..104923f8ee 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -1017,6 +1017,9 @@ Resources\dashboard-ui\bower_components\emby-apiclient\apiclient.js + + Resources\dashboard-ui\bower_components\emby-apiclient\appstorage-cache.js + Resources\dashboard-ui\bower_components\emby-apiclient\appstorage-localstorage.js @@ -3711,6 +3714,9 @@ Resources\dashboard-ui\components\navdrawer\navdrawer.js + + Resources\dashboard-ui\components\syncjoblist\syncjoblist.js + Resources\dashboard-ui\components\tvproviders\schedulesdirect.js From f8b76758e67acc1dec673a03589e847fa561919b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 18:56:32 -0400 Subject: [PATCH 181/220] remove fingerprintjs --- ...MediaBrowser.Server.Implementations.csproj | 1 + .../Sync/SyncNotificationEntryPoint.cs | 48 +++++++++++++++++++ .../Api/DashboardService.cs | 2 - 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7fa9ee32c2..b4fd7b279f 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -271,6 +271,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs new file mode 100644 index 0000000000..7017b422ee --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs @@ -0,0 +1,48 @@ +using System.Threading; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Sync; + +namespace MediaBrowser.Server.Implementations.Sync +{ + public class SyncNotificationEntryPoint : IServerEntryPoint + { + private readonly ISessionManager _sessionManager; + private readonly ISyncManager _syncManager; + + public SyncNotificationEntryPoint(ISyncManager syncManager, ISessionManager sessionManager) + { + _syncManager = syncManager; + _sessionManager = sessionManager; + } + + public void Run() + { + _syncManager.SyncJobItemUpdated += _syncManager_SyncJobItemUpdated; + } + + private async void _syncManager_SyncJobItemUpdated(object sender, GenericEventArgs e) + { + var item = e.Argument; + + if (item.Status == SyncJobItemStatus.ReadyToTransfer) + { + try + { + await _sessionManager.SendMessageToUserDeviceSessions(item.TargetId, "SyncJobItemReady", item, CancellationToken.None).ConfigureAwait(false); + } + catch + { + + } + } + } + + public void Dispose() + { + _syncManager.SyncJobItemUpdated -= _syncManager_SyncJobItemUpdated; + } + } +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 601ebfba73..12e1eb5eaf 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -382,8 +382,6 @@ namespace MediaBrowser.WebDashboard.Api } _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true); - //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "flash"), true); - //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "specs"), true); DeleteCryptoFiles(Path.Combine(bowerPath, "cryptojslib", "components")); From 751febc1de65c9f2811deca66d093503968dd514 Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 19 Aug 2016 03:00:04 +0200 Subject: [PATCH 182/220] Auto-Organize: Async operation and instant feedback UI (reworked) This commit includes changes to enable and stabilize asyncronous operation in the auto-organize area. Here are the key points: - The auto-organize correction dialog is now closed (almost) instantly. This means that the user does not have to wait until the file copy/move operation is completed in order to continue. (even with local HDs the copy/move process can take several minutes or even much longer with network destination). - This commit also implements locking of files to be organized in order to prevent parallel processing of the same item. In effect, there can be 2 or more manual organization operations active even while the normal auto-organization task is running without causing any problems - The items that are currently being processed are indicated as such in the log with an orange color and a spinner graphic - The client display is refreshed through websocket messages - A side effect of this is that other clients showing the auto-organize log at the same time are always up-to-date as well --- .../Library/FileOrganizationService.cs | 14 +-- .../IFileOrganizationService.cs | 24 ++++- .../Session/ISessionManager.cs | 10 ++ .../FileOrganizationResult.cs | 6 ++ .../FileOrganization/EpisodeFileOrganizer.cs | 16 +++ .../FileOrganizationNotifier.cs | 68 ++++++++++++ .../FileOrganizationService.cs | 100 ++++++++++++++++-- ...MediaBrowser.Server.Implementations.csproj | 1 + .../Session/SessionManager.cs | 21 ++++ .../MediaBrowser.WebDashboard.csproj | 3 + MediaBrowser.sln | 5 +- 11 files changed, 251 insertions(+), 17 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 0ed08a8607..ca391bef08 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -154,9 +154,12 @@ namespace MediaBrowser.Api.Library public void Post(PerformOrganization request) { + // Don't await this var task = _iFileOrganizationService.PerformOrganization(request.Id); - Task.WaitAll(task); + // Async processing (close dialog early instead of waiting until the file has been copied) + // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display + task.Wait(2000); } public void Post(OrganizeEpisode request) @@ -168,6 +171,7 @@ namespace MediaBrowser.Api.Library dicNewProviderIds = request.NewSeriesProviderIds; } + // Don't await this var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest { EndingEpisodeNumber = request.EndingEpisodeNumber, @@ -182,11 +186,9 @@ namespace MediaBrowser.Api.Library TargetFolder = request.TargetFolder }); - // For async processing (close dialog early instead of waiting until the file has been copied) - //var tasks = new Task[] { task }; - //Task.WaitAll(tasks, 8000); - - Task.WaitAll(task); + // Async processing (close dialog early instead of waiting until the file has been copied) + // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display + task.Wait(2000); } public object Get(GetSmartMatchInfos request) diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs index daa670d836..9a5b96a241 100644 --- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs +++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs @@ -1,5 +1,7 @@ -using MediaBrowser.Model.FileOrganization; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Querying; +using System; using System.Threading; using System.Threading.Tasks; @@ -7,6 +9,11 @@ namespace MediaBrowser.Controller.FileOrganization { public interface IFileOrganizationService { + event EventHandler> ItemAdded; + event EventHandler> ItemUpdated; + event EventHandler> ItemRemoved; + event EventHandler LogReset; + /// /// Processes the new files. /// @@ -81,5 +88,20 @@ namespace MediaBrowser.Controller.FileOrganization /// Item name. /// The match string to delete. void DeleteSmartMatchEntry(string ItemName, string matchString); + + /// + /// Attempts to add a an item to the list of currently processed items. + /// + /// The result item. + /// Passing true will notify the client to reload all items, otherwise only a single item will be refreshed. + /// True if the item was added, False if the item is already contained in the list. + bool AddToInProgressList(FileOrganizationResult result, bool fullClientRefresh); + + /// + /// Removes an item from the list of currently processed items. + /// + /// The result item. + /// True if the item was removed, False if the item was not contained in the list. + bool RemoveFromInprogressList(FileOrganizationResult result); } } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 6659d15530..e63fc60e1a 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -171,6 +171,16 @@ namespace MediaBrowser.Controller.Session /// Task. Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken); + /// + /// Sends the message to admin sessions. + /// + /// + /// The name. + /// The data. + /// The cancellation token. + /// Task. + Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken); + /// /// Sends the message to user sessions. /// diff --git a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs index ef9d0ca2ae..caf99183dc 100644 --- a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs +++ b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs @@ -95,6 +95,12 @@ namespace MediaBrowser.Model.FileOrganization /// The size of the file. public long FileSize { get; set; } + /// + /// Indicates if the item is currently being processed. + /// + /// Runtime property not persisted to the store. + public bool IsInProgress { get; set; } + public FileOrganizationResult() { DuplicatePaths = new List(); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 39992b65dd..5e01666a9a 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -272,6 +272,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var originalExtractedSeriesString = result.ExtractedName; + bool isNew = string.IsNullOrWhiteSpace(result.Id); + + if (isNew) + { + await _organizationService.SaveResult(result, cancellationToken); + } + + if (!_organizationService.AddToInProgressList(result, isNew)) + { + throw new Exception("File is currently processed otherwise. Please try again later."); + } + try { // Proceed to sort the file @@ -363,6 +375,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _logger.Warn(ex.Message); return; } + finally + { + _organizationService.RemoveFromInprogressList(result); + } if (rememberCorrection) { diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs new file mode 100644 index 0000000000..38b90647c1 --- /dev/null +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs @@ -0,0 +1,68 @@ +using MediaBrowser.Controller.FileOrganization; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.FileOrganization; +using MediaBrowser.Controller.Session; +using System.Threading; + +namespace MediaBrowser.Server.Implementations.FileOrganization +{ + /// + /// Class SessionInfoWebSocketListener + /// + class FileOrganizationNotifier : IServerEntryPoint + { + private readonly IFileOrganizationService _organizationService; + private readonly ISessionManager _sessionManager; + + public FileOrganizationNotifier(ILogger logger, IFileOrganizationService organizationService, ISessionManager sessionManager) + { + _organizationService = organizationService; + _sessionManager = sessionManager; + } + + public void Run() + { + _organizationService.ItemAdded += _organizationService_ItemAdded; + _organizationService.ItemRemoved += _organizationService_ItemRemoved; + _organizationService.ItemUpdated += _organizationService_ItemUpdated; + _organizationService.LogReset += _organizationService_LogReset; + } + + private void _organizationService_LogReset(object sender, EventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + private void _organizationService_ItemUpdated(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", e.Argument, CancellationToken.None); + } + + private void _organizationService_ItemRemoved(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + private void _organizationService_ItemAdded(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + public void Dispose() + { + _organizationService.ItemAdded -= _organizationService_ItemAdded; + _organizationService.ItemRemoved -= _organizationService_ItemRemoved; + _organizationService.ItemUpdated -= _organizationService_ItemUpdated; + _organizationService.LogReset -= _organizationService_LogReset; + } + + + } +} diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 9e16613e62..a42eba6cae 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -3,16 +3,21 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; +using System.Collections.Concurrent; using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Events; +using MediaBrowser.Common.Events; namespace MediaBrowser.Server.Implementations.FileOrganization { @@ -26,6 +31,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly IProviderManager _providerManager; + private readonly ConcurrentDictionary _inProgressItemIds = new ConcurrentDictionary(); + + public event EventHandler> ItemAdded; + public event EventHandler> ItemUpdated; + public event EventHandler> ItemRemoved; + public event EventHandler LogReset; public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager) { @@ -58,12 +69,26 @@ namespace MediaBrowser.Server.Implementations.FileOrganization public QueryResult GetResults(FileOrganizationResultQuery query) { - return _repo.GetResults(query); + var results = _repo.GetResults(query); + + foreach (var result in results.Items) + { + result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id); + } + + return results; } public FileOrganizationResult GetResult(string id) { - return _repo.GetResult(id); + var result = _repo.GetResult(id); + + if (result != null) + { + result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id); + } + + return result; } public FileOrganizationResult GetResultBySourcePath(string path) @@ -78,11 +103,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return GetResult(id); } - public Task DeleteOriginalFile(string resultId) + public async Task DeleteOriginalFile(string resultId) { var result = _repo.GetResult(resultId); _logger.Info("Requested to delete {0}", result.OriginalPath); + + if (!AddToInProgressList(result, false)) + { + throw new Exception("Path is currently processed otherwise. Please try again later."); + } + try { _fileSystem.DeleteFile(result.OriginalPath); @@ -91,8 +122,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { _logger.ErrorException("Error deleting {0}", ex, result.OriginalPath); } + finally + { + RemoveFromInprogressList(result); + } - return _repo.Delete(resultId); + await _repo.Delete(resultId); + + EventHelper.FireEventIfNotNull(ItemRemoved, this, new GenericEventArgs(result), _logger); } private AutoOrganizeOptions GetAutoOrganizeOptions() @@ -121,9 +158,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - public Task ClearLog() + public async Task ClearLog() { - return _repo.DeleteAll(); + await _repo.DeleteAll(); + EventHelper.FireEventIfNotNull(LogReset, this, EventArgs.Empty, _logger); } public async Task PerformEpisodeOrganization(EpisodeFileOrganizationRequest request) @@ -189,5 +227,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _config.SaveAutoOrganizeOptions(options); } } + + /// + /// Attempts to add a an item to the list of currently processed items. + /// + /// The result item. + /// Passing true will notify the client to reload all items, otherwise only a single item will be refreshed. + /// True if the item was added, False if the item is already contained in the list. + public bool AddToInProgressList(FileOrganizationResult result, bool isNewItem) + { + if (string.IsNullOrWhiteSpace(result.Id)) + { + result.Id = result.OriginalPath.GetMD5().ToString("N"); + } + + if (!_inProgressItemIds.TryAdd(result.Id, false)) + { + return false; + } + + result.IsInProgress = true; + + if (isNewItem) + { + EventHelper.FireEventIfNotNull(ItemAdded, this, new GenericEventArgs(result), _logger); + } + else + { + EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs(result), _logger); + } + + return true; + } + + /// + /// Removes an item from the list of currently processed items. + /// + /// The result item. + /// True if the item was removed, False if the item was not contained in the list. + public bool RemoveFromInprogressList(FileOrganizationResult result) + { + bool itemValue; + var retval = _inProgressItemIds.TryRemove(result.Id, out itemValue); + + result.IsInProgress = false; + + EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs(result), _logger); + + return retval; + } + } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7fa9ee32c2..72324b061c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -149,6 +149,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index f495e557a3..9d07f2169e 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1869,6 +1869,27 @@ namespace MediaBrowser.Server.Implementations.Session return GetSessionByAuthenticationToken(info, deviceId, remoteEndpoint, null); } + public Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken) + { + // TODO: How to identify admin sessions? + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); + + var tasks = sessions.Select(session => Task.Run(async () => + { + try + { + await session.SessionController.SendMessage(name, data, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); + } + + }, cancellationToken)); + + return Task.WhenAll(tasks); + } + public Task SendMessageToUserSessions(string userId, string name, T data, CancellationToken cancellationToken) { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 61facf8ec4..706b78a8f3 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -182,6 +182,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c6068f5364..90b318492f 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject @@ -65,9 +65,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms From acd60f1d85f88e19b114ba0cc59af3fb98589064 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Aug 2016 14:43:13 -0400 Subject: [PATCH 183/220] update admin session filter --- .../Session/ISessionManager.cs | 6 +---- .../EntryPoints/RecordingNotifier.cs | 17 ++++++-------- .../EntryPoints/ServerEventNotifier.cs | 3 ++- .../Session/SessionManager.cs | 22 ++++--------------- MediaBrowser.sln | 5 ++++- 5 files changed, 18 insertions(+), 35 deletions(-) diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index e63fc60e1a..3871952450 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -185,12 +185,8 @@ namespace MediaBrowser.Controller.Session /// Sends the message to user sessions. /// /// - /// The user identifier. - /// The name. - /// The data. - /// The cancellation token. /// Task. - Task SendMessageToUserSessions(string userId, string name, T data, CancellationToken cancellationToken); + Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken); /// /// Sends the message to user device sessions. diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs index 620eea774e..414fda400b 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -54,18 +54,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private async void SendMessage(string name, TimerEventInfo info) { - var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).ToList(); + var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList(); - foreach (var user in users) + try { - try - { - await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, info, CancellationToken.None); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending message", ex); - } + await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs index b5624625f2..3ea8417f86 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -11,6 +11,7 @@ using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Events; using MediaBrowser.Model.Sync; using System; +using System.Collections.Generic; using System.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints @@ -164,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private async void SendMessageToUserSession(User user, string name, T data) { - await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, data, CancellationToken.None); + await _sessionManager.SendMessageToUserSessions(new List { user.Id.ToString("N") }, name, data, CancellationToken.None); } /// diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 9d07f2169e..b21fcddd41 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1871,29 +1871,15 @@ namespace MediaBrowser.Server.Implementations.Session public Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken) { - // TODO: How to identify admin sessions? - var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); + var adminUserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id.ToString("N")).ToList(); - var tasks = sessions.Select(session => Task.Run(async () => - { - try - { - await session.SessionController.SendMessage(name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending message", ex); - } - - }, cancellationToken)); - - return Task.WhenAll(tasks); + return SendMessageToUserSessions(adminUserIds, name, data, cancellationToken); } - public Task SendMessageToUserSessions(string userId, string name, T data, + public Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken) { - var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && i.ContainsUser(userId)).ToList(); + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && userIds.Any(i.ContainsUser)).ToList(); var tasks = sessions.Select(session => Task.Run(async () => { diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 90b318492f..c6068f5364 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject @@ -65,6 +65,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms From ce637a27938f603cb16bdd255735198abade6b96 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Aug 2016 17:58:44 -0400 Subject: [PATCH 184/220] add null check when updating images --- .../Persistence/SqliteItemRepository.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c3eee6d354..b9befb531e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -4286,6 +4286,12 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var image in images) { + if (string.IsNullOrWhiteSpace(image.Path)) + { + // Invalid + continue; + } + _saveImagesCommand.GetParameter(0).Value = itemId; _saveImagesCommand.GetParameter(1).Value = image.Type; _saveImagesCommand.GetParameter(2).Value = image.Path; From 2a0b2f7e34b8e375055b4282f5bc838e150c76a3 Mon Sep 17 00:00:00 2001 From: softworkz Date: Mon, 15 Aug 2016 05:09:08 +0200 Subject: [PATCH 185/220] Remove jquery from autoorganize scripts --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 706b78a8f3..ba98f78e68 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -194,6 +194,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 9f7dbec0db461fe416d825b483d475f476c9d42d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Aug 2016 02:59:36 -0400 Subject: [PATCH 186/220] use unified theme media player --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index ba98f78e68..54dd52fb7a 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -998,9 +998,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 430b187ef6b7d550e9ade89dd0254c5d1448a77a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Aug 2016 14:28:24 -0400 Subject: [PATCH 187/220] start a dashboard folder --- .../Updates/GithubUpdater.cs | 1 - .../Configuration/ServerConfiguration.cs | 2 + .../HttpServer/HttpListenerHost.cs | 20 +++- .../ApplicationHost.cs | 1 + .../MediaBrowser.Server.Startup.Common.csproj | 1 + .../Migrations/UpdateLevelMigration.cs | 97 +++++++++++++++++++ .../Api/DashboardService.cs | 62 +++++++----- .../MediaBrowser.WebDashboard.csproj | 34 ++++--- .../Savers/EpisodeNfoSaver.cs | 4 +- 9 files changed, 180 insertions(+), 42 deletions(-) create mode 100644 MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index d1ec30210e..a118f7c265 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -33,7 +33,6 @@ namespace MediaBrowser.Common.Implementations.Updates EnableKeepAlive = false, CancellationToken = cancellationToken, UserAgent = "Emby/3.0" - }; if (_cacheLength.Ticks > 0) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 63d452bcee..a891a422a5 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -74,6 +74,8 @@ namespace MediaBrowser.Model.Configuration /// The metadata path. public string MetadataPath { get; set; } + public string LastVersion { get; set; } + /// /// Gets or sets the display name of the season zero. /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 6332087391..51a53fe211 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -428,8 +428,24 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) || - localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1 || - localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1) + localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1) + { + httpRes.StatusCode = 200; + httpRes.ContentType = "text/html"; + var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) + .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); + + if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + { + httpRes.Write("EmbyPlease update your Emby bookmark to " + newUrl + ""); + + httpRes.Close(); + return; + } + } + + if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 && + localPath.IndexOf("web/dashboard", StringComparison.OrdinalIgnoreCase) == -1) { httpRes.StatusCode = 200; httpRes.ContentType = "text/html"; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 8cb1d4f0db..8516e54ee9 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -385,6 +385,7 @@ namespace MediaBrowser.Server.Startup.Common new OmdbEpisodeProviderMigration(ServerConfigurationManager), new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), + new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename), new FolderViewSettingMigration(ServerConfigurationManager, UserManager), new CollectionGroupingMigration(ServerConfigurationManager, UserManager), new CollectionsViewMigration(ServerConfigurationManager, UserManager) diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 808d25fc9c..979a3a3577 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -77,6 +77,7 @@ + diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs new file mode 100644 index 0000000000..fa354065c3 --- /dev/null +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -0,0 +1,97 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Implementations.Updates; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Updates; + +namespace MediaBrowser.Server.Startup.Common.Migrations +{ + public class UpdateLevelMigration : IVersionMigration + { + private readonly IServerConfigurationManager _config; + private readonly IServerApplicationHost _appHost; + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + private readonly string _releaseAssetFilename; + + public UpdateLevelMigration(IServerConfigurationManager config, IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, string releaseAssetFilename) + { + _config = config; + _appHost = appHost; + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + _releaseAssetFilename = releaseAssetFilename; + } + + public async void Run() + { + var lastVersion = _config.Configuration.LastVersion; + var currentVersion = _appHost.ApplicationVersion; + + if (string.Equals(lastVersion, currentVersion.ToString(), StringComparison.OrdinalIgnoreCase)) + { + return; + } + + try + { + var updateLevel = _config.Configuration.SystemUpdateLevel; + + // Go down a level + if (updateLevel == PackageVersionClass.Release) + { + updateLevel = PackageVersionClass.Beta; + } + else if (updateLevel == PackageVersionClass.Beta) + { + updateLevel = PackageVersionClass.Dev; + } + else if (updateLevel == PackageVersionClass.Dev) + { + // It's already dev, there's nothing to check + return; + } + + await CheckVersion(currentVersion, updateLevel, CancellationToken.None).ConfigureAwait(false); + } + catch + { + + } + } + + private async Task CheckVersion(Version currentVersion, PackageVersionClass updateLevel, CancellationToken cancellationToken) + { + var result = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(5)) + .CheckForUpdateResult("MediaBrowser", "Emby", currentVersion, PackageVersionClass.Beta, _releaseAssetFilename, "MBServer", "Mbserver.zip", + cancellationToken).ConfigureAwait(false); + + if (result != null && result.IsUpdateAvailable) + { + _config.Configuration.SystemUpdateLevel = updateLevel; + _config.SaveConfiguration(); + return; + } + + // Go down a level + if (updateLevel == PackageVersionClass.Release) + { + updateLevel = PackageVersionClass.Beta; + } + else if (updateLevel == PackageVersionClass.Beta) + { + updateLevel = PackageVersionClass.Dev; + } + else + { + return; + } + + await CheckVersion(currentVersion, updateLevel, cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 12e1eb5eaf..aec4632ae8 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -157,11 +157,21 @@ namespace MediaBrowser.WebDashboard.Api var creator = GetPackageCreator(); var directory = creator.DashboardUIPath; - var skipExtensions = GetUndeployedExtensions(); + var skipExtensions = GetDeployIgnoreExtensions(); + var skipNames = GetDeployIgnoreFilenames(); return Directory.GetFiles(directory, "*", SearchOption.AllDirectories) .Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + .Where(i => !skipNames.Any(s => + { + if (s.Item2) + { + return string.Equals(s.Item1, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase); + } + + return (Path.GetFileName(i) ?? string.Empty).IndexOf(s.Item1, StringComparison.OrdinalIgnoreCase) != -1; + })) .Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString()) .ToList(); } @@ -300,7 +310,7 @@ namespace MediaBrowser.WebDashboard.Api return new PackageCreator(_fileSystem, _localization, Logger, _serverConfigurationManager, _jsonSerializer); } - private List GetUndeployedExtensions() + private List GetDeployIgnoreExtensions() { var list = new List(); @@ -315,6 +325,28 @@ namespace MediaBrowser.WebDashboard.Api return list; } + private List> GetDeployIgnoreFilenames() + { + var list = new List>(); + + list.Add(new Tuple("copying", true)); + list.Add(new Tuple("license", true)); + list.Add(new Tuple("license-mit", true)); + list.Add(new Tuple("gitignore", false)); + list.Add(new Tuple("npmignore", false)); + list.Add(new Tuple("jshintrc", false)); + list.Add(new Tuple("gruntfile", false)); + list.Add(new Tuple("bowerrc", false)); + list.Add(new Tuple("jscsrc", false)); + list.Add(new Tuple("hero.svg", false)); + list.Add(new Tuple("travis.yml", false)); + list.Add(new Tuple("build.js", false)); + list.Add(new Tuple("editorconfig", false)); + list.Add(new Tuple("gitattributes", false)); + + return list; + } + public async Task Get(GetDashboardPackage request) { var path = Path.Combine(_serverConfigurationManager.ApplicationPaths.ProgramDataPath, @@ -344,30 +376,12 @@ namespace MediaBrowser.WebDashboard.Api // Try to trim the output size a bit var bowerPath = Path.Combine(path, "bower_components"); - if (!string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) - { - //var versionedBowerPath = Path.Combine(Path.GetDirectoryName(bowerPath), "bower_components" + _appHost.ApplicationVersion); - //Directory.Move(bowerPath, versionedBowerPath); - //bowerPath = versionedBowerPath; - } - - GetUndeployedExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i)); + GetDeployIgnoreExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i)); DeleteFilesByExtension(bowerPath, ".json", "strings\\"); - DeleteFilesByName(bowerPath, "copying", true); - DeleteFilesByName(bowerPath, "license", true); - DeleteFilesByName(bowerPath, "license-mit", true); - DeleteFilesByName(bowerPath, "gitignore"); - DeleteFilesByName(bowerPath, "npmignore"); - DeleteFilesByName(bowerPath, "jshintrc"); - DeleteFilesByName(bowerPath, "gruntfile"); - DeleteFilesByName(bowerPath, "bowerrc"); - DeleteFilesByName(bowerPath, "jscsrc"); - DeleteFilesByName(bowerPath, "hero.svg"); - DeleteFilesByName(bowerPath, "travis.yml"); - DeleteFilesByName(bowerPath, "build.js"); - DeleteFilesByName(bowerPath, "editorconfig"); - DeleteFilesByName(bowerPath, "gitattributes"); + + GetDeployIgnoreFilenames().ForEach(i => DeleteFilesByName(bowerPath, i.Item1, i.Item2)); + DeleteFoldersByName(bowerPath, "demo"); DeleteFoldersByName(bowerPath, "test"); DeleteFoldersByName(bowerPath, "guides"); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 54dd52fb7a..b2eb34526c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -101,6 +101,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -185,6 +188,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -326,7 +332,7 @@ PreserveNewest - + PreserveNewest @@ -338,7 +344,7 @@ PreserveNewest - + PreserveNewest @@ -356,7 +362,7 @@ PreserveNewest - + PreserveNewest @@ -377,7 +383,7 @@ PreserveNewest - + PreserveNewest @@ -503,7 +509,7 @@ PreserveNewest - + PreserveNewest @@ -863,13 +869,13 @@ PreserveNewest - + PreserveNewest PreserveNewest - + PreserveNewest @@ -881,7 +887,7 @@ PreserveNewest - + PreserveNewest @@ -896,10 +902,10 @@ PreserveNewest - + PreserveNewest - + PreserveNewest @@ -1089,7 +1095,7 @@ PreserveNewest - + PreserveNewest @@ -1356,7 +1362,7 @@ - + PreserveNewest @@ -1429,7 +1435,7 @@ - + PreserveNewest @@ -1441,7 +1447,7 @@ PreserveNewest - + PreserveNewest diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs index 7523ce6bf1..6380b9f53b 100644 --- a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs @@ -118,7 +118,9 @@ namespace MediaBrowser.XbmcMetadata.Savers "airsbefore_season", "DVD_episodenumber", "DVD_season", - "absolute_number" + "absolute_number", + "displayseason", + "displayepisode" }; return list; From ac4023ed47f35a6b90d0689ab205810c5e4acfcf Mon Sep 17 00:00:00 2001 From: softworkz Date: Tue, 23 Aug 2016 03:26:34 +0200 Subject: [PATCH 188/220] Core server preparation for new "TV Maze Provider Plugin" --- MediaBrowser.Controller/Providers/BaseItemXmlParser.cs | 9 +++++++++ MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs | 7 +++++++ MediaBrowser.Model/Entities/MetadataProviders.cs | 3 ++- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 9 +++++++++ MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 6 ++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index a783910e34..c0912708c3 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -724,6 +724,15 @@ namespace MediaBrowser.Controller.Providers } break; } + case "TvMazeId": + { + var id = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(id)) + { + item.SetProviderId(MetadataProviders.TvMaze, id); + } + break; + } case "AudioDbArtistId": { var id = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index 2b3f53aeb5..d472d48121 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -553,6 +553,13 @@ namespace MediaBrowser.LocalMetadata.Savers builder.Append("" + SecurityElement.Escape(externalId) + ""); } + externalId = item.GetProviderId(MetadataProviders.TvMaze); + + if (!string.IsNullOrEmpty(externalId)) + { + builder.Append("" + SecurityElement.Escape(externalId) + ""); + } + var hasTagline = item as IHasTaglines; if (hasTagline != null) { diff --git a/MediaBrowser.Model/Entities/MetadataProviders.cs b/MediaBrowser.Model/Entities/MetadataProviders.cs index f5ab0c1d47..1e7bde934d 100644 --- a/MediaBrowser.Model/Entities/MetadataProviders.cs +++ b/MediaBrowser.Model/Entities/MetadataProviders.cs @@ -39,6 +39,7 @@ namespace MediaBrowser.Model.Entities TvRage = 15, AudioDbArtist = 16, AudioDbAlbum = 17, - MusicBrainzTrack = 18 + MusicBrainzTrack = 18, + TvMaze = 19 } } diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 0c8501e626..f777ae16bc 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -827,6 +827,15 @@ namespace MediaBrowser.XbmcMetadata.Parsers } break; } + case "tvmazeid": + { + var id = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(id)) + { + item.SetProviderId(MetadataProviders.TvMaze, id); + } + break; + } case "audiodbartistid": { var id = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 954fb2a474..c28a15a939 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -822,6 +822,12 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteElementString("tvrageid", externalId); } + externalId = item.GetProviderId(MetadataProviders.TvMaze); + if (!string.IsNullOrEmpty(externalId)) + { + writer.WriteElementString("tvmazeid", externalId); + } + if (options.SaveImagePathsInNfo) { AddImages(item, writer, libraryManager, config); From b098f0cd2704e744f3b3185f7233d3181ea572b6 Mon Sep 17 00:00:00 2001 From: Softworkz Date: Sun, 14 Aug 2016 02:51:11 +0200 Subject: [PATCH 189/220] ETag for synced media --- .../Sync/SyncedMediaSourceProvider.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs index efd37fa00e..a2b5851ac0 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs @@ -144,6 +144,10 @@ namespace MediaBrowser.Server.Implementations.Sync { mediaSource.Id = item.Id; mediaSource.SupportsTranscoding = false; + if (mediaSource.Protocol == Model.MediaInfo.MediaProtocol.File) + { + mediaSource.ETag = item.Id; + } } public Task CloseMediaSource(string liveStreamId, CancellationToken cancellationToken) From 17e1c8c22b8ee09a363cfd76ed315b3af9cc09c8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Aug 2016 01:08:07 -0400 Subject: [PATCH 190/220] update sync settings --- .../Playback/BaseStreamingService.cs | 14 ++------ .../Playback/Hls/BaseHlsService.cs | 5 --- MediaBrowser.Api/Playback/StreamRequest.cs | 2 -- MediaBrowser.Api/Sync/SyncHelper.cs | 13 +++++++ MediaBrowser.Api/Sync/SyncService.cs | 3 +- .../MediaEncoding/MediaEncoderHelpers.cs | 7 +++- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 1 - MediaBrowser.Dlna/Profiles/KodiProfile.cs | 2 -- MediaBrowser.Model/Dlna/AudioOptions.cs | 6 +++- MediaBrowser.Model/Dlna/DeviceProfile.cs | 3 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 35 +++++++++++-------- MediaBrowser.Model/Dlna/StreamInfo.cs | 4 +-- MediaBrowser.Model/Dlna/TranscodingProfile.cs | 3 -- .../MediaEncoder/EncodingManager.cs | 2 +- .../Sync/AppSyncProvider.cs | 5 +++ 15 files changed, 58 insertions(+), 47 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f52505c04b..bff6ec2ffa 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1589,13 +1589,6 @@ namespace MediaBrowser.Api.Playback } } else if (i == 25) - { - if (videoRequest != null) - { - videoRequest.ForceLiveStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); - } - } - else if (i == 26) { if (!string.IsNullOrWhiteSpace(val) && videoRequest != null) { @@ -1606,18 +1599,18 @@ namespace MediaBrowser.Api.Playback } } } - else if (i == 27) + else if (i == 26) { request.TranscodingMaxAudioChannels = int.Parse(val, UsCulture); } - else if (i == 28) + else if (i == 27) { if (videoRequest != null) { videoRequest.EnableSubtitlesInManifest = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); } } - else if (i == 29) + else if (i == 28) { request.Tag = val; } @@ -2218,7 +2211,6 @@ namespace MediaBrowser.Api.Playback if (state.VideoRequest != null) { state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps; - state.VideoRequest.ForceLiveStream = transcodingProfile.ForceLiveStream; state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest; } } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 4ec14c96cb..a0ac96b9d2 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -281,11 +281,6 @@ namespace MediaBrowser.Api.Playback.Hls { var isLiveStream = (state.RunTimeTicks ?? 0) == 0; - if (state.VideoRequest.ForceLiveStream) - { - return true; - } - return isLiveStream; } } diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index e1a577f525..8cdf846ed5 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -193,8 +193,6 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool CopyTimestamps { get; set; } - public bool ForceLiveStream { get; set; } - public bool EnableSubtitlesInManifest { get; set; } public VideoStreamRequest() diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs index 2f857000c0..60df2bb1e9 100644 --- a/MediaBrowser.Api/Sync/SyncHelper.cs +++ b/MediaBrowser.Api/Sync/SyncHelper.cs @@ -24,6 +24,19 @@ namespace MediaBrowser.Api.Sync } break; } + if (item.IsAudio) + { + options.Add(SyncJobOption.Quality); + options.Add(SyncJobOption.Profile); + break; + } + if (item.IsMusicGenre || item.IsArtist|| item.IsType("musicalbum")) + { + options.Add(SyncJobOption.Quality); + options.Add(SyncJobOption.Profile); + options.Add(SyncJobOption.ItemLimit); + break; + } if (item.IsFolderItem && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre) { options.Add(SyncJobOption.Quality); diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index b9544d71ba..821591dc4e 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -291,7 +291,8 @@ namespace MediaBrowser.Api.Sync { Fields = new List { - ItemFields.SyncInfo + ItemFields.SyncInfo, + ItemFields.BasicSyncInfo } }; diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs index 66a9fa60b8..96a3753e19 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs @@ -36,8 +36,13 @@ namespace MediaBrowser.Controller.MediaEncoding return new[] {videoPath}; } - public static List GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, IEnumerable filenames) + private static List GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, List filenames) { + if (filenames.Count == 0) + { + return new List(); + } + var allFiles = fileSystem .GetFilePaths(rootPath, true) .ToList(); diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index e4f6d337fe..5f60e8306d 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -33,7 +33,6 @@ namespace MediaBrowser.Dlna.Profiles MaxStreamingBitrate = 20000000; MaxStaticBitrate = 20000000; MusicStreamingTranscodingBitrate = 192000; - MusicSyncBitrate = 192000; EnableAlbumArtInDidl = false; diff --git a/MediaBrowser.Dlna/Profiles/KodiProfile.cs b/MediaBrowser.Dlna/Profiles/KodiProfile.cs index 184923b70d..5e1ac57608 100644 --- a/MediaBrowser.Dlna/Profiles/KodiProfile.cs +++ b/MediaBrowser.Dlna/Profiles/KodiProfile.cs @@ -11,9 +11,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "Kodi"; MaxStreamingBitrate = 100000000; - MaxStaticBitrate = 100000000; MusicStreamingTranscodingBitrate = 1280000; - MusicSyncBitrate = 1280000; TimelineOffsetSeconds = 5; diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index c208e8ab0b..f3b6df861d 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Model.Dlna /// Gets the maximum bitrate. /// /// System.Nullable<System.Int32>. - public int? GetMaxBitrate() + public int? GetMaxBitrate(bool isAudio) { if (MaxBitrate.HasValue) { @@ -70,6 +70,10 @@ namespace MediaBrowser.Model.Dlna { if (Context == EncodingContext.Static) { + if (isAudio && Profile.MaxStaticMusicBitrate.HasValue) + { + return Profile.MaxStaticMusicBitrate; + } return Profile.MaxStaticBitrate; } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 423928f620..d6a3223227 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna public int? MaxStaticBitrate { get; set; } public int? MusicStreamingTranscodingBitrate { get; set; } - public int? MusicSyncBitrate { get; set; } + public int? MaxStaticMusicBitrate { get; set; } /// /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace. @@ -115,7 +115,6 @@ namespace MediaBrowser.Model.Dlna MaxStreamingBitrate = 8000000; MaxStaticBitrate = 8000000; MusicStreamingTranscodingBitrate = 128000; - MusicSyncBitrate = 128000; } public List GetSupportedMediaTypes() diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 0710417c85..f1b3e7bab5 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna stream.DeviceProfileId = options.Profile.Id; } - return GetOptimalStream(streams, options.GetMaxBitrate()); + return GetOptimalStream(streams, options.GetMaxBitrate(true)); } public StreamInfo BuildVideoItem(VideoOptions options) @@ -88,7 +88,7 @@ namespace MediaBrowser.Model.Dlna stream.DeviceProfileId = options.Profile.Id; } - return GetOptimalStream(streams, options.GetMaxBitrate()); + return GetOptimalStream(streams, options.GetMaxBitrate(false)); } private StreamInfo GetOptimalStream(List streams, int? maxBitrate) @@ -275,24 +275,32 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int configuredBitrate = options.AudioTranscodingBitrate ?? - (options.Context == EncodingContext.Static ? options.Profile.MusicSyncBitrate : options.Profile.MusicStreamingTranscodingBitrate) ?? + int transcodingBitrate = options.AudioTranscodingBitrate ?? + options.Profile.MusicStreamingTranscodingBitrate ?? 128000; - playlistItem.AudioBitrate = Math.Min(configuredBitrate, playlistItem.AudioBitrate ?? configuredBitrate); + int? configuredBitrate = options.GetMaxBitrate(true); + + if (configuredBitrate.HasValue) + { + transcodingBitrate = Math.Min(configuredBitrate.Value, transcodingBitrate); + } + + playlistItem.AudioBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate); + } return playlistItem; } - private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options) + private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio) { if (item.Protocol == MediaProtocol.File) { return options.Profile.MaxStaticBitrate; } - return options.GetMaxBitrate(); + return options.GetMaxBitrate(isAudio); } private List GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options) @@ -312,7 +320,7 @@ namespace MediaBrowser.Model.Dlna if (directPlayProfile != null) { // While options takes the network and other factors into account. Only applies to direct stream - if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate()) && options.EnableDirectStream) + if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true)) && options.EnableDirectStream) { playMethods.Add(PlayMethod.DirectStream); } @@ -320,7 +328,7 @@ namespace MediaBrowser.Model.Dlna // The profile describes what the device supports // If device requirements are satisfied then allow both direct stream and direct play if (item.SupportsDirectPlay && - IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options)) && options.EnableDirectPlay) + IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true)) && options.EnableDirectPlay) { playMethods.Add(PlayMethod.DirectPlay); } @@ -403,8 +411,8 @@ namespace MediaBrowser.Model.Dlna MediaStream videoStream = item.VideoStream; // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough - bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay)); - bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream)); + bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay)); + bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream)); _logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}", options.Profile.Name ?? "Unknown Profile", @@ -469,7 +477,6 @@ namespace MediaBrowser.Model.Dlna playlistItem.VideoCodec = transcodingProfile.VideoCodec; playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps; - playlistItem.ForceLiveStream = transcodingProfile.ForceLiveStream; playlistItem.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest; if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels)) @@ -570,10 +577,10 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); + int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); - int? maxBitrateSetting = options.GetMaxBitrate(); + int? maxBitrateSetting = options.GetMaxBitrate(false); // Honor max rate if (maxBitrateSetting.HasValue) { diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 02239aa484..ac024f00b9 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -36,7 +36,6 @@ namespace MediaBrowser.Model.Dlna public string VideoProfile { get; set; } public bool CopyTimestamps { get; set; } - public bool ForceLiveStream { get; set; } public bool EnableSubtitlesInManifest { get; set; } public string[] AudioCodecs { get; set; } @@ -216,7 +215,7 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty)); list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty)); - if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls") && !item.ForceLiveStream) + if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls")) { list.Add(new NameValuePair("StartTimeTicks", string.Empty)); } @@ -246,7 +245,6 @@ namespace MediaBrowser.Model.Dlna } list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString().ToLower())); - list.Add(new NameValuePair("ForceLiveStream", item.ForceLiveStream.ToString().ToLower())); list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty)); list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? StringHelper.ToStringCultureInvariant(item.TranscodingMaxAudioChannels.Value) : string.Empty)); diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs index 19caf85eb2..beb83b053b 100644 --- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs @@ -35,9 +35,6 @@ namespace MediaBrowser.Model.Dlna [XmlAttribute("context")] public EncodingContext Context { get; set; } - [XmlAttribute("forceLiveStream")] - public bool ForceLiveStream { get; set; } - [XmlAttribute("enableSubtitlesInManifest")] public bool EnableSubtitlesInManifest { get; set; } diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 7f709d084f..46ba7d2e74 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder { if (extractImages) { - if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay) + if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) { continue; } diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index 03485012f0..408ec717eb 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -85,6 +85,11 @@ namespace MediaBrowser.Server.Implementations.Sync { Name = "Low", Id = "low" + }, + new SyncQualityOption + { + Name = "Custom", + Id = "custom" } }; } From 86480e207b8d680e2a777892c7196b3bc1ea2209 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Aug 2016 02:42:15 -0400 Subject: [PATCH 191/220] update sync --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index b2eb34526c..5b66c27f48 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1001,9 +1001,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From f57a0e6b81b34a01ce3975b3652f245edae41f10 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Aug 2016 12:02:14 -0400 Subject: [PATCH 192/220] fixes #1535 - More options for transcoding music --- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index e96a77e647..d1c4c0b449 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.654 + 3.0.655 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index ada11fd45a..ffee84de2e 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.654 + 3.0.655 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index f4a79f454f..73c51ca355 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.654 + 3.0.655 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + From 2e65c32ededcfe67dbfb345270b55e1f3d816edc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Aug 2016 12:31:16 -0400 Subject: [PATCH 193/220] add vaapi support --- .../Playback/BaseStreamingService.cs | 129 ++++++++++++------ .../Encoder/BaseEncoder.cs | 118 ++++++++++------ .../Encoder/EncodingJobFactory.cs | 4 + .../Configuration/EncodingOptions.cs | 1 + .../Native/BaseMonoApp.cs | 29 +--- 5 files changed, 175 insertions(+), 106 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index bff6ec2ffa..4c8b918c6a 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -314,6 +314,10 @@ namespace MediaBrowser.Api.Playback { return GetAvailableEncoder("h264_omx", defaultEncoder); } + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + { + return GetAvailableEncoder("h264_vaapi", defaultEncoder); + } } return defaultEncoder; @@ -427,7 +431,8 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrEmpty(state.VideoRequest.Profile)) { - if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { // not supported by h264_omx param += " -profile:v " + state.VideoRequest.Profile; @@ -482,7 +487,8 @@ namespace MediaBrowser.Api.Playback if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) && - !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase)) + !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { param = "-pix_fmt yuv420p " + param; } @@ -548,59 +554,97 @@ namespace MediaBrowser.Api.Playback var filters = new List(); - if (state.DeInterlace) + if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + { + filters.Add("format=nv12|vaapi"); + filters.Add("hwupload"); + } + else if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { filters.Add("yadif=0:-1:0"); } - // If fixed dimensions were supplied - if (request.Width.HasValue && request.Height.HasValue) + if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { - var widthParam = request.Width.Value.ToString(UsCulture); - var heightParam = request.Height.Value.ToString(UsCulture); + // Work around vaapi's reduced scaling features + var scaler = "scale_vaapi"; - filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam)); - } + // Given the input dimensions (inputWidth, inputHeight), determine the output dimensions + // (outputWidth, outputHeight). The user may request precise output dimensions or maximum + // output dimensions. Output dimensions are guaranteed to be even. + decimal inputWidth = Convert.ToDecimal(state.VideoStream.Width); + decimal inputHeight = Convert.ToDecimal(state.VideoStream.Height); + decimal outputWidth = request.Width.HasValue ? Convert.ToDecimal(request.Width.Value) : inputWidth; + decimal outputHeight = request.Height.HasValue ? Convert.ToDecimal(request.Height.Value) : inputHeight; + decimal maximumWidth = request.MaxWidth.HasValue ? Convert.ToDecimal(request.MaxWidth.Value) : outputWidth; + decimal maximumHeight = request.MaxHeight.HasValue ? Convert.ToDecimal(request.MaxHeight.Value) : outputHeight; - // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size - else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue) - { - var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); - var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); + if (outputWidth > maximumWidth || outputHeight > maximumHeight) + { + var scale = Math.Min(maximumWidth / outputWidth, maximumHeight / outputHeight); + outputWidth = Math.Min(maximumWidth, Math.Truncate(outputWidth * scale)); + outputHeight = Math.Min(maximumHeight, Math.Truncate(outputHeight * scale)); + } - filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam)); - } + outputWidth = 2 * Math.Truncate(outputWidth / 2); + outputHeight = 2 * Math.Truncate(outputHeight / 2); - // If a fixed width was requested - else if (request.Width.HasValue) + if (outputWidth != inputWidth || outputHeight != inputHeight) + { + filters.Add(string.Format("{0}=w={1}:h={2}", scaler, outputWidth.ToString(UsCulture), outputHeight.ToString(UsCulture))); + } + } + else { - var widthParam = request.Width.Value.ToString(UsCulture); + // If fixed dimensions were supplied + if (request.Width.HasValue && request.Height.HasValue) + { + var widthParam = request.Width.Value.ToString(UsCulture); + var heightParam = request.Height.Value.ToString(UsCulture); - filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam)); - } + filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam)); + } - // If a fixed height was requested - else if (request.Height.HasValue) - { - var heightParam = request.Height.Value.ToString(UsCulture); + // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size + else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue) + { + var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam)); - } + filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam)); + } - // If a max width was requested - else if (request.MaxWidth.HasValue) - { - var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + // If a fixed width was requested + else if (request.Width.HasValue) + { + var widthParam = request.Width.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam)); - } + filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam)); + } - // If a max height was requested - else if (request.MaxHeight.HasValue) - { - var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); + // If a fixed height was requested + else if (request.Height.HasValue) + { + var heightParam = request.Height.Value.ToString(UsCulture); + + filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam)); + } + + // If a max width was requested + else if (request.MaxWidth.HasValue) + { + var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + + filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam)); + } + + // If a max height was requested + else if (request.MaxHeight.HasValue) + { + var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); + filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); + } } var output = string.Empty; @@ -935,6 +979,15 @@ namespace MediaBrowser.Api.Playback } } + if (state.VideoRequest != null) + { + var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions(); + if (GetVideoEncoder(state).IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1) + { + arg = "-hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device " + encodingOptions.VaapiDevice + " " + arg; + } + } + return arg.Trim(); } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 32cd950afe..aaa5593b48 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -680,7 +680,8 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!string.IsNullOrEmpty(state.Options.Profile)) { - if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { // not supported by h264_omx param += " -profile:v " + state.Options.Profile; @@ -737,7 +738,8 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) && - !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase)) + !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { param = "-pix_fmt yuv420p " + param; } @@ -887,66 +889,96 @@ namespace MediaBrowser.MediaEncoding.Encoder var filters = new List(); - if (state.DeInterlace) + if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + { + filters.Add("format=nv12|vaapi"); + filters.Add("hwupload"); + } + else if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { filters.Add("yadif=0:-1:0"); } - // If fixed dimensions were supplied - if (request.Width.HasValue && request.Height.HasValue) + if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { - var widthParam = request.Width.Value.ToString(UsCulture); - var heightParam = request.Height.Value.ToString(UsCulture); + // Work around vaapi's reduced scaling features + var scaler = "scale_vaapi"; - filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam)); - } + // Given the input dimensions (inputWidth, inputHeight), determine the output dimensions + // (outputWidth, outputHeight). The user may request precise output dimensions or maximum + // output dimensions. Output dimensions are guaranteed to be even. + decimal inputWidth = Convert.ToDecimal(state.VideoStream.Width); + decimal inputHeight = Convert.ToDecimal(state.VideoStream.Height); + decimal outputWidth = request.Width.HasValue ? Convert.ToDecimal(request.Width.Value) : inputWidth; + decimal outputHeight = request.Height.HasValue ? Convert.ToDecimal(request.Height.Value) : inputHeight; + decimal maximumWidth = request.MaxWidth.HasValue ? Convert.ToDecimal(request.MaxWidth.Value) : outputWidth; + decimal maximumHeight = request.MaxHeight.HasValue ? Convert.ToDecimal(request.MaxHeight.Value) : outputHeight; - // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size - else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue) - { - var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); - var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); + if (outputWidth > maximumWidth || outputHeight > maximumHeight) + { + var scale = Math.Min(maximumWidth / outputWidth, maximumHeight / outputHeight); + outputWidth = Math.Min(maximumWidth, Math.Truncate(outputWidth * scale)); + outputHeight = Math.Min(maximumHeight, Math.Truncate(outputHeight * scale)); + } - filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam)); - } + outputWidth = 2 * Math.Truncate(outputWidth / 2); + outputHeight = 2 * Math.Truncate(outputHeight / 2); - // If a fixed width was requested - else if (request.Width.HasValue) + if (outputWidth != inputWidth || outputHeight != inputHeight) + { + filters.Add(string.Format("{0}=w={1}:h={2}", scaler, outputWidth.ToString(UsCulture), outputHeight.ToString(UsCulture))); + } + } + else { - var widthParam = request.Width.Value.ToString(UsCulture); + // If fixed dimensions were supplied + if (request.Width.HasValue && request.Height.HasValue) + { + var widthParam = request.Width.Value.ToString(UsCulture); + var heightParam = request.Height.Value.ToString(UsCulture); - filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam)); - } + filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam)); + } - // If a fixed height was requested - else if (request.Height.HasValue) - { - var heightParam = request.Height.Value.ToString(UsCulture); + // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size + else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue) + { + var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam)); - } + filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam)); + } - // If a max width was requested - else if (request.MaxWidth.HasValue) - { - var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + // If a fixed width was requested + else if (request.Width.HasValue) + { + var widthParam = request.Width.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam)); - } + filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam)); + } - // If a max height was requested - else if (request.MaxHeight.HasValue) - { - var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); + // If a fixed height was requested + else if (request.Height.HasValue) + { + var heightParam = request.Height.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); - } + filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam)); + } - if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) - { - if (filters.Count > 1) + // If a max width was requested + else if (request.MaxWidth.HasValue) + { + var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); + + filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam)); + } + + // If a max height was requested + else if (request.MaxHeight.HasValue) { - //filters[filters.Count - 1] += ":flags=fast_bilinear"; + var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); + + filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index ba7b149508..b5e97f09a1 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -586,6 +586,10 @@ namespace MediaBrowser.MediaEncoding.Encoder { return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder); } + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + { + return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder); + } } return defaultEncoder; diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 91d28a2969..4ef15604aa 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -10,6 +10,7 @@ namespace MediaBrowser.Model.Configuration public int ThrottleDelaySeconds { get; set; } public string HardwareAccelerationType { get; set; } public string EncoderAppPath { get; set; } + public string VaapiDevice { get; set; } public EncodingOptions() { diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 4011fa3de3..faf3ba37ea 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Server.Mono.Native { get { - return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx; + return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx; } } @@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Mono.Native { info.SystemArchitecture = Architecture.X64; } - else + else { info.SystemArchitecture = Architecture.X86; } @@ -273,32 +273,11 @@ namespace MediaBrowser.Server.Mono.Native break; } - info.DownloadUrls = GetDownloadUrls(environment); + // No version available - user requirement + info.DownloadUrls = new string[] { }; return info; } - - private static string[] GetDownloadUrls(NativeEnvironment environment) - { - switch (environment.OperatingSystem) - { - case OperatingSystem.Linux: - - switch (environment.SystemArchitecture) - { - case Architecture.X64: - return new[] - { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-64bit-static.7z" - }; - } - break; - } - - // No version available - return new string[] { }; - } - } public class NullPowerManagement : IPowerManagement From e4851e1b25e7a51d5e950978c2e0ccc2e44a07c5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 02:13:15 -0400 Subject: [PATCH 194/220] reduce rescanning due to IsOffline --- .../Playback/BaseStreamingService.cs | 9 +++-- MediaBrowser.Controller/Entities/BaseItem.cs | 22 ++++++++-- MediaBrowser.Controller/Entities/Folder.cs | 15 +------ .../MediaEncoding/IMediaEncoder.cs | 1 + .../Encoder/EncodingJobFactory.cs | 2 +- .../Encoder/MediaEncoder.cs | 16 ++++---- .../Configuration/UserConfiguration.cs | 1 - .../MediaInfo/AudioImageProvider.cs | 9 +++-- .../MediaInfo/FFProbeProvider.cs | 2 +- .../MediaInfo/VideoImageProvider.cs | 2 +- .../Photos/PhotoProvider.cs | 9 +++-- .../Persistence/CleanDatabaseScheduledTask.cs | 3 +- .../Persistence/SqliteItemRepository.cs | 3 -- .../ApplicationHost.cs | 1 - .../MediaBrowser.Server.Startup.Common.csproj | 1 - .../Migrations/FolderViewSettingMigration.cs | 40 ------------------- 16 files changed, 51 insertions(+), 85 deletions(-) delete mode 100644 MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4c8b918c6a..6f4b6323d6 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -298,7 +298,8 @@ namespace MediaBrowser.Api.Playback // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. if (state.VideoType == VideoType.VideoFile) { - var hwType = ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType; + var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions(); + var hwType = encodingOptions.HardwareAccelerationType; if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) || string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) @@ -314,7 +315,7 @@ namespace MediaBrowser.Api.Playback { return GetAvailableEncoder("h264_omx", defaultEncoder); } - if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(encodingOptions.VaapiDevice)) { return GetAvailableEncoder("h264_vaapi", defaultEncoder); } @@ -988,6 +989,8 @@ namespace MediaBrowser.Api.Playback } } + arg += string.Format(" -ss {0}", MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(1).Ticks)); + return arg.Trim(); } @@ -2289,7 +2292,7 @@ namespace MediaBrowser.Api.Playback return Task.FromResult(true); } - if (!string.Equals(MediaEncoder.EncoderLocationType, "Default", StringComparison.OrdinalIgnoreCase)) + if (!MediaEncoder.IsDefaultEncoderPath) { return Task.FromResult(true); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cbbb9a89a3..984374a499 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -281,6 +281,20 @@ namespace MediaBrowser.Controller.Entities } } + public Task UpdateIsOffline(bool newValue) + { + var item = this; + + if (item.IsOffline != newValue) + { + item.IsOffline = newValue; + // this is creating too many repeated db updates + //return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); + } + + return Task.FromResult(true); + } + /// /// Gets or sets the type of the location. /// @@ -290,10 +304,10 @@ namespace MediaBrowser.Controller.Entities { get { - if (IsOffline) - { - return LocationType.Offline; - } + //if (IsOffline) + //{ + // return LocationType.Offline; + //} if (string.IsNullOrWhiteSpace(Path)) { diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b5c76c0ebc..bea648a3d3 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -375,7 +375,7 @@ namespace MediaBrowser.Controller.Entities if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child)) { - await UpdateIsOffline(currentChild, false).ConfigureAwait(false); + await currentChild.UpdateIsOffline(false).ConfigureAwait(false); validChildren.Add(currentChild); continue; @@ -404,7 +404,7 @@ namespace MediaBrowser.Controller.Entities else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path)) { - await UpdateIsOffline(item, true).ConfigureAwait(false); + await item.UpdateIsOffline(true).ConfigureAwait(false); } else { @@ -461,17 +461,6 @@ namespace MediaBrowser.Controller.Entities progress.Report(100); } - private Task UpdateIsOffline(BaseItem item, bool newValue) - { - if (item.IsOffline != newValue) - { - item.IsOffline = newValue; - return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); - } - - return Task.FromResult(true); - } - private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress progress, CancellationToken cancellationToken) { var children = ActualChildren.ToList(); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 1fef8bead7..7fdbf020ce 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -134,5 +134,6 @@ namespace MediaBrowser.Controller.MediaEncoding Task UpdateEncoderPath(string path, string pathType); bool SupportsEncoder(string encoder); + bool IsDefaultEncoderPath { get; } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index b5e97f09a1..c725326691 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -586,7 +586,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder); } - if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(options.VaapiDevice)) { return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder); } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f488be11a7..ad84ffee82 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -123,20 +123,20 @@ namespace MediaBrowser.MediaEncoding.Encoder return "System"; } - if (IsDefaultPath(FFMpegPath)) - { - return "Default"; - } - return "Custom"; } } - private bool IsDefaultPath(string path) + public bool IsDefaultEncoderPath { - var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410"); + get + { + var path = FFMpegPath; + + var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410"); - return FileSystem.ContainsSubPath(parentPath, path); + return FileSystem.ContainsSubPath(parentPath, path); + } } private bool IsSystemInstalledPath(string path) diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 69dc23b21c..b081e29737 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -48,7 +48,6 @@ namespace MediaBrowser.Model.Configuration public bool RememberAudioSelections { get; set; } public bool RememberSubtitleSelections { get; set; } public bool EnableNextEpisodeAutoPlay { get; set; } - public bool DisplayFoldersView { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 6c79189887..027341ee6a 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -167,10 +167,13 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 0df8b6c4b7..d255110fb7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path)) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 280e92beb9..2ad02da2ef 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (item.EnableRefreshOnDateModifiedChange) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/Photos/PhotoProvider.cs b/MediaBrowser.Providers/Photos/PhotoProvider.cs index 619b726368..c48c3d09be 100644 --- a/MediaBrowser.Providers/Photos/PhotoProvider.cs +++ b/MediaBrowser.Providers/Photos/PhotoProvider.cs @@ -154,10 +154,13 @@ namespace MediaBrowser.Providers.Photos public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index bf2afb5ace..c1394ee1c3 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -313,8 +313,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (Folder.IsPathOffline(path)) { - libraryItem.IsOffline = true; - await libraryItem.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false); + await libraryItem.UpdateIsOffline(true).ConfigureAwait(false); continue; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index b9befb531e..5c94d589dc 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -211,7 +211,6 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "ProductionYear", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "ParentId", "GUID"); _connection.AddColumn(Logger, "TypedBaseItems", "Genres", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "ParentalRatingValue", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "SchemaVersion", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "SortName", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); @@ -488,7 +487,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "ProductionYear", "ParentId", "Genres", - "ParentalRatingValue", "InheritedParentalRatingValue", "SchemaVersion", "SortName", @@ -795,7 +793,6 @@ namespace MediaBrowser.Server.Implementations.Persistence } _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); - _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0; _saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0; _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 8516e54ee9..75f2d24270 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -386,7 +386,6 @@ namespace MediaBrowser.Server.Startup.Common new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename), - new FolderViewSettingMigration(ServerConfigurationManager, UserManager), new CollectionGroupingMigration(ServerConfigurationManager, UserManager), new CollectionsViewMigration(ServerConfigurationManager, UserManager) }; diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 979a3a3577..bbef5caeae 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -72,7 +72,6 @@ - diff --git a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs deleted file mode 100644 index 12054864b3..0000000000 --- a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Linq; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Library; - -namespace MediaBrowser.Server.Startup.Common.Migrations -{ - public class FolderViewSettingMigration : IVersionMigration - { - private readonly IServerConfigurationManager _config; - private readonly IUserManager _userManager; - - public FolderViewSettingMigration(IServerConfigurationManager config, IUserManager userManager) - { - _config = config; - _userManager = userManager; - } - - public void Run() - { - var migrationKey = this.GetType().Name; - var migrationKeyList = _config.Configuration.Migrations.ToList(); - - if (!migrationKeyList.Contains(migrationKey)) - { - if (_config.Configuration.IsStartupWizardCompleted) - { - if (_userManager.Users.Any(i => i.Configuration.DisplayFoldersView)) - { - _config.Configuration.EnableFolderView = true; - } - } - - migrationKeyList.Add(migrationKey); - _config.Configuration.Migrations = migrationKeyList.ToArray(); - _config.SaveConfiguration(); - } - - } - } -} From e03ead01aea85fdc2ace162ab4daa94248ec6909 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 11:48:23 -0400 Subject: [PATCH 195/220] update opus mime type --- MediaBrowser.Model/Net/MimeTypes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index a138145381..8bf0703be9 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -241,7 +241,7 @@ namespace MediaBrowser.Model.Net } if (StringHelper.EqualsIgnoreCase(ext, ".opus")) { - return "audio/opus"; + return "audio/ogg"; } // Playlists From e5d5c67041d38b6137a5a31b1cddf9088f2d2cb0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 16:14:35 -0400 Subject: [PATCH 196/220] update vaapi defaults --- MediaBrowser.Model/Configuration/EncodingOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 4ef15604aa..3c03dc12a0 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Configuration EnableThrottling = true; ThrottleDelaySeconds = 180; EncodingThreadCount = -1; + VaapiDevice = "/dev/dri/card0"; } } } From c46e38725e40171639d6b1fec930081be129a1bc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 16:46:26 -0400 Subject: [PATCH 197/220] support realtime monitor per library --- .../Entities/CollectionFolder.cs | 1 + .../Configuration/LibraryOptions.cs | 3 ++ .../IO/LibraryMonitor.cs | 40 ++++++++++--------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index e120f2e23d..597ecf973a 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -106,6 +106,7 @@ namespace MediaBrowser.Controller.Entities { LibraryOptions[path] = options; + options.SchemaVersion = 1; XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); } } diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index e15df37c1a..3fe694553a 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -4,10 +4,13 @@ { public bool EnableArchiveMediaFiles { get; set; } public bool EnablePhotos { get; set; } + public bool EnableRealtimeMonitor { get; set; } + public int SchemaVersion { get; set; } public LibraryOptions() { EnablePhotos = true; + EnableRealtimeMonitor = true; } } } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index ea9e58ee47..7ed4dc71ef 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -172,27 +172,29 @@ namespace MediaBrowser.Server.Implementations.IO } } - public void Start() + private bool IsLibraryMonitorEnabaled(BaseItem item) { - if (EnableLibraryMonitor) + var options = LibraryManager.GetLibraryOptions(item); + + if (options != null && options.SchemaVersion >= 1) { - StartInternal(); + return options.EnableRealtimeMonitor; } + + return EnableLibraryMonitor; } - /// - /// Starts this instance. - /// - private void StartInternal() + public void Start() { LibraryManager.ItemAdded += LibraryManager_ItemAdded; LibraryManager.ItemRemoved += LibraryManager_ItemRemoved; - var pathsToWatch = new List { LibraryManager.RootFolder.Path }; + var pathsToWatch = new List { }; var paths = LibraryManager .RootFolder .Children + .Where(IsLibraryMonitorEnabaled) .OfType() .SelectMany(f => f.PhysicalLocations) .Distinct(StringComparer.OrdinalIgnoreCase) @@ -213,6 +215,14 @@ namespace MediaBrowser.Server.Implementations.IO } } + private void StartWatching(BaseItem item) + { + if (IsLibraryMonitorEnabaled(item)) + { + StartWatchingPath(item.Path); + } + } + /// /// Handles the ItemRemoved event of the LibraryManager control. /// @@ -235,7 +245,7 @@ namespace MediaBrowser.Server.Implementations.IO { if (e.Item.GetParent() is AggregateFolder) { - StartWatchingPath(e.Item.Path); + StartWatching(e.Item); } } @@ -382,14 +392,6 @@ namespace MediaBrowser.Server.Implementations.IO Logger.ErrorException("Error in Directory watcher for: " + dw.Path, ex); DisposeWatcher(dw); - - if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) - { - Logger.Info("Disabling realtime monitor to prevent future instability"); - - ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled; - Stop(); - } } /// @@ -420,8 +422,8 @@ namespace MediaBrowser.Server.Implementations.IO var filename = Path.GetFileName(path); - var monitorPath = !string.IsNullOrEmpty(filename) && - !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && + var monitorPath = !string.IsNullOrEmpty(filename) && + !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase); // Ignore certain files From 0117ee67d8ef5ae1e3b1885b46e4260e0bae60a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 17:06:04 -0400 Subject: [PATCH 198/220] resolve 128k limit --- .../Configuration/UserConfiguration.cs | 2 - MediaBrowser.Model/Dlna/StreamBuilder.cs | 13 +++--- .../ApplicationHost.cs | 1 - .../MediaBrowser.Server.Startup.Common.csproj | 1 - .../Migrations/CollectionGroupingMigration.cs | 40 ------------------- 5 files changed, 5 insertions(+), 52 deletions(-) delete mode 100644 MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index b081e29737..313c5243c3 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -27,8 +27,6 @@ namespace MediaBrowser.Model.Configuration public bool DisplayMissingEpisodes { get; set; } public bool DisplayUnairedEpisodes { get; set; } - public bool GroupMoviesIntoBoxSets { get; set; } - public string[] ExcludeFoldersFromGrouping { get; set; } public string[] GroupedFolders { get; set; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index f1b3e7bab5..d042125b9b 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -602,19 +602,16 @@ namespace MediaBrowser.Model.Dlna private int GetAudioBitrate(string subProtocol, int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) { - var defaultBitrate = 128000; - if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) + var defaultBitrate = audioStream.BitRate ?? 192000; + // Reduce the bitrate if we're downmixing + if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) { - defaultBitrate = 192000; - } - if (!string.IsNullOrEmpty(targetAudioCodec) && audioStream != null && StringHelper.EqualsIgnoreCase(audioStream.Codec, targetAudioCodec)) - { - defaultBitrate = audioStream.BitRate ?? defaultBitrate; + defaultBitrate = StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3") ? 192000 : 128000; } if (targetAudioChannels.HasValue) { - if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1500000) + if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1200000) { if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) { diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 75f2d24270..9c5015b0ec 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -386,7 +386,6 @@ namespace MediaBrowser.Server.Startup.Common new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename), - new CollectionGroupingMigration(ServerConfigurationManager, UserManager), new CollectionsViewMigration(ServerConfigurationManager, UserManager) }; diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index bbef5caeae..5ee7d49e86 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -70,7 +70,6 @@ - diff --git a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs deleted file mode 100644 index 5041c49b8b..0000000000 --- a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Linq; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Library; - -namespace MediaBrowser.Server.Startup.Common.Migrations -{ - public class CollectionGroupingMigration : IVersionMigration - { - private readonly IServerConfigurationManager _config; - private readonly IUserManager _userManager; - - public CollectionGroupingMigration(IServerConfigurationManager config, IUserManager userManager) - { - _config = config; - _userManager = userManager; - } - - public void Run() - { - var migrationKey = this.GetType().Name; - var migrationKeyList = _config.Configuration.Migrations.ToList(); - - if (!migrationKeyList.Contains(migrationKey)) - { - if (_config.Configuration.IsStartupWizardCompleted) - { - if (_userManager.Users.Any(i => i.Configuration.GroupMoviesIntoBoxSets)) - { - _config.Configuration.EnableGroupingIntoCollections = true; - } - } - - migrationKeyList.Add(migrationKey); - _config.Configuration.Migrations = migrationKeyList.ToArray(); - _config.SaveConfiguration(); - } - - } - } -} From f1d965c655781bc26b4ee84ef8c9b56fd7061e2f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 22:54:21 -0400 Subject: [PATCH 199/220] update cards --- MediaBrowser.Dlna/PlayTo/Device.cs | 10 +++++----- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 6ad5899da1..174ca871a4 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -479,17 +479,17 @@ namespace MediaBrowser.Dlna.PlayTo _successiveStopCount++; _connectFailureCount++; - if (_successiveStopCount >= maxSuccessiveStopReturns) - { - RestartTimerInactive(); - } - if (_connectFailureCount >= maxSuccessiveStopReturns) + if (_connectFailureCount >= 3) { if (OnDeviceUnavailable != null) { OnDeviceUnavailable(); } } + if (_successiveStopCount >= maxSuccessiveStopReturns) + { + RestartTimerInactive(); + } } catch (Exception ex) { diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 7429330bd6..913b34016d 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -99,11 +99,11 @@ namespace MediaBrowser.Dlna.PlayTo public void Init(Device device) { _device = device; + _device.OnDeviceUnavailable = OnDeviceUnavailable; _device.PlaybackStart += _device_PlaybackStart; _device.PlaybackProgress += _device_PlaybackProgress; _device.PlaybackStopped += _device_PlaybackStopped; _device.MediaChanged += _device_MediaChanged; - _device.OnDeviceUnavailable = OnDeviceUnavailable; _device.Start(); From 90b9b739126b09c81d3c29ae5c51d6ee3408fc14 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 23:12:25 -0400 Subject: [PATCH 200/220] fix because you watched showing unwatched titles --- MediaBrowser.Api/Movies/MoviesService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 755713c845..66f2fac812 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -192,7 +192,8 @@ namespace MediaBrowser.Api.Movies SortOrder = SortOrder.Descending, Limit = 7, ParentId = parentIdGuid, - Recursive = true + Recursive = true, + IsPlayed = true }; var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList(); From dc09bb8c0847cec812364ee6f32be055741e76dc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 23:44:59 -0400 Subject: [PATCH 201/220] fix dynamic images for osx --- Emby.Drawing/GDI/DynamicImageHelpers.cs | 48 ++++++------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/Emby.Drawing/GDI/DynamicImageHelpers.cs b/Emby.Drawing/GDI/DynamicImageHelpers.cs index 7b8ef2f98a..e0ce901200 100644 --- a/Emby.Drawing/GDI/DynamicImageHelpers.cs +++ b/Emby.Drawing/GDI/DynamicImageHelpers.cs @@ -33,7 +33,9 @@ namespace Emby.Drawing.GDI graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - graphics.CompositingMode = CompositingMode.SourceCopy; + + // This causes the image to be blank in OSX + //graphics.CompositingMode = CompositingMode.SourceCopy; for (var row = 0; row < rows; row++) { @@ -44,19 +46,9 @@ namespace Emby.Drawing.GDI if (files.Count > index) { - using (var fileStream = fileSystem.GetFileStream(files[index], FileMode.Open, FileAccess.Read, FileShare.Read, true)) + using (var imgtemp = Image.FromFile(files[index])) { - using (var memoryStream = new MemoryStream()) - { - fileStream.CopyTo(memoryStream); - - memoryStream.Position = 0; - - using (var imgtemp = Image.FromStream(memoryStream, true, false)) - { - graphics.DrawImage(imgtemp, x, y, cellWidth, cellHeight); - } - } + graphics.DrawImage(imgtemp, x, y, cellWidth, cellHeight); } } @@ -90,7 +82,9 @@ namespace Emby.Drawing.GDI graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - graphics.CompositingMode = CompositingMode.SourceCopy; + + // This causes the image to be blank in OSX + //graphics.CompositingMode = CompositingMode.SourceCopy; for (var row = 0; row < rows; row++) { @@ -99,21 +93,10 @@ namespace Emby.Drawing.GDI var x = col * singleSize; var y = row * singleSize; - using (var fileStream = fileSystem.GetFileStream(files[index], FileMode.Open, FileAccess.Read, FileShare.Read, true)) + using (var imgtemp = Image.FromFile(files[index])) { - using (var memoryStream = new MemoryStream()) - { - fileStream.CopyTo(memoryStream); - - memoryStream.Position = 0; - - using (var imgtemp = Image.FromStream(memoryStream, true, false)) - { - graphics.DrawImage(imgtemp, x, y, singleSize, singleSize); - } - } + graphics.DrawImage(imgtemp, x, y, singleSize, singleSize); } - index++; } } @@ -121,16 +104,5 @@ namespace Emby.Drawing.GDI } } } - - private static Stream GetStream(Image image) - { - var ms = new MemoryStream(); - - image.Save(ms, ImageFormat.Png); - - ms.Position = 0; - - return ms; - } } } From 1c9e414794d5c70035421231f52a363666f273e0 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 24 Aug 2016 23:54:07 -0400 Subject: [PATCH 202/220] update mac project --- .../Emby.Server.Mac.csproj | 394 ++++-------------- 1 file changed, 71 insertions(+), 323 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 104923f8ee..f04b833b90 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -390,6 +390,9 @@ Resources\dashboard-ui\autoorganizetv.html + + Resources\dashboard-ui\camerauploadsettings.html + Resources\dashboard-ui\channelitems.html @@ -1128,9 +1131,6 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\multidownload.js - - Resources\dashboard-ui\bower_components\emby-webcomponents\objectassign.js - Resources\dashboard-ui\bower_components\emby-webcomponents\playmenu.js @@ -1155,6 +1155,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\shortcuts.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\thememediaplayer.js + Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js @@ -1566,6 +1569,15 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\playlisteditor\playlisteditor.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\array.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\bind.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\objectassign.js + Resources\dashboard-ui\bower_components\emby-webcomponents\prompt\nativeprompt.js @@ -1773,6 +1785,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\subtitleeditor\subtitleeditor.template.html + + Resources\dashboard-ui\bower_components\emby-webcomponents\sync\sync.js + Resources\dashboard-ui\bower_components\emby-webcomponents\toast\toast.css @@ -1860,36 +1875,6 @@ Resources\dashboard-ui\bower_components\fetch\fetch.js - - Resources\dashboard-ui\bower_components\fingerprintjs2\.bower.json - - - Resources\dashboard-ui\bower_components\fingerprintjs2\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\fingerprintjs2\FAQ.md - - - Resources\dashboard-ui\bower_components\fingerprintjs2\README.md - - - Resources\dashboard-ui\bower_components\fingerprintjs2\bower.json - - - Resources\dashboard-ui\bower_components\fingerprintjs2\fingerprint2.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\gulpfile.js - - - Resources\dashboard-ui\bower_components\fingerprintjs2\index.html - - - Resources\dashboard-ui\bower_components\fingerprintjs2\package.json - - - Resources\dashboard-ui\bower_components\fingerprintjs2\dist\fingerprint2.min.js - Resources\dashboard-ui\bower_components\font-roboto\.bower.json @@ -2094,45 +2079,6 @@ Resources\dashboard-ui\bower_components\iron-a11y-keys-behavior\test\index.html - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.bower.json - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.gitignore - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\README.md - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\bower.json - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\hero.svg - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\index.html - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\iron-autogrow-textarea.html - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-autogrow-textarea\test\index.html - Resources\dashboard-ui\bower_components\iron-behaviors\.bower.json @@ -2502,51 +2448,6 @@ Resources\dashboard-ui\bower_components\iron-iconset-svg\test\iron-iconset-svg.html - - Resources\dashboard-ui\bower_components\iron-input\.bower.json - - - Resources\dashboard-ui\bower_components\iron-input\.gitignore - - - Resources\dashboard-ui\bower_components\iron-input\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-input\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-input\README.md - - - Resources\dashboard-ui\bower_components\iron-input\bower.json - - - Resources\dashboard-ui\bower_components\iron-input\hero.svg - - - Resources\dashboard-ui\bower_components\iron-input\index.html - - - Resources\dashboard-ui\bower_components\iron-input\iron-input.html - - - Resources\dashboard-ui\bower_components\iron-input\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-input\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-input\test\disabled-input.html - - - Resources\dashboard-ui\bower_components\iron-input\test\index.html - - - Resources\dashboard-ui\bower_components\iron-input\test\iron-input.html - - - Resources\dashboard-ui\bower_components\iron-input\test\letters-only.html - Resources\dashboard-ui\bower_components\iron-meta\.bower.json @@ -2574,6 +2475,9 @@ Resources\dashboard-ui\bower_components\iron-meta\iron-meta.html + + Resources\dashboard-ui\bower_components\iron-meta\.github\ISSUE_TEMPLATE.md + Resources\dashboard-ui\bower_components\iron-meta\demo\index.html @@ -2586,45 +2490,6 @@ Resources\dashboard-ui\bower_components\iron-meta\test\iron-meta.html - - Resources\dashboard-ui\bower_components\iron-range-behavior\.bower.json - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.gitignore - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.travis.yml - - - Resources\dashboard-ui\bower_components\iron-range-behavior\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\iron-range-behavior\README.md - - - Resources\dashboard-ui\bower_components\iron-range-behavior\bower.json - - - Resources\dashboard-ui\bower_components\iron-range-behavior\index.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\iron-range-behavior.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\iron-range-behavior\demo\index.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\test\basic.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\test\index.html - - - Resources\dashboard-ui\bower_components\iron-range-behavior\test\x-progressbar.html - Resources\dashboard-ui\bower_components\iron-validatable-behavior\.bower.json @@ -3252,126 +3117,6 @@ Resources\dashboard-ui\bower_components\paper-icon-button\test\index.html - - Resources\dashboard-ui\bower_components\paper-input\.bower.json - - - Resources\dashboard-ui\bower_components\paper-input\.gitignore - - - Resources\dashboard-ui\bower_components\paper-input\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-input\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-input\README.md - - - Resources\dashboard-ui\bower_components\paper-input\all-imports.html - - - Resources\dashboard-ui\bower_components\paper-input\bower.json - - - Resources\dashboard-ui\bower_components\paper-input\hero.svg - - - Resources\dashboard-ui\bower_components\paper-input\index.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-addon-behavior.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-behavior.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-char-counter.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-container.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input-error.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-input.html - - - Resources\dashboard-ui\bower_components\paper-input\paper-textarea.html - - - Resources\dashboard-ui\bower_components\paper-input\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-input\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-input\demo\ssn-input.html - - - Resources\dashboard-ui\bower_components\paper-input\demo\ssn-validator.html - - - Resources\dashboard-ui\bower_components\paper-input\test\index.html - - - Resources\dashboard-ui\bower_components\paper-input\test\letters-only.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-char-counter.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-container.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input-error.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-input.html - - - Resources\dashboard-ui\bower_components\paper-input\test\paper-textarea.html - - - Resources\dashboard-ui\bower_components\paper-progress\.bower.json - - - Resources\dashboard-ui\bower_components\paper-progress\.gitignore - - - Resources\dashboard-ui\bower_components\paper-progress\.travis.yml - - - Resources\dashboard-ui\bower_components\paper-progress\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\paper-progress\README.md - - - Resources\dashboard-ui\bower_components\paper-progress\bower.json - - - Resources\dashboard-ui\bower_components\paper-progress\hero.svg - - - Resources\dashboard-ui\bower_components\paper-progress\index.html - - - Resources\dashboard-ui\bower_components\paper-progress\paper-progress.html - - - Resources\dashboard-ui\bower_components\paper-progress\.github\ISSUE_TEMPLATE.md - - - Resources\dashboard-ui\bower_components\paper-progress\demo\index.html - - - Resources\dashboard-ui\bower_components\paper-progress\test\basic.html - - - Resources\dashboard-ui\bower_components\paper-progress\test\index.html - Resources\dashboard-ui\bower_components\paper-ripple\.bower.json @@ -3729,6 +3474,9 @@ Resources\dashboard-ui\components\tvproviders\xmltv.template.html + + Resources\dashboard-ui\css\autoorganizetable.css + Resources\dashboard-ui\css\chromecast.css @@ -3801,6 +3549,9 @@ Resources\dashboard-ui\css\images\rotten.png + + Resources\dashboard-ui\css\images\throbber.gif + Resources\dashboard-ui\css\images\userflyoutdefault.png @@ -3987,6 +3738,48 @@ Resources\dashboard-ui\css\images\userdata\password.png + + Resources\dashboard-ui\dashboard\aboutpage.js + + + Resources\dashboard-ui\dashboard\autoorganizelog.js + + + Resources\dashboard-ui\dashboard\autoorganizesmart.js + + + Resources\dashboard-ui\dashboard\autoorganizetv.js + + + Resources\dashboard-ui\dashboard\cinemamodeconfiguration.js + + + Resources\dashboard-ui\dashboard\dashboardgeneral.js + + + Resources\dashboard-ui\dashboard\dashboardhosting.js + + + Resources\dashboard-ui\dashboard\devicesupload.js + + + Resources\dashboard-ui\dashboard\librarydisplay.js + + + Resources\dashboard-ui\dashboard\librarysettings.js + + + Resources\dashboard-ui\dashboard\livetvtunerprovider-satip.js + + + Resources\dashboard-ui\dashboard\logpage.js + + + Resources\dashboard-ui\dashboard\wizardcomponents.js + + + Resources\dashboard-ui\dashboard\wizardfinishpage.js + Resources\dashboard-ui\devices\android\android.css @@ -4008,9 +3801,6 @@ Resources\dashboard-ui\legacy\selectmenu.js - - Resources\dashboard-ui\scripts\aboutpage.js - Resources\dashboard-ui\scripts\addpluginpage.js @@ -4020,14 +3810,8 @@ Resources\dashboard-ui\scripts\autobackdrops.js - - Resources\dashboard-ui\scripts\autoorganizelog.js - - - Resources\dashboard-ui\scripts\autoorganizesmart.js - - - Resources\dashboard-ui\scripts\autoorganizetv.js + + Resources\dashboard-ui\scripts\camerauploadsettings.js Resources\dashboard-ui\scripts\channelitems.js @@ -4041,18 +3825,9 @@ Resources\dashboard-ui\scripts\chromecast.js - - Resources\dashboard-ui\scripts\cinemamodeconfiguration.js - Resources\dashboard-ui\scripts\connectlogin.js - - Resources\dashboard-ui\scripts\dashboardgeneral.js - - - Resources\dashboard-ui\scripts\dashboardhosting.js - Resources\dashboard-ui\scripts\dashboardpage.js @@ -4062,9 +3837,6 @@ Resources\dashboard-ui\scripts\devices.js - - Resources\dashboard-ui\scripts\devicesupload.js - Resources\dashboard-ui\scripts\dlnaprofile.js @@ -4140,18 +3912,12 @@ Resources\dashboard-ui\scripts\librarybrowser.js - - Resources\dashboard-ui\scripts\librarydisplay.js - Resources\dashboard-ui\scripts\librarymenu.js Resources\dashboard-ui\scripts\librarypathmapping.js - - Resources\dashboard-ui\scripts\librarysettings.js - Resources\dashboard-ui\scripts\livetvchannel.js @@ -4197,18 +3963,12 @@ Resources\dashboard-ui\scripts\livetvtunerprovider-m3u.js - - Resources\dashboard-ui\scripts\livetvtunerprovider-satip.js - Resources\dashboard-ui\scripts\localsync.js Resources\dashboard-ui\scripts\loginpage.js - - Resources\dashboard-ui\scripts\logpage.js - Resources\dashboard-ui\scripts\mediacontroller.js @@ -4371,9 +4131,6 @@ Resources\dashboard-ui\scripts\supporterkeypage.js - - Resources\dashboard-ui\scripts\sync.js - Resources\dashboard-ui\scripts\syncactivity.js @@ -4386,9 +4143,6 @@ Resources\dashboard-ui\scripts\taskbutton.js - - Resources\dashboard-ui\scripts\thememediaplayer.js - Resources\dashboard-ui\scripts\tvgenres.js @@ -4431,15 +4185,9 @@ Resources\dashboard-ui\scripts\wizardagreement.js - - Resources\dashboard-ui\scripts\wizardcomponents.js - Resources\dashboard-ui\scripts\wizardcontroller.js - - Resources\dashboard-ui\scripts\wizardfinishpage.js - Resources\dashboard-ui\scripts\wizardlivetvguide.js From f5a6a418f58b26f49ff8fc17c32e391f79565105 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 00:54:06 -0400 Subject: [PATCH 203/220] update scaling with MaxHeight --- Emby.Drawing/GDI/DynamicImageHelpers.cs | 4 ++-- Emby.Drawing/GDI/GDIImageEncoder.cs | 8 +++++--- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Emby.Drawing/GDI/DynamicImageHelpers.cs b/Emby.Drawing/GDI/DynamicImageHelpers.cs index e0ce901200..59340af8a9 100644 --- a/Emby.Drawing/GDI/DynamicImageHelpers.cs +++ b/Emby.Drawing/GDI/DynamicImageHelpers.cs @@ -34,7 +34,7 @@ namespace Emby.Drawing.GDI graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - // This causes the image to be blank in OSX + // SourceCopy causes the image to be blank in OSX //graphics.CompositingMode = CompositingMode.SourceCopy; for (var row = 0; row < rows; row++) @@ -83,7 +83,7 @@ namespace Emby.Drawing.GDI graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - // This causes the image to be blank in OSX + // SourceCopy causes the image to be blank in OSX //graphics.CompositingMode = CompositingMode.SourceCopy; for (var row = 0; row < rows; row++) diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index bdd1c5a22f..afd16899dc 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -119,9 +119,11 @@ namespace Emby.Drawing.GDI thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality; thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic; thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality; - thumbnailGraph.CompositingMode = !hasPostProcessing ? - CompositingMode.SourceCopy : - CompositingMode.SourceOver; + + // SourceCopy causes the image to be blank in OSX + //thumbnailGraph.CompositingMode = !hasPostProcessing ? + // CompositingMode.SourceCopy : + // CompositingMode.SourceOver; SetBackgroundColor(thumbnailGraph, options); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 6f4b6323d6..a022c83d84 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -644,7 +644,7 @@ namespace MediaBrowser.Api.Playback { var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); + filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam)); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index aaa5593b48..6bf414dfa4 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -978,7 +978,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); - filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); + filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam)); } } From 916bda6f32b8bbf0210f06fbb288b98bd1dfbed1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 02:44:24 -0400 Subject: [PATCH 204/220] fix slow episode responses --- .../Entities/TV/Episode.cs | 44 ++++++++++--------- MediaBrowser.Controller/Entities/TV/Season.cs | 7 ++- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 726390f65e..30379f3ffc 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -135,7 +135,10 @@ namespace MediaBrowser.Controller.Entities.TV [IgnoreDataMember] public Series Series { - get { return FindParent(); } + get + { + return SeriesId.HasValue ? (LibraryManager.GetItemById(SeriesId.Value) as Series) : null; + } } [IgnoreDataMember] @@ -143,24 +146,7 @@ namespace MediaBrowser.Controller.Entities.TV { get { - var season = FindParent(); - - // Episodes directly in series folder - if (season == null) - { - var series = Series; - - if (series != null && ParentIndexNumber.HasValue) - { - var findNumber = ParentIndexNumber.Value; - - season = series.Children - .OfType() - .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == findNumber); - } - } - - return season; + return SeasonId.HasValue ? (LibraryManager.GetItemById(SeasonId.Value) as Season) : null; } } @@ -193,7 +179,23 @@ namespace MediaBrowser.Controller.Entities.TV public Guid? FindSeasonId() { - var season = Season; + var season = FindParent(); + + // Episodes directly in series folder + if (season == null) + { + var series = Series; + + if (series != null && ParentIndexNumber.HasValue) + { + var findNumber = ParentIndexNumber.Value; + + season = series.Children + .OfType() + .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == findNumber); + } + } + return season == null ? (Guid?)null : season.Id; } @@ -263,7 +265,7 @@ namespace MediaBrowser.Controller.Entities.TV public Guid? FindSeriesId() { - var series = Series; + var series = FindParent(); return series == null ? (Guid?)null : series.Id; } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 842b2fd602..cf5d52a2b8 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -99,7 +99,10 @@ namespace MediaBrowser.Controller.Entities.TV [IgnoreDataMember] public Series Series { - get { return FindParent(); } + get + { + return SeriesId.HasValue ? (LibraryManager.GetItemById(SeriesId.Value) as Series) : null; + } } [IgnoreDataMember] @@ -241,7 +244,7 @@ namespace MediaBrowser.Controller.Entities.TV public Guid? FindSeriesId() { - var series = Series; + var series = FindParent(); return series == null ? (Guid?)null : series.Id; } From 93a05271c21496c4df213f1761ddbfae6ffa0b34 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 12:55:57 -0400 Subject: [PATCH 205/220] fix notifications query --- MediaBrowser.Api/Reports/ReportsService.cs | 2 -- .../UserLibrary/BaseItemsByNameService.cs | 2 -- MediaBrowser.Api/UserLibrary/ItemsService.cs | 20 ------------------- MediaBrowser.Controller/Entities/Folder.cs | 6 +++--- MediaBrowser.Model/Querying/ItemFilter.cs | 4 ---- .../Library/Resolvers/Movies/MovieResolver.cs | 6 ------ 6 files changed, 3 insertions(+), 37 deletions(-) diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index d0b6d6e787..cb03d93822 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -275,8 +275,6 @@ namespace MediaBrowser.Api.Reports case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 94a6a7ef13..5381f9004c 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -164,8 +164,6 @@ namespace MediaBrowser.Api.UserLibrary case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index ce7905b42f..681624ba22 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -149,24 +149,6 @@ namespace MediaBrowser.Api.UserLibrary item = user == null ? _libraryManager.RootFolder : user.RootFolder; } - if (!string.IsNullOrEmpty(request.Ids)) - { - var query = GetItemsQuery(request, user); - var specificItems = _libraryManager.GetItemList(query).ToArray(); - if (query.SortBy.Length == 0) - { - var ids = query.ItemIds.ToList(); - - // Try to preserve order - specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); - } - return new QueryResult - { - Items = specificItems.ToArray(), - TotalRecordCount = specificItems.Length - }; - } - // Default list type = children var folder = item as Folder; @@ -289,8 +271,6 @@ namespace MediaBrowser.Api.UserLibrary case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index bea648a3d3..bf47ada0dc 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -891,16 +891,16 @@ namespace MediaBrowser.Controller.Entities { if (query.ItemIds.Length > 0) { - var specificItems = query.ItemIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); + var result = LibraryManager.GetItemsResult(query); if (query.SortBy.Length == 0) { var ids = query.ItemIds.ToList(); // Try to preserve order - specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToList(); + result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); } - return Task.FromResult(PostFilterAndSort(specificItems, query, true, true)); + return Task.FromResult(result); } return GetItemsInternal(query); diff --git a/MediaBrowser.Model/Querying/ItemFilter.cs b/MediaBrowser.Model/Querying/ItemFilter.cs index 83d61ae514..ff28bd08c4 100644 --- a/MediaBrowser.Model/Querying/ItemFilter.cs +++ b/MediaBrowser.Model/Querying/ItemFilter.cs @@ -27,10 +27,6 @@ namespace MediaBrowser.Model.Querying /// IsFavorite = 5, /// - /// The is recently added - /// - IsRecentlyAdded = 6, - /// /// The item is resumable /// IsResumable = 7, diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 6558407538..ee9533d2ac 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -203,12 +203,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies /// Video. protected override Video Resolve(ItemResolveArgs args) { - if (args.Path != null && args.Path.IndexOf("disney", StringComparison.OrdinalIgnoreCase) != -1) - { - var b = true; - var a = b; - } - var collectionType = args.GetCollectionType(); if (IsInvalid(args.Parent, collectionType)) From 2b61894e3ce1c0ec6d188a6be550cf22c2f84fa9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 13:48:16 -0400 Subject: [PATCH 206/220] update translations --- MediaBrowser.Controller/Entities/TV/Episode.cs | 6 ++++-- MediaBrowser.Controller/Entities/TV/Season.cs | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 30379f3ffc..1a02043d6f 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -137,7 +137,8 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return SeriesId.HasValue ? (LibraryManager.GetItemById(SeriesId.Value) as Series) : null; + var seriesId = SeriesId ?? FindSeriesId(); + return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null; } } @@ -146,7 +147,8 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return SeasonId.HasValue ? (LibraryManager.GetItemById(SeasonId.Value) as Season) : null; + var seasonId = SeasonId ?? FindSeasonId(); + return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null; } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index cf5d52a2b8..65b7c9955b 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -101,7 +101,8 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return SeriesId.HasValue ? (LibraryManager.GetItemById(SeriesId.Value) as Series) : null; + var seriesId = SeriesId ?? FindSeriesId(); + return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null; } } From 86bc77fd6aa9f366e29cd789de112e4f1f6e7fd9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 17:30:35 -0400 Subject: [PATCH 207/220] fix update level migration --- .../Updates/GithubUpdater.cs | 63 +++++++++++++++++++ .../Migrations/UpdateLevelMigration.cs | 57 ++++++++--------- 2 files changed, 92 insertions(+), 28 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index a118f7c265..6281ab3edb 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -78,6 +78,69 @@ namespace MediaBrowser.Common.Implementations.Updates }; } + private bool MatchesUpdateLevel(RootObject i, PackageVersionClass updateLevel) + { + if (updateLevel == PackageVersionClass.Beta) + { + return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase); + } + if (updateLevel == PackageVersionClass.Dev) + { + return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) || + i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase); + } + + // Technically all we need to do is check that it's not pre-release + // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly. + return !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) && + !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase); + } + + public async Task> GetLatestReleases(string organzation, string repository, string assetFilename, CancellationToken cancellationToken) + { + var list = new List(); + + 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(stream); + + obj = obj.Where(i => (i.assets ?? new List()).Any(a => IsAsset(a, assetFilename))).ToArray(); + + list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Release)).OrderByDescending(GetVersion).Take(1)); + list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Beta)).OrderByDescending(GetVersion).Take(1)); + list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Dev)).OrderByDescending(GetVersion).Take(1)); + + return list; + } + } + + public Version GetVersion(RootObject obj) + { + Version version; + if (!Version.TryParse(obj.tag_name, out version)) + { + return new Version(1, 0); + } + + return version; + } + private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename) { Version version; diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs index fa354065c3..948fe114ae 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -41,16 +41,7 @@ namespace MediaBrowser.Server.Startup.Common.Migrations { var updateLevel = _config.Configuration.SystemUpdateLevel; - // Go down a level - if (updateLevel == PackageVersionClass.Release) - { - updateLevel = PackageVersionClass.Beta; - } - else if (updateLevel == PackageVersionClass.Beta) - { - updateLevel = PackageVersionClass.Dev; - } - else if (updateLevel == PackageVersionClass.Dev) + if (updateLevel == PackageVersionClass.Dev) { // It's already dev, there's nothing to check return; @@ -66,32 +57,42 @@ namespace MediaBrowser.Server.Startup.Common.Migrations private async Task CheckVersion(Version currentVersion, PackageVersionClass updateLevel, CancellationToken cancellationToken) { - var result = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(5)) - .CheckForUpdateResult("MediaBrowser", "Emby", currentVersion, PackageVersionClass.Beta, _releaseAssetFilename, "MBServer", "Mbserver.zip", - cancellationToken).ConfigureAwait(false); + var releases = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(5)) + .GetLatestReleases("MediaBrowser", "Emby", _releaseAssetFilename, cancellationToken).ConfigureAwait(false); - if (result != null && result.IsUpdateAvailable) - { - _config.Configuration.SystemUpdateLevel = updateLevel; - _config.SaveConfiguration(); - return; - } + var newUpdateLevel = updateLevel; - // Go down a level - if (updateLevel == PackageVersionClass.Release) + if (releases.Count >= 2) { - updateLevel = PackageVersionClass.Beta; + var beta = releases[1]; + Version version; + if (Version.TryParse(beta.tag_name, out version)) + { + if (currentVersion >= version) + { + newUpdateLevel = PackageVersionClass.Beta; + } + } } - else if (updateLevel == PackageVersionClass.Beta) + + if (releases.Count >= 3) { - updateLevel = PackageVersionClass.Dev; + var dev = releases[2]; + Version version; + if (Version.TryParse(dev.tag_name, out version)) + { + if (currentVersion >= version) + { + newUpdateLevel = PackageVersionClass.Dev; + } + } } - else + + if (newUpdateLevel != updateLevel) { - return; + _config.Configuration.SystemUpdateLevel = newUpdateLevel; + _config.SaveConfiguration(); } - - await CheckVersion(currentVersion, updateLevel, cancellationToken).ConfigureAwait(false); } } } From 6377e7365b94be92e38515beda20a0e6dbabe65f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Aug 2016 13:24:04 -0400 Subject: [PATCH 208/220] fix sync container statuses --- MediaBrowser.Api/ItemUpdateService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 3 + .../Entities/IHasMetadata.cs | 3 + .../Manager/MetadataService.cs | 7 ++ .../Persistence/SqliteItemRepository.cs | 92 ++------------ .../Sync/SyncRepository.cs | 112 +++++++++++++----- .../Migrations/UpdateLevelMigration.cs | 14 ++- 7 files changed, 113 insertions(+), 120 deletions(-) diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index b944a39b6a..2778cfe29c 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -304,7 +304,7 @@ namespace MediaBrowser.Api item.EndDate = request.EndDate.HasValue ? NormalizeDateTime(request.EndDate.Value) : (DateTime?)null; item.PremiereDate = request.PremiereDate.HasValue ? NormalizeDateTime(request.PremiereDate.Value) : (DateTime?)null; item.ProductionYear = request.ProductionYear; - item.OfficialRating = request.OfficialRating; + item.OfficialRating = string.IsNullOrWhiteSpace(request.OfficialRating) ? null : request.OfficialRating; item.CustomRating = request.CustomRating; SetProductionLocations(item, request); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 984374a499..55aaf04ffc 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -781,6 +781,9 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public string OfficialRating { get; set; } + [IgnoreDataMember] + public int InheritedParentalRatingValue { get; set; } + /// /// Gets or sets the critic rating. /// diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 26f425ff0b..cf2f7db64b 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -59,5 +59,8 @@ namespace MediaBrowser.Controller.Entities string GetPresentationUniqueKey(); string CreatePresentationUniqueKey(); bool StopRefreshIfLocalMetadataFound { get; } + + int? GetInheritedParentalRatingValue(); + int InheritedParentalRatingValue { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 2a69948b1a..c535f33baf 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -294,6 +294,13 @@ namespace MediaBrowser.Providers.Manager updateType |= ItemUpdateType.MetadataImport; } + var inheritedParentalRatingValue = item.GetInheritedParentalRatingValue() ?? 0; + if (inheritedParentalRatingValue != item.InheritedParentalRatingValue) + { + item.InheritedParentalRatingValue = inheritedParentalRatingValue; + updateType |= ItemUpdateType.MetadataImport; + } + return updateType; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 5c94d589dc..dc98c346ed 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -92,7 +92,6 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteImagesCommand; private IDbCommand _saveImagesCommand; - private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; public const int LatestSchemaVersion = 109; @@ -412,7 +411,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "SeasonId", "SeriesId", "SeriesSortName", - "PresentationUniqueKey" + "PresentationUniqueKey", + "InheritedParentalRatingValue" }; private readonly string[] _mediaStreamSaveColumns = @@ -611,11 +611,6 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.Parameters.Add(_saveStreamCommand, "@" + col); } - _updateInheritedRatingCommand = _connection.CreateCommand(); - _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid"; - _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid"); - _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue"); - _updateInheritedTagsCommand = _connection.CreateCommand(); _updateInheritedTagsCommand.CommandText = "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid"; _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@Guid"); @@ -1458,6 +1453,12 @@ namespace MediaBrowser.Server.Implementations.Persistence } index++; + if (!reader.IsDBNull(index)) + { + item.InheritedParentalRatingValue = reader.GetInt32(index); + } + index++; + return item; } @@ -3402,7 +3403,6 @@ namespace MediaBrowser.Server.Implementations.Persistence public async Task UpdateInheritedValues(CancellationToken cancellationToken) { - await UpdateInheritedParentalRating(cancellationToken).ConfigureAwait(false); await UpdateInheritedTags(cancellationToken).ConfigureAwait(false); } @@ -3482,82 +3482,6 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - private async Task UpdateInheritedParentalRating(CancellationToken cancellationToken) - { - var newValues = new List>(); - - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(InheritedParentalRatingValue, (select COALESCE(MAX(InheritedParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - var id = reader.GetGuid(0); - var newValue = reader.GetInt32(2); - - newValues.Add(new Tuple(id, newValue)); - } - } - } - - Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count); - if (newValues.Count == 0) - { - return; - } - - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try - { - transaction = _connection.BeginTransaction(); - - foreach (var item in newValues) - { - _updateInheritedRatingCommand.GetParameter(0).Value = item.Item1; - _updateInheritedRatingCommand.GetParameter(1).Value = item.Item2; - - _updateInheritedRatingCommand.Transaction = transaction; - _updateInheritedRatingCommand.ExecuteNonQuery(); - } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - catch (Exception e) - { - Logger.ErrorException("Error running query:", e); - - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } - - WriteLock.Release(); - } - } - private static Dictionary GetTypeMapDictionary() { var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 6b7bcfa010..8b0a1d5602 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -47,15 +47,18 @@ namespace MediaBrowser.Server.Implementations.Sync string[] queries = { "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Profile TEXT, Quality TEXT, Bitrate INT, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", - "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create index if not exists idx_SyncJobs1 on SyncJobs(TargetId)", "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT, ItemDateModifiedTicks BIGINT)", - "create index if not exists idx_SyncJobItems1 on SyncJobItems(Id)", "drop index if exists idx_SyncJobItems2", "drop index if exists idx_SyncJobItems3", + "drop index if exists idx_SyncJobs1", + "drop index if exists idx_SyncJobs", + "drop index if exists idx_SyncJobItems1", "create index if not exists idx_SyncJobItems4 on SyncJobItems(TargetId,ItemId,Status,Progress,DateCreated)", + "create index if not exists idx_SyncJobItems5 on SyncJobItems(TargetId,Status,ItemId,Progress)", + + "create index if not exists idx_SyncJobs2 on SyncJobs(TargetId,Status,ItemIds,Progress)", "pragma shrink_memory" }; @@ -641,37 +644,24 @@ namespace MediaBrowser.Server.Implementations.Sync cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); } - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + cmd.CommandText += ";" + cmd.CommandText + .Replace("select ItemId,Status,Progress from SyncJobItems", "select ItemIds,Status,Progress from SyncJobs") + .Replace("'Synced'", "'Completed','CompletedWithError'"); + + Logger.Debug(cmd.CommandText); + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { while (reader.Read()) { - var itemId = reader.GetString(0); + AddStatusResult(reader, result, false); + } - if (!reader.IsDBNull(1)) + if (reader.NextResult()) + { + while (reader.Read()) { - var status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(1), true); - - if (status == SyncJobItemStatus.Synced) - { - result[itemId] = new SyncedItemProgress - { - Status = SyncJobItemStatus.Synced - }; - } - else - { - SyncedItemProgress currentStatus; - double progress = reader.IsDBNull(2) ? 0.0 : reader.GetDouble(2); - - if (!result.TryGetValue(itemId, out currentStatus) || (currentStatus.Status != SyncJobItemStatus.Synced && progress >= currentStatus.Progress)) - { - result[itemId] = new SyncedItemProgress - { - Status = status, - Progress = progress - }; - } - } + AddStatusResult(reader, result, true); } } } @@ -681,6 +671,70 @@ namespace MediaBrowser.Server.Implementations.Sync return result; } + private void AddStatusResult(IDataReader reader, Dictionary result, bool multipleIds) + { + if (reader.IsDBNull(0)) + { + return; + } + + var itemIds = new List(); + + var ids = reader.GetString(0); + + if (multipleIds) + { + itemIds = ids.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + else + { + itemIds.Add(ids); + } + + if (!reader.IsDBNull(1)) + { + SyncJobItemStatus status; + var statusString = reader.GetString(1); + if (string.Equals(statusString, "Completed", StringComparison.OrdinalIgnoreCase) || + string.Equals(statusString, "CompletedWithError", StringComparison.OrdinalIgnoreCase)) + { + status = SyncJobItemStatus.Synced; + } + else + { + status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), statusString, true); + } + + if (status == SyncJobItemStatus.Synced) + { + foreach (var itemId in itemIds) + { + result[itemId] = new SyncedItemProgress + { + Status = SyncJobItemStatus.Synced + }; + } + } + else + { + double progress = reader.IsDBNull(2) ? 0.0 : reader.GetDouble(2); + + foreach (var itemId in itemIds) + { + SyncedItemProgress currentStatus; + if (!result.TryGetValue(itemId, out currentStatus) || (currentStatus.Status != SyncJobItemStatus.Synced && progress >= currentStatus.Progress)) + { + result[itemId] = new SyncedItemProgress + { + Status = status, + Progress = progress + }; + } + } + } + } + } + public QueryResult GetJobItems(SyncJobItemQuery query) { return GetJobItemReader(query, BaseJobItemSelectText, GetJobItem); diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs index 948fe114ae..6d22aaed02 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -62,11 +62,12 @@ namespace MediaBrowser.Server.Startup.Common.Migrations var newUpdateLevel = updateLevel; - if (releases.Count >= 2) + // If the current version is later than current stable, set the update level to beta + if (releases.Count >= 1) { - var beta = releases[1]; + var release = releases[0]; Version version; - if (Version.TryParse(beta.tag_name, out version)) + if (Version.TryParse(release.tag_name, out version)) { if (currentVersion >= version) { @@ -75,11 +76,12 @@ namespace MediaBrowser.Server.Startup.Common.Migrations } } - if (releases.Count >= 3) + // If the current version is later than current beta, set the update level to dev + if (releases.Count >= 2) { - var dev = releases[2]; + var release = releases[1]; Version version; - if (Version.TryParse(dev.tag_name, out version)) + if (Version.TryParse(release.tag_name, out version)) { if (currentVersion >= version) { From 510fbf139cf1df9ba7659351d96cf74eb92c0b23 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Aug 2016 15:29:28 -0400 Subject: [PATCH 209/220] fix repeated guide refreshes --- .../LiveTv/ILiveTvManager.cs | 5 ++- MediaBrowser.Model/Dlna/StreamBuilder.cs | 2 +- .../LiveTv/LiveTvManager.cs | 7 ++-- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 4 +-- .../Sync/SyncRepository.cs | 32 ++++++++++++++++++- .../Migrations/UpdateLevelMigration.cs | 4 +-- MediaBrowser.ServerApplication/MainStartup.cs | 2 +- 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index fe69b38cb0..ed64127c38 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -331,12 +331,11 @@ namespace MediaBrowser.Controller.LiveTv /// The user. /// Task. Task AddInfoToProgramDto(List> programs, List fields, User user = null); + /// /// Saves the tuner host. /// - /// The information. - /// Task. - Task SaveTunerHost(TunerHostInfo info); + Task SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true); /// /// Saves the listing provider. /// diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index d042125b9b..13d5597738 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -602,7 +602,7 @@ namespace MediaBrowser.Model.Dlna private int GetAudioBitrate(string subProtocol, int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) { - var defaultBitrate = audioStream.BitRate ?? 192000; + var defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? 192000; // Reduce the bitrate if we're downmixing if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index ccbcb910d3..88017aa59d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2475,7 +2475,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return await _libraryManager.GetNamedView(name, CollectionType.LiveTv, name, cancellationToken).ConfigureAwait(false); } - public async Task SaveTunerHost(TunerHostInfo info) + public async Task SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true) { info = (TunerHostInfo)_jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info), typeof(TunerHostInfo)); @@ -2508,7 +2508,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv _config.SaveConfiguration("livetv", config); - _taskManager.CancelIfRunningAndQueue(); + if (dataSourceChanged) + { + _taskManager.CancelIfRunningAndQueue(); + } return info; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 43f48b37bf..9d5dba2823 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -111,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp M3UUrl = info.M3UUrl, IsEnabled = true - }).ConfigureAwait(false); + }, true).ConfigureAwait(false); } else { @@ -120,7 +120,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp existing.M3UUrl = info.M3UUrl; existing.FriendlyName = info.FriendlyName; existing.Tuners = info.Tuners; - await _liveTvManager.SaveTunerHost(existing).ConfigureAwait(false); + await _liveTvManager.SaveTunerHost(existing, false).ConfigureAwait(false); } } catch (OperationCanceledException) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 8b0a1d5602..64ed00ded1 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -618,6 +618,8 @@ namespace MediaBrowser.Server.Implementations.Sync { var result = new Dictionary(); + var now = DateTime.UtcNow; + using (var connection = CreateConnection(true).Result) { using (var cmd = connection.CreateCommand()) @@ -648,10 +650,12 @@ namespace MediaBrowser.Server.Implementations.Sync .Replace("select ItemId,Status,Progress from SyncJobItems", "select ItemIds,Status,Progress from SyncJobs") .Replace("'Synced'", "'Completed','CompletedWithError'"); - Logger.Debug(cmd.CommandText); + //Logger.Debug(cmd.CommandText); using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { + LogQueryTime("GetSyncedItemProgresses", cmd, now); + while (reader.Read()) { AddStatusResult(reader, result, false); @@ -671,6 +675,32 @@ namespace MediaBrowser.Server.Implementations.Sync return result; } + private void LogQueryTime(string methodName, IDbCommand cmd, DateTime startDate) + { + var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds; + + var slowThreshold = 1000; + +#if DEBUG + slowThreshold = 50; +#endif + + if (elapsed >= slowThreshold) + { + Logger.Debug("{2} query time (slow): {0}ms. Query: {1}", + Convert.ToInt32(elapsed), + cmd.CommandText, + methodName); + } + else + { + //Logger.Debug("{2} query time: {0}ms. Query: {1}", + // Convert.ToInt32(elapsed), + // cmd.CommandText, + // methodName); + } + } + private void AddStatusResult(IDataReader reader, Dictionary result, bool multipleIds) { if (reader.IsDBNull(0)) diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs index 6d22aaed02..5212b8ac3e 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -69,7 +69,7 @@ namespace MediaBrowser.Server.Startup.Common.Migrations Version version; if (Version.TryParse(release.tag_name, out version)) { - if (currentVersion >= version) + if (currentVersion > version) { newUpdateLevel = PackageVersionClass.Beta; } @@ -83,7 +83,7 @@ namespace MediaBrowser.Server.Startup.Common.Migrations Version version; if (Version.TryParse(release.tag_name, out version)) { - if (currentVersion >= version) + if (currentVersion > version) { newUpdateLevel = PackageVersionClass.Dev; } diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index c40e633749..8f153f33fe 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -163,7 +163,7 @@ namespace MediaBrowser.ServerApplication { _logger.Info("Found a duplicate process. Giving it time to exit."); - if (!duplicate.WaitForExit(15000)) + if (!duplicate.WaitForExit(20000)) { _logger.Info("The duplicate process did not exit."); return true; From ae331babed85ad55eb67641fb17f9829f2a3a8bc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Aug 2016 16:37:19 -0400 Subject: [PATCH 210/220] fix version comparison --- .../Migrations/UpdateLevelMigration.cs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs index 5212b8ac3e..ec00fb33de 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -66,13 +66,10 @@ namespace MediaBrowser.Server.Startup.Common.Migrations if (releases.Count >= 1) { var release = releases[0]; - Version version; - if (Version.TryParse(release.tag_name, out version)) + var version = ParseVersion(release.tag_name); + if (version != null && currentVersion > version) { - if (currentVersion > version) - { - newUpdateLevel = PackageVersionClass.Beta; - } + newUpdateLevel = PackageVersionClass.Beta; } } @@ -80,13 +77,10 @@ namespace MediaBrowser.Server.Startup.Common.Migrations if (releases.Count >= 2) { var release = releases[1]; - Version version; - if (Version.TryParse(release.tag_name, out version)) + var version = ParseVersion(release.tag_name); + if (version != null && currentVersion > version) { - if (currentVersion > version) - { - newUpdateLevel = PackageVersionClass.Dev; - } + newUpdateLevel = PackageVersionClass.Dev; } } @@ -96,5 +90,19 @@ namespace MediaBrowser.Server.Startup.Common.Migrations _config.SaveConfiguration(); } } + + private Version ParseVersion(string versionString) + { + var parts = versionString.Split('.'); + if (parts.Length == 3) + { + versionString += ".0"; + } + + Version version; + Version.TryParse(versionString, out version); + + return version; + } } } From cf64c404135381a5e56d386003eb245386428756 Mon Sep 17 00:00:00 2001 From: softworkz Date: Mon, 22 Aug 2016 23:52:54 +0200 Subject: [PATCH 211/220] AutoorganizeLog: Fixed error when log empty; re-introduced full reload on task completion --- .../ScheduledTasks/ScheduledTaskWorker.cs | 11 ------- .../FileOrganizationNotifier.cs | 30 +++++++++++++------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index dcd3a3025e..ab2aa761b5 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -429,17 +429,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks GC.Collect(2, GCCollectionMode.Forced, true); } - /// - /// Executes the task. - /// - /// The cancellation token. - /// The progress. - /// Task. - private Task ExecuteTask(CancellationToken cancellationToken, IProgress progress) - { - return Task.Run(async () => await ScheduledTask.Execute(cancellationToken, progress).ConfigureAwait(false), cancellationToken); - } - /// /// Progress_s the progress changed. /// diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs index 38b90647c1..a81584082e 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs @@ -1,14 +1,11 @@ -using MediaBrowser.Controller.FileOrganization; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.Events; using MediaBrowser.Model.FileOrganization; -using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Logging; +using System; using System.Threading; namespace MediaBrowser.Server.Implementations.FileOrganization @@ -20,11 +17,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { private readonly IFileOrganizationService _organizationService; private readonly ISessionManager _sessionManager; + private readonly ITaskManager _taskManager; - public FileOrganizationNotifier(ILogger logger, IFileOrganizationService organizationService, ISessionManager sessionManager) + public FileOrganizationNotifier(ILogger logger, IFileOrganizationService organizationService, ISessionManager sessionManager, ITaskManager taskManager) { _organizationService = organizationService; _sessionManager = sessionManager; + _taskManager = taskManager; } public void Run() @@ -33,6 +32,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _organizationService.ItemRemoved += _organizationService_ItemRemoved; _organizationService.ItemUpdated += _organizationService_ItemUpdated; _organizationService.LogReset += _organizationService_LogReset; + + _taskManager.TaskCompleted += _taskManager_TaskCompleted; } private void _organizationService_LogReset(object sender, EventArgs e) @@ -55,12 +56,23 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); } + private void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) + { + var taskWithKey = e.Task.ScheduledTask as IHasKey; + if (taskWithKey != null && taskWithKey.Key == "AutoOrganize") + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + } + public void Dispose() { _organizationService.ItemAdded -= _organizationService_ItemAdded; _organizationService.ItemRemoved -= _organizationService_ItemRemoved; _organizationService.ItemUpdated -= _organizationService_ItemUpdated; _organizationService.LogReset -= _organizationService_LogReset; + + _taskManager.TaskCompleted -= _taskManager_TaskCompleted; } From 803a96cb4e6e2643f683f43c4dd9bbf6c2cc0f68 Mon Sep 17 00:00:00 2001 From: softworkz Date: Tue, 23 Aug 2016 05:35:59 +0200 Subject: [PATCH 212/220] AutoOrganize: Differentiate server events --- .../FileOrganizationNotifier.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs index a81584082e..5c3814f669 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs @@ -33,37 +33,37 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _organizationService.ItemUpdated += _organizationService_ItemUpdated; _organizationService.LogReset += _organizationService_LogReset; - _taskManager.TaskCompleted += _taskManager_TaskCompleted; + //_taskManager.TaskCompleted += _taskManager_TaskCompleted; } private void _organizationService_LogReset(object sender, EventArgs e) { - _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + _sessionManager.SendMessageToAdminSessions("AutoOrganize_LogReset", (FileOrganizationResult)null, CancellationToken.None); } private void _organizationService_ItemUpdated(object sender, GenericEventArgs e) { - _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", e.Argument, CancellationToken.None); + _sessionManager.SendMessageToAdminSessions("AutoOrganize_ItemUpdated", e.Argument, CancellationToken.None); } private void _organizationService_ItemRemoved(object sender, GenericEventArgs e) { - _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + _sessionManager.SendMessageToAdminSessions("AutoOrganize_ItemRemoved", e.Argument, CancellationToken.None); } private void _organizationService_ItemAdded(object sender, GenericEventArgs e) { - _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + _sessionManager.SendMessageToAdminSessions("AutoOrganize_ItemAdded", e.Argument, CancellationToken.None); } - private void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - var taskWithKey = e.Task.ScheduledTask as IHasKey; - if (taskWithKey != null && taskWithKey.Key == "AutoOrganize") - { - _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); - } - } + //private void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) + //{ + // var taskWithKey = e.Task.ScheduledTask as IHasKey; + // if (taskWithKey != null && taskWithKey.Key == "AutoOrganize") + // { + // _sessionManager.SendMessageToAdminSessions("AutoOrganize_TaskCompleted", (FileOrganizationResult)null, CancellationToken.None); + // } + //} public void Dispose() { @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _organizationService.ItemUpdated -= _organizationService_ItemUpdated; _organizationService.LogReset -= _organizationService_LogReset; - _taskManager.TaskCompleted -= _taskManager_TaskCompleted; + //_taskManager.TaskCompleted -= _taskManager_TaskCompleted; } From 4fa0df37e28d88f789bb978bbb4757241fd5dceb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Aug 2016 00:35:06 -0400 Subject: [PATCH 213/220] fix fields that shouldn't be required --- MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs index 6380b9f53b..bf6df2347f 100644 --- a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs @@ -64,25 +64,25 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteElementString("aired", episode.PremiereDate.Value.ToLocalTime().ToString(formatString)); } - if (episode.AirsAfterSeasonNumber.HasValue) + if (episode.AirsAfterSeasonNumber.HasValue && episode.AirsAfterSeasonNumber.Value != -1) { writer.WriteElementString("airsafter_season", episode.AirsAfterSeasonNumber.Value.ToString(UsCulture)); } - if (episode.AirsBeforeEpisodeNumber.HasValue) + if (episode.AirsBeforeEpisodeNumber.HasValue && episode.AirsBeforeEpisodeNumber.Value != -1) { writer.WriteElementString("airsbefore_episode", episode.AirsBeforeEpisodeNumber.Value.ToString(UsCulture)); } - if (episode.AirsBeforeEpisodeNumber.HasValue) + if (episode.AirsBeforeEpisodeNumber.HasValue && episode.AirsBeforeEpisodeNumber.Value != -1) { writer.WriteElementString("displayepisode", episode.AirsBeforeEpisodeNumber.Value.ToString(UsCulture)); } - if (episode.AirsBeforeSeasonNumber.HasValue) + if (episode.AirsBeforeSeasonNumber.HasValue && episode.AirsBeforeSeasonNumber.Value != -1) { writer.WriteElementString("airsbefore_season", episode.AirsBeforeSeasonNumber.Value.ToString(UsCulture)); } var season = episode.AiredSeasonNumber; - if (season.HasValue) + if (season.HasValue && season.Value != -1) { writer.WriteElementString("displayseason", season.Value.ToString(UsCulture)); } From 73bafa7cda7d341a347b4f56681d7efebe756618 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Aug 2016 12:47:09 -0400 Subject: [PATCH 214/220] fix saving of IsVirtualItem --- MediaBrowser.Server.Implementations/Library/UserViewManager.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 319e715c33..5fffa3d1fb 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -283,7 +283,7 @@ namespace MediaBrowser.Server.Implementations.Library ExcludeItemTypes = excludeItemTypes, ExcludeLocationTypes = new[] { LocationType.Virtual }, Limit = limit * 5, - ExcludeSourceTypes = parentIds.Length == 0 ? new[] { SourceType.Channel, SourceType.LiveTV } : new SourceType[] { }, + SourceTypes = parentIds.Length == 0 ? new[] { SourceType.Library } : new SourceType[] { }, IsPlayed = request.IsPlayed }, parentIds); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index dc98c346ed..5ece3dd826 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -937,7 +937,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.Album; - _saveItemCommand.GetParameter(index++).Value = item.IsVirtualItem || (!item.IsFolder && item.LocationType == LocationType.Virtual); + _saveItemCommand.GetParameter(index++).Value = item.IsVirtualItem; var hasSeries = item as IHasSeries; if (hasSeries != null) From d68e9841207e6681b9b78c560ccee889fb1173fa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Aug 2016 13:27:48 -0400 Subject: [PATCH 215/220] add new sony dlna profiles --- MediaBrowser.Dlna/DlnaManager.cs | 5 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 10 +- ...2013Profile.cs => SonyBlurayPlayer2013.cs} | 4 +- .../Profiles/SonyBlurayPlayer2014.cs | 187 ++++++++++++++++++ .../Profiles/SonyBlurayPlayer2015.cs | 187 ++++++++++++++++++ .../Profiles/SonyBlurayPlayer2016.cs | 187 ++++++++++++++++++ MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Default.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml | 8 +- .../Profiles/Xml/DirecTV HD-DVR.xml | 6 +- .../Profiles/Xml/Dish Hopper-Joey.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Kodi.xml | 10 +- .../Profiles/Xml/LG Smart TV.xml | 8 +- .../Profiles/Xml/Linksys DMA2100.xml | 8 +- .../Profiles/Xml/MediaMonkey.xml | 8 +- .../Profiles/Xml/Panasonic Viera.xml | 8 +- .../Profiles/Xml/Popcorn Hour.xml | 8 +- .../Profiles/Xml/Samsung Smart TV.xml | 8 +- .../Profiles/Xml/Sony Blu-ray Player 2013.xml | 8 +- .../Profiles/Xml/Sony Blu-ray Player 2014.xml | 81 ++++++++ .../Profiles/Xml/Sony Blu-ray Player 2015.xml | 81 ++++++++ .../Profiles/Xml/Sony Blu-ray Player 2016.xml | 81 ++++++++ .../Profiles/Xml/Sony Blu-ray Player.xml | 8 +- .../Profiles/Xml/Sony Bravia (2010).xml | 8 +- .../Profiles/Xml/Sony Bravia (2011).xml | 8 +- .../Profiles/Xml/Sony Bravia (2012).xml | 8 +- .../Profiles/Xml/Sony Bravia (2013).xml | 8 +- .../Profiles/Xml/Sony Bravia (2014).xml | 8 +- .../Profiles/Xml/Sony PlayStation 3.xml | 8 +- .../Profiles/Xml/Sony PlayStation 4.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Vlc.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 8 +- MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml | 8 +- 35 files changed, 923 insertions(+), 108 deletions(-) rename MediaBrowser.Dlna/Profiles/{SonyBlurayPlayer2013Profile.cs => SonyBlurayPlayer2013.cs} (99%) create mode 100644 MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index a01d73451e..5f4c34bb77 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -566,7 +566,10 @@ namespace MediaBrowser.Dlna new SonyBravia2012Profile(), new SonyBravia2013Profile(), new SonyBravia2014Profile(), - new SonyBlurayPlayer2013Profile(), + new SonyBlurayPlayer2013(), + new SonyBlurayPlayer2014(), + new SonyBlurayPlayer2015(), + new SonyBlurayPlayer2016(), new SonyBlurayPlayerProfile(), new PanasonicVieraProfile(), new WdtvLiveProfile(), diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 9df9c0a252..d10a5f7b5a 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -94,6 +94,9 @@ + + + @@ -137,7 +140,7 @@ - + @@ -244,6 +247,11 @@ + + + + +