From 9fc0db643f5eb773f28a2ed34e623e446af71395 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 9 Jan 2016 16:27:43 -0500 Subject: [PATCH 001/214] add ConnectUser property --- MediaBrowser.Model/Connect/ConnectUser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/Connect/ConnectUser.cs b/MediaBrowser.Model/Connect/ConnectUser.cs index da290da12..383261a6b 100644 --- a/MediaBrowser.Model/Connect/ConnectUser.cs +++ b/MediaBrowser.Model/Connect/ConnectUser.cs @@ -8,5 +8,6 @@ namespace MediaBrowser.Model.Connect public string Email { get; set; } public bool IsActive { get; set; } public string ImageUrl { get; set; } + public bool IsSupporter { get; set; } } } From d815582ea844f77ff3e3c1b019de4ae8a41072e1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 10 Jan 2016 12:36:38 -0500 Subject: [PATCH 002/214] hide restart if not specified --- MediaBrowser.Server.Mono/Native/NativeApp.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs index 500555647..c73a96497 100644 --- a/MediaBrowser.Server.Mono/Native/NativeApp.cs +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -28,7 +28,8 @@ namespace MediaBrowser.Server.Mono.Native { get { - return true; + // A restart script must be provided + return StartupOptions.ContainsOption("-restartpath"); } } From 3f17949f252ec5dbc3fd00223eea1da81c0a49e4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 11 Jan 2016 11:53:54 -0500 Subject: [PATCH 003/214] update ps3 dlna profile --- MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs | 2 +- MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs index a99d7775a..6ad2b3fca 100644 --- a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Dlna.Profiles { Container = "ts", VideoCodec = "h264", - AudioCodec = "mp3", + AudioCodec = "ac3,aac,mp3", Type = DlnaProfileType.Video }, new TranscodingProfile diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index 5d6e72000..ce34dd5f2 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -48,7 +48,7 @@ - + From 72120e0de5430cec167ee200b1c6880a4898e33d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 11 Jan 2016 21:38:43 -0500 Subject: [PATCH 004/214] ensure recording filename is unique --- .../LiveTv/EmbyTV/RecordingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 3ee808bb5..a5c869d45 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } else { - name += " " + info.StartDate.ToString("yyyy-MM-dd"); + name += " " + info.StartDate.ToString("yyyy-MM-dd") + " " + info.Id; } return name; From 06633d9fdf588b819e60ac576c294545e006c278 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 11 Jan 2016 12:16:46 -0500 Subject: [PATCH 005/214] update translations --- MediaBrowser.Server.Implementations/Localization/Core/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 33fd30c36..98039b994 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -154,7 +154,7 @@ "HeaderDisc": "Disc", "HeaderTrack": "Track", "HeaderAudio": "\u00c0udio", - "HeaderVideo": "Video", + "HeaderVideo": "V\u00eddeo", "HeaderEmbeddedImage": "Embedded image", "HeaderResolution": "Resolution", "HeaderSubtitles": "Subtitles", From dbc9beab22a2ec4a9e2680505256cb478550a31f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:12:50 -0500 Subject: [PATCH 006/214] add error handling to package retrieval --- .../Updates/InstallationManager.cs | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index d155f11c7..8e0df9005 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -193,38 +193,37 @@ namespace MediaBrowser.Common.Implementations.Updates /// The cancellation token. /// Task{List{PackageInfo}}. public async Task> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) - { - using (var stream = await GetCachedPackages(cancellationToken).ConfigureAwait(false)) - { - var packages = _jsonSerializer.DeserializeFromStream>(stream).ToList(); - - if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength()) - { - UpdateCachedPackages(CancellationToken.None, false); - } - - return packages; - } - } - - private string PackageCachePath - { - get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); } - } - - private async Task GetCachedPackages(CancellationToken cancellationToken) { try { - return _fileSystem.OpenRead(PackageCachePath); + using (var stream = _fileSystem.OpenRead(PackageCachePath)) + { + var packages = _jsonSerializer.DeserializeFromStream>(stream).ToList(); + + if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength()) + { + UpdateCachedPackages(CancellationToken.None, false); + } + + return packages; + } } catch (Exception) { } + _lastPackageUpdateTime = DateTime.MinValue; await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false); - return _fileSystem.OpenRead(PackageCachePath); + using (var stream = _fileSystem.OpenRead(PackageCachePath)) + { + return _jsonSerializer.DeserializeFromStream>(stream).ToList(); + } + } + + private string PackageCachePath + { + get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); } } private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1); From f3c941ad04b2b23e36f581573dce2af66294cfd3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:19:06 -0500 Subject: [PATCH 007/214] 3.0.5807 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 749c65f73..d6c457d76 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5806")] +[assembly: AssemblyVersion("3.0.5807")] From ab1f5db146557187e7605bfacc13d4e56c1929d3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:49:33 -0500 Subject: [PATCH 008/214] capture conductor --- .../Probing/ProbeResultNormalizer.cs | 10 +++++++++- MediaBrowser.Model/Entities/PersonType.cs | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index d98efffe7..922f4b271 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -440,7 +440,6 @@ namespace MediaBrowser.MediaEncoding.Probing } var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer"); - if (!string.IsNullOrWhiteSpace(composer)) { foreach (var person in Split(composer, false)) @@ -449,6 +448,15 @@ namespace MediaBrowser.MediaEncoding.Probing } } + var conductor = FFProbeHelpers.GetDictionaryValue(tags, "conductor"); + if (!string.IsNullOrWhiteSpace(conductor)) + { + foreach (var person in Split(conductor, false)) + { + audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor }); + } + } + audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album"); var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists"); diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index ee80b1496..bdf846095 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -30,5 +30,9 @@ namespace MediaBrowser.Model.Entities /// The producer /// public const string Producer = "Producer"; + /// + /// The conductor + /// + public const string Conductor = "Conductor"; } } From 234a5ad7123417cc90bbdc7d2bbe298ef4ce8d39 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Jan 2016 15:58:45 -0500 Subject: [PATCH 009/214] add logging --- MediaBrowser.ServerApplication/MainStartup.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index ac6fd1bbe..471bd4c8d 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -591,7 +591,7 @@ namespace MediaBrowser.ServerApplication } catch (Exception ex) { - logger.ErrorException("Error installing ImageMagick", ex); + logger.ErrorException("Error installing Visual Studio C++ runtime", ex); } } @@ -619,6 +619,8 @@ namespace MediaBrowser.ServerApplication ErrorDialog = false }; + _logger.Info("Running {0}", startInfo.FileName); + using (var process = Process.Start(startInfo)) { process.WaitForExit(); From 1a2e5f41d58c9baecf3ec5958bb69286ffc8c399 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Jan 2016 15:59:03 -0500 Subject: [PATCH 010/214] adjust package cache --- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 1d12089f3..b0f37eeef 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -1301,7 +1301,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task{CheckForUpdateResult}. public override async Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) { - var cacheLength = TimeSpan.FromHours(12); + var cacheLength = TimeSpan.FromHours(3); var updateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel; if (updateLevel == PackageVersionClass.Beta) From 5d30bfeb3c69f9c9743b3467fdd3e47e99317881 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Jan 2016 15:59:32 -0500 Subject: [PATCH 011/214] update notify icon --- MediaBrowser.ServerApplication/ServerNotifyIcon.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index e9a7d5985..673c6cddd 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -133,9 +133,22 @@ namespace MediaBrowser.ServerApplication LocalizeText(); notifyIcon1.DoubleClick += notifyIcon1_DoubleClick; + Application.ThreadExit += Application_ThreadExit; Application.ApplicationExit += Application_ApplicationExit; } + void Application_ThreadExit(object sender, EventArgs e) + { + try + { + notifyIcon1.Visible = false; + } + catch + { + + } + } + void Application_ApplicationExit(object sender, EventArgs e) { try From d5c65d016325adc2c448f276711fe99a65e448fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Jan 2016 16:21:39 -0500 Subject: [PATCH 012/214] update interlaced detection --- .../MediaEncoding/IMediaEncoder.cs | 3 +- .../MediaEncoding/MediaInfoRequest.cs | 1 - .../Encoder/MediaEncoder.cs | 34 ++++++++++++------- .../Probing/ProbeResultNormalizer.cs | 1 + MediaBrowser.Model/Entities/MediaStream.cs | 6 ++++ .../MediaInfo/AudioImageProvider.cs | 29 +++++++++++----- 6 files changed, 52 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 427af6f6d..76ef054de 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -35,9 +35,10 @@ namespace MediaBrowser.Controller.MediaEncoding /// Extracts the audio image. /// /// The path. + /// Index of the image stream. /// The cancellation token. /// Task{Stream}. - Task ExtractAudioImage(string path, CancellationToken cancellationToken); + Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken); /// /// Extracts the video image. diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs index 24df7b885..ca0c2fdbb 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs @@ -15,7 +15,6 @@ namespace MediaBrowser.Controller.MediaEncoding public IIsoMount MountedIso { get; set; } public VideoType VideoType { get; set; } public List PlayableStreamFileNames { get; set; } - public bool ExtractKeyFrameInterval { get; set; } public MediaInfoRequest() { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f436ca3a0..ba0790bf3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -307,7 +307,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var args = "{0} -i {1} -map 0:v:{2} -filter:v idet -frames:v 500 -an -f null /dev/null"; + var args = "{0} -i {1} -map 0:v:{2} -an -filter:v idet -frames:v 500 -an -f null /dev/null"; var process = new Process { @@ -447,7 +447,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } - if (((tff + bff) / total) >= .65) + if (((tff + bff) / total) >= .4) { return true; } @@ -472,29 +472,37 @@ namespace MediaBrowser.MediaEncoding.Encoder /// protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public Task ExtractAudioImage(string path, CancellationToken cancellationToken) + public Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); } public Task ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, protocol, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, null, protocol, false, threedFormat, offset, cancellationToken); } - private async Task ExtractImage(string[] inputFiles, MediaProtocol protocol, bool isAudio, + private async Task ExtractImage(string[] inputFiles, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool; var inputArgument = GetInputArgument(inputFiles, protocol); - if (!isAudio) + if (isAudio) + { + if (imageStreamIndex.HasValue && imageStreamIndex.Value > 0) + { + // It seems for audio files we need to subtract 1 (for the audio stream??) + imageStreamIndex = imageStreamIndex.Value - 1; + } + } + else { try { - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { @@ -506,10 +514,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); } - private async Task ExtractImageInternal(string inputPath, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + private async Task ExtractImageInternal(string inputPath, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { @@ -543,9 +551,11 @@ 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} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf) : - string.Format("-i {0} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf); + var args = useIFrame ? string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf, mapArg) : + string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf, mapArg); var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol); diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 922f4b271..31f6af181 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -141,6 +141,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (streamInfo.tags != null) { stream.Language = GetDictionaryValue(streamInfo.tags, "language"); + stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); } if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index d089f0aa9..7f4cc2f84 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -30,6 +30,12 @@ namespace MediaBrowser.Model.Entities /// The language. public string Language { get; set; } + /// + /// Gets or sets the comment. + /// + /// The comment. + public string Comment { get; set; } + /// /// Gets or sets a value indicating whether this instance is interlaced. /// diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 8884412d2..c98a67bbd 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using System; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -43,20 +44,27 @@ namespace MediaBrowser.Providers.MediaInfo { var audio = (Audio)item; + var imageStreams = + audio.GetMediaSources(false) + .Take(1) + .SelectMany(i => i.MediaStreams) + .Where(i => i.Type == MediaStreamType.EmbeddedImage) + .ToList(); + // Can't extract if we didn't find a video stream in the file - if (!audio.GetMediaSources(false).Take(1).SelectMany(i => i.MediaStreams).Any(i => i.Type == MediaStreamType.EmbeddedImage)) + if (imageStreams.Count == 0) { return Task.FromResult(new DynamicImageResponse { HasImage = false }); } - return GetImage((Audio)item, cancellationToken); + return GetImage((Audio)item, imageStreams, cancellationToken); } - public async Task GetImage(Audio item, CancellationToken cancellationToken) + public async Task GetImage(Audio item, List imageStreams, CancellationToken cancellationToken) { var path = GetAudioImagePath(item); - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { var semaphore = GetLock(path); @@ -66,11 +74,16 @@ namespace MediaBrowser.Providers.MediaInfo try { // Check again in case it was saved while waiting for the lock - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false)) + var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ?? + imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1); + + var imageStreamIndex = imageStream == null ? (int?)null : imageStream.Index; + + using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, imageStreamIndex, cancellationToken).ConfigureAwait(false)) { using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { From d438a6f1f846fd5732c9503dba17db38d0c7285b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Jan 2016 23:33:17 -0500 Subject: [PATCH 013/214] increase startup timeout --- MediaBrowser.ServerApplication/MainStartup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 471bd4c8d..62cdbd05f 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -148,7 +148,7 @@ namespace MediaBrowser.ServerApplication { _logger.Info("Found a duplicate process. Giving it time to exit."); - if (!duplicate.WaitForExit(10000)) + if (!duplicate.WaitForExit(12000)) { _logger.Info("The duplicate process did not exit."); return true; From 3e1058995c18058870104ef819774f3015864beb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 00:24:00 -0500 Subject: [PATCH 014/214] 3.0.5808 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d6c457d76..ee28d01c9 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5807")] +[assembly: AssemblyVersion("3.0.5808")] From 56763c08a2be6594457e1fffea1eda791c187f9c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:12:50 -0500 Subject: [PATCH 015/214] add error handling to package retrieval --- .../Updates/InstallationManager.cs | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index 014275331..6d68b968b 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -193,38 +193,37 @@ namespace MediaBrowser.Common.Implementations.Updates /// The cancellation token. /// Task{List{PackageInfo}}. public async Task> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) - { - using (var stream = await GetCachedPackages(cancellationToken).ConfigureAwait(false)) - { - var packages = _jsonSerializer.DeserializeFromStream>(stream).ToList(); - - if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength()) - { - UpdateCachedPackages(CancellationToken.None, false); - } - - return packages; - } - } - - private string PackageCachePath - { - get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); } - } - - private async Task GetCachedPackages(CancellationToken cancellationToken) { try { - return _fileSystem.OpenRead(PackageCachePath); + using (var stream = _fileSystem.OpenRead(PackageCachePath)) + { + var packages = _jsonSerializer.DeserializeFromStream>(stream).ToList(); + + if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength()) + { + UpdateCachedPackages(CancellationToken.None, false); + } + + return packages; + } } catch (Exception) { } + _lastPackageUpdateTime = DateTime.MinValue; await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false); - return _fileSystem.OpenRead(PackageCachePath); + using (var stream = _fileSystem.OpenRead(PackageCachePath)) + { + return _jsonSerializer.DeserializeFromStream>(stream).ToList(); + } + } + + private string PackageCachePath + { + get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); } } private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1); From b7780ec7c6f747d14f90b914c0a0bb9268c89274 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:49:33 -0500 Subject: [PATCH 016/214] capture conductor --- .../Probing/ProbeResultNormalizer.cs | 10 +++++++++- MediaBrowser.Model/Entities/PersonType.cs | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 6bd754865..d91df253e 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -440,7 +440,6 @@ namespace MediaBrowser.MediaEncoding.Probing } var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer"); - if (!string.IsNullOrWhiteSpace(composer)) { foreach (var person in Split(composer, false)) @@ -449,6 +448,15 @@ namespace MediaBrowser.MediaEncoding.Probing } } + var conductor = FFProbeHelpers.GetDictionaryValue(tags, "conductor"); + if (!string.IsNullOrWhiteSpace(conductor)) + { + foreach (var person in Split(conductor, false)) + { + audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor }); + } + } + audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album"); var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists"); diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index ee80b1496..bdf846095 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -30,5 +30,9 @@ namespace MediaBrowser.Model.Entities /// The producer /// public const string Producer = "Producer"; + /// + /// The conductor + /// + public const string Conductor = "Conductor"; } } From 0c2192e9033c649d72c422695366214de0a81ea3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 12:04:42 -0500 Subject: [PATCH 017/214] merge from dev --- MediaBrowser.WebDashboard/Api/DashboardService.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 53dbaf4aa..5ad40e4c7 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -345,6 +345,9 @@ namespace MediaBrowser.WebDashboard.Api DeleteFoldersByName(bowerPath, "grunt"); DeleteFoldersByName(bowerPath, "rollups"); + _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "external"), true); + _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true); + DeleteCryptoFiles(Path.Combine(bowerPath, "cryptojslib", "components")); DeleteFoldersByName(Path.Combine(bowerPath, "jquery"), "src"); From c8f65e758906263039b0d6cda7b5cb77552b29a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 12:11:29 -0500 Subject: [PATCH 018/214] update interlaced detection --- .../MediaEncoding/IMediaEncoder.cs | 3 +- .../MediaEncoding/MediaInfoRequest.cs | 1 - .../Encoder/EncodingJobFactory.cs | 2 +- .../Encoder/MediaEncoder.cs | 73 +++++++++++-------- .../Probing/ProbeResultNormalizer.cs | 3 +- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/Entities/MediaStream.cs | 6 ++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/Net/EndPointInfo.cs | 8 ++ .../MediaInfo/AudioImageProvider.cs | 29 ++++++-- 11 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 MediaBrowser.Model/Net/EndPointInfo.cs diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 427af6f6d..76ef054de 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -35,9 +35,10 @@ namespace MediaBrowser.Controller.MediaEncoding /// Extracts the audio image. /// /// The path. + /// Index of the image stream. /// The cancellation token. /// Task{Stream}. - Task ExtractAudioImage(string path, CancellationToken cancellationToken); + Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken); /// /// Extracts the video image. diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs index 24df7b885..ca0c2fdbb 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs @@ -15,7 +15,6 @@ namespace MediaBrowser.Controller.MediaEncoding public IIsoMount MountedIso { get; set; } public VideoType VideoType { get; set; } public List PlayableStreamFileNames { get; set; } - public bool ExtractKeyFrameInterval { get; set; } public MediaInfoRequest() { diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index afbd29578..9cdc4a7bf 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -505,7 +505,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { return "libx264"; } - if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)) { return "libx265"; } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f44d922d5..d5645ce0e 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -258,17 +258,17 @@ namespace MediaBrowser.MediaEncoding.Encoder var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); - //var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); + var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - //if (videoStream != null) - //{ - // var isInterlaced = await DetectInterlaced(mediaInfo, videoStream, inputPath, probeSizeArgument).ConfigureAwait(false); + if (videoStream != null) + { + var isInterlaced = await DetectInterlaced(mediaInfo, videoStream, inputPath, probeSizeArgument).ConfigureAwait(false); - // if (isInterlaced) - // { - // videoStream.IsInterlaced = true; - // } - //} + if (isInterlaced) + { + videoStream.IsInterlaced = true; + } + } return mediaInfo; } @@ -292,19 +292,22 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } - var formats = (video.Container ?? string.Empty).Split(',').ToList(); - - // Take a shortcut and limit this to containers that are likely to have interlaced content - if (!formats.Contains("vob", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("m2ts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("ts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("wtv", StringComparer.OrdinalIgnoreCase)) + // If the video codec is not some form of mpeg, then take a shortcut and limit this to containers that are likely to have interlaced content + if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) == -1) { - return false; + var formats = (video.Container ?? string.Empty).Split(',').ToList(); + + if (!formats.Contains("vob", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("m2ts", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("ts", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("wtv", StringComparer.OrdinalIgnoreCase)) + { + return false; + } } - var args = "{0} -i {1} -map 0:v:{2} -filter:v idet -frames:v 500 -an -f null /dev/null"; + var args = "{0} -i {1} -map 0:v:{2} -an -filter:v idet -frames:v 500 -an -f null /dev/null"; var process = new Process { @@ -444,7 +447,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } - if (((tff + bff) / total) >= .65) + if (((tff + bff) / total) >= .4) { return true; } @@ -469,29 +472,37 @@ namespace MediaBrowser.MediaEncoding.Encoder /// protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public Task ExtractAudioImage(string path, CancellationToken cancellationToken) + public Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); } public Task ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, protocol, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, null, protocol, false, threedFormat, offset, cancellationToken); } - private async Task ExtractImage(string[] inputFiles, MediaProtocol protocol, bool isAudio, + private async Task ExtractImage(string[] inputFiles, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool; var inputArgument = GetInputArgument(inputFiles, protocol); - if (!isAudio) + if (isAudio) + { + //if (imageStreamIndex.HasValue && imageStreamIndex.Value > 0) + //{ + // // It seems for audio files we need to subtract 1 (for the audio stream??) + // imageStreamIndex = imageStreamIndex.Value - 1; + //} + } + else { try { - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { @@ -503,10 +514,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); } - private async Task ExtractImageInternal(string inputPath, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + private async Task ExtractImageInternal(string inputPath, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { @@ -540,9 +551,11 @@ 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} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf) : - string.Format("-i {0} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf); + var args = useIFrame ? string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf, mapArg) : + string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf, mapArg); var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol); diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index d91df253e..31f6af181 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -141,6 +141,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (streamInfo.tags != null) { stream.Language = GetDictionaryValue(streamInfo.tags, "language"); + stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); } if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) @@ -872,7 +873,7 @@ namespace MediaBrowser.MediaEncoding.Probing } } - private void ExtractTimestamp(Model.MediaInfo.MediaInfo video) + private void ExtractTimestamp(MediaInfo video) { if (video.VideoType == VideoType.VideoFile) { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 6145983e2..b8c64b643 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -827,6 +827,9 @@ MediaInfo\VideoCodec.cs + + Net\EndPointInfo.cs + Net\HttpException.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 435c4f50b..e74468eff 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -783,6 +783,9 @@ MediaInfo\VideoCodec.cs + + Net\EndPointInfo.cs + Net\HttpException.cs diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index d089f0aa9..7f4cc2f84 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -30,6 +30,12 @@ namespace MediaBrowser.Model.Entities /// The language. public string Language { get; set; } + /// + /// Gets or sets the comment. + /// + /// The comment. + public string Comment { get; set; } + /// /// Gets or sets a value indicating whether this instance is interlaced. /// diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 3664175d8..db278baa1 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -162,6 +162,7 @@ + diff --git a/MediaBrowser.Model/Net/EndPointInfo.cs b/MediaBrowser.Model/Net/EndPointInfo.cs new file mode 100644 index 000000000..5a158e785 --- /dev/null +++ b/MediaBrowser.Model/Net/EndPointInfo.cs @@ -0,0 +1,8 @@ +namespace MediaBrowser.Model.Net +{ + public class EndPointInfo + { + public bool IsLocal { get; set; } + public bool IsInNetwork { get; set; } + } +} diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 8884412d2..c98a67bbd 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using System; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -43,20 +44,27 @@ namespace MediaBrowser.Providers.MediaInfo { var audio = (Audio)item; + var imageStreams = + audio.GetMediaSources(false) + .Take(1) + .SelectMany(i => i.MediaStreams) + .Where(i => i.Type == MediaStreamType.EmbeddedImage) + .ToList(); + // Can't extract if we didn't find a video stream in the file - if (!audio.GetMediaSources(false).Take(1).SelectMany(i => i.MediaStreams).Any(i => i.Type == MediaStreamType.EmbeddedImage)) + if (imageStreams.Count == 0) { return Task.FromResult(new DynamicImageResponse { HasImage = false }); } - return GetImage((Audio)item, cancellationToken); + return GetImage((Audio)item, imageStreams, cancellationToken); } - public async Task GetImage(Audio item, CancellationToken cancellationToken) + public async Task GetImage(Audio item, List imageStreams, CancellationToken cancellationToken) { var path = GetAudioImagePath(item); - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { var semaphore = GetLock(path); @@ -66,11 +74,16 @@ namespace MediaBrowser.Providers.MediaInfo try { // Check again in case it was saved while waiting for the lock - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false)) + var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ?? + imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1); + + var imageStreamIndex = imageStream == null ? (int?)null : imageStream.Index; + + using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, imageStreamIndex, cancellationToken).ConfigureAwait(false)) { using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { From 16b6b99a912533c59e8992088fe72b95bea352a8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 13:19:10 -0500 Subject: [PATCH 019/214] 3.0.5786 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index b4951f12d..a23f384f5 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5785.0")] +[assembly: AssemblyVersion("3.0.5786.0")] From bb7b6028372ca68fe6402c75d437a24ff426a572 Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 14 Jan 2016 23:36:21 -0500 Subject: [PATCH 020/214] update mac project --- .../Emby.Server.Mac.csproj | 517 +++++++++++++++++- 1 file changed, 488 insertions(+), 29 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 6cc96490e..f7a6a8cd6 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -1136,6 +1136,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\requirehtml.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js + Resources\dashboard-ui\bower_components\fastclick\.bower.json @@ -1328,6 +1331,9 @@ 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 @@ -1367,6 +1373,9 @@ Resources\dashboard-ui\bower_components\hls.js\src\remux\mp4-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 @@ -2363,11 +2372,50 @@ Resources\dashboard-ui\bower_components\jquery\.bower.json - - Resources\dashboard-ui\bower_components\jquery\MIT-LICENSE.txt + + Resources\dashboard-ui\bower_components\jquery\.editorconfig - - Resources\dashboard-ui\bower_components\jquery\bower.json + + Resources\dashboard-ui\bower_components\jquery\.gitattributes + + + Resources\dashboard-ui\bower_components\jquery\.gitignore + + + Resources\dashboard-ui\bower_components\jquery\.jscsrc + + + Resources\dashboard-ui\bower_components\jquery\.jshintignore + + + Resources\dashboard-ui\bower_components\jquery\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\.mailmap + + + Resources\dashboard-ui\bower_components\jquery\.npmignore + + + Resources\dashboard-ui\bower_components\jquery\.travis.yml + + + Resources\dashboard-ui\bower_components\jquery\AUTHORS.txt + + + Resources\dashboard-ui\bower_components\jquery\CONTRIBUTING.md + + + Resources\dashboard-ui\bower_components\jquery\Gruntfile.js + + + Resources\dashboard-ui\bower_components\jquery\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\README.md + + + Resources\dashboard-ui\bower_components\jquery\package.json Resources\dashboard-ui\bower_components\jquery\dist\jquery.js @@ -2378,6 +2426,48 @@ Resources\dashboard-ui\bower_components\jquery\dist\jquery.min.map + + Resources\dashboard-ui\bower_components\jquery\external\npo\npo.js + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.css + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.js + + + Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js + + + Resources\dashboard-ui\bower_components\jquery\external\requirejs\require.js + + + Resources\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js + + + 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\ajax.js @@ -2492,9 +2582,15 @@ Resources\dashboard-ui\bower_components\jquery\src\core\ready.js + + Resources\dashboard-ui\bower_components\jquery\src\core\support.js + Resources\dashboard-ui\bower_components\jquery\src\css\addGetHookIf.js + + Resources\dashboard-ui\bower_components\jquery\src\css\adjustCSS.js + Resources\dashboard-ui\bower_components\jquery\src\css\curCSS.js @@ -2504,18 +2600,15 @@ Resources\dashboard-ui\bower_components\jquery\src\css\hiddenVisibleSelectors.js + + Resources\dashboard-ui\bower_components\jquery\src\css\showHide.js + Resources\dashboard-ui\bower_components\jquery\src\css\support.js - - Resources\dashboard-ui\bower_components\jquery\src\css\swap.js - Resources\dashboard-ui\bower_components\jquery\src\data\Data.js - - Resources\dashboard-ui\bower_components\jquery\src\data\accepts.js - Resources\dashboard-ui\bower_components\jquery\src\effects\Tween.js @@ -2528,9 +2621,15 @@ Resources\dashboard-ui\bower_components\jquery\src\event\alias.js + + Resources\dashboard-ui\bower_components\jquery\src\event\focusin.js + Resources\dashboard-ui\bower_components\jquery\src\event\support.js + + Resources\dashboard-ui\bower_components\jquery\src\event\trigger.js + Resources\dashboard-ui\bower_components\jquery\src\exports\amd.js @@ -2540,24 +2639,387 @@ Resources\dashboard-ui\bower_components\jquery\src\manipulation\_evalUrl.js + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js + + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js + + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\setGlobalEval.js + Resources\dashboard-ui\bower_components\jquery\src\manipulation\support.js + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\wrapMap.js + Resources\dashboard-ui\bower_components\jquery\src\queue\delay.js - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.js - - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.min.js - - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.min.map - Resources\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js + + Resources\dashboard-ui\bower_components\jquery\test\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\test\delegatetest.html + + + Resources\dashboard-ui\bower_components\jquery\test\hovertest.html + + + Resources\dashboard-ui\bower_components\jquery\test\index.html + + + Resources\dashboard-ui\bower_components\jquery\test\jquery.js + + + Resources\dashboard-ui\bower_components\jquery\test\localfile.html + + + Resources\dashboard-ui\bower_components\jquery\test\networkerror.html + + + Resources\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js + + + Resources\dashboard-ui\bower_components\jquery\test\readywait.html + + + Resources\dashboard-ui\bower_components\jquery\test\xhtml.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\1x1.jpg + + + Resources\dashboard-ui\bower_components\jquery\test\data\atom+xml.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\badcall.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\badjson.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\cleanScript.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\dashboard.xml + + + Resources\dashboard-ui\bower_components\jquery\test\data\echoData.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\echoQuery.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\errorWithText.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\etag.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\headers.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\iframe.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\json.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\json_obj.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\jsonp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\name.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\name.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\nocontent.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\params_html.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\script.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\statusText.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\test.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\test.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\test2.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\test3.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\testbar.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\testinit.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\testrunner.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\testsuite.css + + + Resources\dashboard-ui\bower_components\jquery\test\data\text.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\with_fries.xml + + + Resources\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\method.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\aliased.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\onready.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\body.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\relative.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\static.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\table.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js + + + Resources\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\ajax.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\attributes.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\basic.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\callbacks.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\core.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\css.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\data.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\deferred.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\deprecated.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\dimensions.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\effects.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\event.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\exports.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\manipulation.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\offset.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\queue.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\ready.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\selector.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\serialize.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\support.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\traversing.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\wrap.js + Resources\dashboard-ui\bower_components\jstree\.bower.json @@ -2726,6 +3188,9 @@ 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 @@ -2819,8 +3284,8 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\index.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\shared.css + + Resources\dashboard-ui\bower_components\neon-animation\demo\shared-styles.html Resources\dashboard-ui\bower_components\neon-animation\demo\card\index.html @@ -2834,8 +3299,8 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\declarative\index.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\basic.html + + Resources\dashboard-ui\bower_components\neon-animation\demo\doc\index.html Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-animatable.html @@ -2843,9 +3308,6 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-dialog.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\types.html - Resources\dashboard-ui\bower_components\neon-animation\demo\dropdown\animated-dropdown.html @@ -4121,9 +4583,6 @@ Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js - - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js.gz - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js.map From f0089e9f044d691d5b003235e1cd4843c26fce4d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 30 Dec 2015 14:51:52 -0500 Subject: [PATCH 021/214] allow realtime monitor under linux --- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index ba6d7ad1f..8f3006e11 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -119,7 +119,7 @@ namespace MediaBrowser.Server.Mono.Native { get { - return false; + return Environment.OperatingSystem == Startup.Common.OperatingSystem.Linux; } } From 7fe2809483a03b431f680629dc9370a852313fab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 16:41:23 -0500 Subject: [PATCH 022/214] xbox 360 dlna fixes --- MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 3 +-- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 4 ++-- MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs | 12 ++++++++---- .../HttpServer/ResponseFilter.cs | 5 ++++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 431807aed..64b728721 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "Xbox 360"; // Required according to above - ModelName = "Windows Media Connect"; + ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; @@ -25,7 +25,6 @@ namespace MediaBrowser.Dlna.Profiles ManufacturerUrl = "http://www.microsoft.com"; XDlnaDoc = "DMS-1.50"; ModelDescription = "Emby : UPnP Media Server"; - ModelNumber = "001"; TimelineOffsetSeconds = 40; RequiresPlainFolders = true; diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index bfe1fceea..35799f313 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -11,9 +11,9 @@ ${HostName}: 1 Microsoft Corporation http://www.microsoft.com - Windows Media Connect + Windows Media Player Sharing Emby : UPnP Media Server - 001 + 12.0 http://go.microsoft.com/fwlink/?LinkId=105926 false false diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index 649612e1e..63ea59d53 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -92,10 +92,7 @@ namespace MediaBrowser.Dlna.Server builder.Append(""); AppendDeviceProperties(builder); - if (_profile.EnableDlnaProtocol) - { - AppendIconList(builder); - } + AppendIconList(builder); AppendServiceList(builder); builder.Append(""); } @@ -111,6 +108,13 @@ namespace MediaBrowser.Dlna.Server builder.Append("M-DMS-1.50"); builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); } + else + { + builder.Append("" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + ""); + + builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); + builder.Append("M-DMS-1.50"); + } builder.Append("" + SecurityElement.Escape(GetFriendlyName()) + ""); builder.Append("" + SecurityElement.Escape(_profile.Manufacturer ?? string.Empty) + ""); diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs index 0da34efc6..4ef9d5277 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs @@ -58,7 +58,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (hasOptions != null) { - hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1"; + if (!hasOptions.Options.ContainsKey("Server")) + { + hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50"; + } // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy string contentLength; From ee9a914100abb246aa34629974d5abd9c5aaeb60 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 12:31:05 -0500 Subject: [PATCH 023/214] 3.0.5809 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index ee28d01c9..a508fafe5 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5808")] +[assembly: AssemblyVersion("3.0.5809")] From 04508df3ef2dc6281271295c027a065138ff1d9e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 12:17:21 -0500 Subject: [PATCH 024/214] update nfo codecs --- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index fa58b67da..0da53f575 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -305,8 +305,19 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(stream.Codec)) { - writer.WriteElementString("codec", stream.Codec); - writer.WriteElementString("micodec", stream.Codec); + var codec = stream.Codec; + + if ((stream.CodecTag ?? string.Empty).IndexOf("xvid", StringComparison.OrdinalIgnoreCase) != -1) + { + codec = "xvid;"; + } + else if ((stream.CodecTag ?? string.Empty).IndexOf("divx", StringComparison.OrdinalIgnoreCase) != -1) + { + codec = "divx;"; + } + + writer.WriteElementString("codec", codec); + writer.WriteElementString("micodec", codec); } if (stream.BitRate.HasValue) From c9ca6a6ad2d1fb62e96aaa987c89be8df918a5a4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 14 Jan 2016 12:36:15 -0500 Subject: [PATCH 025/214] fixes #1391 - SubtitleDownloader: 407 Limit --- .../Subtitles/OpenSubtitleDownloader.cs | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs index 74296db8a..90b281e8a 100644 --- a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs +++ b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.Subtitles { @@ -30,15 +31,6 @@ namespace MediaBrowser.Providers.Subtitles private readonly IServerConfigurationManager _config; private readonly IEncryptionManager _encryption; - private Timer _dailyTimer; - - // This is limited to 200 per day - private int _dailyDownloadCount; - - // It's 200 but this will be in-exact so buffer a little - // And the user may restart the server - private const int MaxDownloadsPerDay = 150; - private readonly IJsonSerializer _json; public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption, IJsonSerializer json) @@ -51,9 +43,6 @@ namespace MediaBrowser.Providers.Subtitles _config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating; - // Reset the count every 24 hours - _dailyTimer = new Timer(state => _dailyDownloadCount = 0, null, TimeSpan.FromHours(24), TimeSpan.FromHours(24)); - Utilities.HttpClient = httpClient; OpenSubtitles.SetUserAgent("mediabrowser.tv"); } @@ -123,6 +112,7 @@ namespace MediaBrowser.Providers.Subtitles return GetSubtitlesInternal(id, GetOptions(), cancellationToken); } + private DateTime _lastRateLimitException; private async Task GetSubtitlesInternal(string id, SubtitleOptions options, CancellationToken cancellationToken) @@ -132,12 +122,6 @@ namespace MediaBrowser.Providers.Subtitles throw new ArgumentNullException("id"); } - if (_dailyDownloadCount >= MaxDownloadsPerDay && - !options.IsOpenSubtitleVipAccount) - { - throw new InvalidOperationException("Open Subtitle's daily download limit has been exceeded. Please try again tomorrow."); - } - var idParts = id.Split(new[] { '-' }, 3); var format = idParts[0]; @@ -148,8 +132,19 @@ namespace MediaBrowser.Providers.Subtitles await Login(cancellationToken).ConfigureAwait(false); + if ((DateTime.UtcNow - _lastRateLimitException).TotalHours < 1) + { + throw new ApplicationException("OpenSubtitles rate limit reached"); + } + var resultDownLoad = await OpenSubtitles.DownloadSubtitlesAsync(downloadsList, cancellationToken).ConfigureAwait(false); + if ((resultDownLoad.Status ?? string.Empty).IndexOf("407", StringComparison.OrdinalIgnoreCase) != -1) + { + _lastRateLimitException = DateTime.UtcNow; + throw new ApplicationException("OpenSubtitles rate limit reached"); + } + if (!(resultDownLoad is MethodResponseSubtitleDownload)) { throw new ApplicationException("Invalid response type"); @@ -157,13 +152,15 @@ namespace MediaBrowser.Providers.Subtitles var results = ((MethodResponseSubtitleDownload)resultDownLoad).Results; + _lastRateLimitException = DateTime.MinValue; + if (results.Count == 0) { var msg = string.Format("Subtitle with Id {0} was not found. Name: {1}. Status: {2}. Message: {3}", ossId, resultDownLoad.Name ?? string.Empty, - resultDownLoad.Message ?? string.Empty, - resultDownLoad.Status ?? string.Empty); + resultDownLoad.Status ?? string.Empty, + resultDownLoad.Message ?? string.Empty); throw new ResourceNotFoundException(msg); } @@ -339,12 +336,6 @@ namespace MediaBrowser.Providers.Subtitles public void Dispose() { _config.NamedConfigurationUpdating -= _config_NamedConfigurationUpdating; - - if (_dailyTimer != null) - { - _dailyTimer.Dispose(); - _dailyTimer = null; - } } } } From 1bd63682eab32b1d2d19b07d59b0ba8ff9990a25 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 13:45:48 -0500 Subject: [PATCH 026/214] xbox 360 dlna fixes --- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 1 - MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 1 - MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Default.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml | 1 - .../Profiles/Xml/DirecTV HD-DVR.xml | 1 - .../Profiles/Xml/Dish Hopper-Joey.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Kodi.xml | 1 - .../Profiles/Xml/LG Smart TV.xml | 1 - .../Profiles/Xml/Linksys DMA2100.xml | 1 - .../Profiles/Xml/MediaMonkey.xml | 1 - .../Profiles/Xml/Panasonic Viera.xml | 1 - .../Profiles/Xml/Popcorn Hour.xml | 1 - .../Profiles/Xml/Samsung Smart TV.xml | 1 - .../Profiles/Xml/Sony Blu-ray Player 2013.xml | 1 - .../Profiles/Xml/Sony Blu-ray Player.xml | 1 - .../Profiles/Xml/Sony Bravia (2010).xml | 1 - .../Profiles/Xml/Sony Bravia (2011).xml | 1 - .../Profiles/Xml/Sony Bravia (2012).xml | 1 - .../Profiles/Xml/Sony Bravia (2013).xml | 1 - .../Profiles/Xml/Sony Bravia (2014).xml | 1 - .../Profiles/Xml/Sony PlayStation 3.xml | 1 - .../Profiles/Xml/Sony PlayStation 4.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Vlc.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 1 - MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml | 1 - .../Server/DescriptionXmlBuilder.cs | 27 +++++-------------- MediaBrowser.Model/Dlna/DeviceProfile.cs | 1 - 30 files changed, 7 insertions(+), 49 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index 18a595d5b..37ce0ce67 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -37,7 +37,6 @@ namespace MediaBrowser.Dlna.Profiles MusicSyncBitrate = 128000; EnableAlbumArtInDidl = false; - EnableDlnaProtocol = true; TranscodingProfiles = new[] { diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 64b728721..5a3e7b7c0 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -30,7 +30,6 @@ namespace MediaBrowser.Dlna.Profiles RequiresPlainFolders = true; RequiresPlainVideoItems = true; EnableMSMediaReceiverRegistrar = true; - EnableDlnaProtocol = false; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml index ca98f950b..29f7f7c75 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index 58c37a423..6559e8971 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -28,7 +28,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml index 86be2d18b..da033f86e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml @@ -33,7 +33,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml index c553f9a06..d916f9984 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml @@ -34,7 +34,6 @@ true false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml index bb14ea309..702f4ee6c 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml @@ -35,7 +35,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml index 5d30d141e..4a06c3122 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index 62da6dbf4..e2b42a77e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml index 9d83164d8..3d37a9c9e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml @@ -32,7 +32,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml index b66ebfe9e..4249fd6ca 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml index 329c97fbd..b468391ef 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml @@ -35,7 +35,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml index a53e731cf..ae9fc4de4 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml @@ -28,7 +28,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index 642395ac8..2355fe7a4 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml index afcce2b07..f273fcae0 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml index 8dc221251..6132e19dc 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml index 69dae2806..fbd67262a 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml index 2292d634d..3f61b930b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml index 095fcb28e..0774d53f9 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml index c700c4bfb..c052cf85e 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml index 96fa2861d..91cfc0db2 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index ce34dd5f2..b0825c8f6 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml index 939c8a813..670c8a6df 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml @@ -36,7 +36,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml index 82b806f1a..03d39350f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index df2a746d0..10b642bba 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -35,7 +35,6 @@ false false true - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index 35799f313..0724c2a83 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -35,7 +35,6 @@ true true false - false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index bd315ac66..cfedea465 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -35,7 +35,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml index a282af655..8812118ea 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml @@ -34,7 +34,6 @@ false false false - true diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs index 63ea59d53..386370596 100644 --- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs +++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs @@ -54,14 +54,11 @@ namespace MediaBrowser.Dlna.Server var attributes = _profile.XmlRootAttributes.ToList(); - if (_profile.EnableDlnaProtocol) + attributes.Insert(0, new XmlAttribute { - attributes.Insert(0, new XmlAttribute - { - Name = "xmlns:dlna", - Value = "urn:schemas-dlna-org:device-1-0" - }); - } + Name = "xmlns:dlna", + Value = "urn:schemas-dlna-org:device-1-0" + }); attributes.Insert(0, new XmlAttribute { Name = "xmlns", @@ -101,20 +98,10 @@ namespace MediaBrowser.Dlna.Server { builder.Append("urn:schemas-upnp-org:device:MediaServer:1"); - if (_profile.EnableDlnaProtocol) - { - builder.Append("" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + ""); + builder.Append("" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + ""); - builder.Append("M-DMS-1.50"); - builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); - } - else - { - builder.Append("" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + ""); - - builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); - builder.Append("M-DMS-1.50"); - } + builder.Append("M-DMS-1.50"); + builder.Append("" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + ""); builder.Append("" + SecurityElement.Escape(GetFriendlyName()) + ""); builder.Append("" + SecurityElement.Escape(_profile.Manufacturer ?? string.Empty) + ""); diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 5554c0623..778db8fb5 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -78,7 +78,6 @@ namespace MediaBrowser.Model.Dlna public bool EnableMSMediaReceiverRegistrar { get; set; } public bool IgnoreTranscodeByteRangeRequests { get; set; } - public bool EnableDlnaProtocol { get; set; } public XmlAttribute[] XmlRootAttributes { get; set; } From 41568ff2a409a8406fccb964e5b740cbc0c1c6ff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 14:15:32 -0500 Subject: [PATCH 027/214] remove unneeded omdb image check --- MediaBrowser.Providers/Omdb/OmdbImageProvider.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs index 3f25f0f93..a6f346d48 100644 --- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs @@ -51,25 +51,15 @@ namespace MediaBrowser.Providers.Omdb return Task.FromResult>(list); } - public async Task GetImageResponse(string url, CancellationToken cancellationToken) + public Task GetImageResponse(string url, CancellationToken cancellationToken) { - var response = await _httpClient.GetResponse(new HttpRequestOptions + return _httpClient.GetResponse(new HttpRequestOptions { CancellationToken = cancellationToken, Url = url, ResourcePool = OmdbProvider.ResourcePool - }).ConfigureAwait(false); - - if (response.ContentLength == 11059) - { - throw new HttpException("File not found") - { - StatusCode = HttpStatusCode.NotFound - }; - } - - return response; + }); } public string Name From b9118de8c36af933bd959d504f62f94605b34da8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 14:15:51 -0500 Subject: [PATCH 028/214] update identification feature --- MediaBrowser.Api/ItemLookupService.cs | 6 +++++- .../Manager/ProviderManager.cs | 16 ---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index f453036d7..8e1abef14 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -17,6 +17,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Api { @@ -112,13 +113,15 @@ namespace MediaBrowser.Api private readonly IServerApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; private readonly ILibraryManager _libraryManager; + private readonly IJsonSerializer _json; - public ItemLookupService(IProviderManager providerManager, IServerApplicationPaths appPaths, IFileSystem fileSystem, ILibraryManager libraryManager) + public ItemLookupService(IProviderManager providerManager, IServerApplicationPaths appPaths, IFileSystem fileSystem, ILibraryManager libraryManager, IJsonSerializer json) { _providerManager = providerManager; _appPaths = appPaths; _fileSystem = fileSystem; _libraryManager = libraryManager; + _json = json; } public object Get(GetExternalIdInfos request) @@ -199,6 +202,7 @@ namespace MediaBrowser.Api // item.SetProviderId(key.Key, value); // } //} + Logger.Info("Setting provider id's to item {0}-{1}: {2}", item.Id, item.Name, _json.SerializeToString(request.ProviderIds)); item.ProviderIds = request.ProviderIds; var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem) diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 580e9c4ac..090509ed3 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -795,22 +795,6 @@ namespace MediaBrowser.Providers.Manager } } - // This is a workaround duplicate check for movies, where intersecting provider ids are not always available - if (typeof(TItemType) == typeof(Movie) || typeof(TItemType) == typeof(Series)) - { - var titleYearString = string.Format("{0} ({1})", result.Name, result.ProductionYear); - - if (foundTitleYearStrings.Contains(titleYearString)) - { - bFound = true; - } - else - { - foundTitleYearStrings.Add(titleYearString); - } - - } - if (!bFound && resultList.Count < maxResults) { resultList.Add(result); From 8e0ded8d33f79a460c23f26b3284c70b7cdffb7f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 14:16:25 -0500 Subject: [PATCH 029/214] don't use search query when only a single result is needed --- .../Omdb/OmdbItemProvider.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index efcc76e69..30bd4bed7 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -57,7 +57,12 @@ namespace MediaBrowser.Providers.Omdb return GetSearchResults(searchInfo, "movie", cancellationToken); } - public async Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + public Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + { + return GetSearchResultsInternal(searchInfo, type, true, cancellationToken); + } + + private async Task> GetSearchResultsInternal(ItemLookupInfo searchInfo, string type, bool enableMultipleResults, CancellationToken cancellationToken) { bool isSearch = false; @@ -86,7 +91,14 @@ namespace MediaBrowser.Providers.Omdb } // &s means search and returns a list of results as opposed to t - url += "&s=" + WebUtility.UrlEncode(name); + if (enableMultipleResults) + { + url += "&s=" + WebUtility.UrlEncode(name); + } + else + { + url += "&t=" + WebUtility.UrlEncode(name); + } url += "&type=" + type; isSearch = true; } @@ -239,14 +251,14 @@ namespace MediaBrowser.Providers.Omdb private async Task GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) { - var results = await GetSearchResults(info, "movie", cancellationToken).ConfigureAwait(false); + var results = await GetSearchResultsInternal(info, "movie", false, cancellationToken).ConfigureAwait(false); var first = results.FirstOrDefault(); return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } private async Task GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) { - var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false); + var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false); var first = results.FirstOrDefault(); return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } From b343d91df6330b6b01fcae954f7614adb6b08056 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 15 Jan 2016 15:31:40 -0500 Subject: [PATCH 030/214] 3.0.5810 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index a508fafe5..59a89d676 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5809")] +[assembly: AssemblyVersion("3.0.5810")] From 6d53ef82cca76ba71321fcb80deef9aa1467f0c5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 14:02:15 -0500 Subject: [PATCH 031/214] update xbox one dlna profile --- MediaBrowser.Dlna/Profiles/XboxOneProfile.cs | 2 +- MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs index b78b5df0c..e82f9b58c 100644 --- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs +++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Dlna.Profiles new DirectPlayProfile { Container = "mp4,mov,mkv", - VideoCodec = "h264,mpeg4", + VideoCodec = "h264,mpeg4,mpeg2video", AudioCodec = "aac,ac3", Type = DlnaProfileType.Video }, diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index cfedea465..e4344f6ab 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -40,7 +40,7 @@ - + From b1321600b88052b4703cb793f8e140ae19c5c68f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 14:02:25 -0500 Subject: [PATCH 032/214] update tvdb --- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 7250dbee4..022cf241d 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -222,6 +222,11 @@ namespace MediaBrowser.Providers.TV seriesId = await GetSeriesByRemoteId(seriesId, idType, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); } + if (string.IsNullOrWhiteSpace(seriesId)) + { + throw new ArgumentNullException("seriesId"); + } + var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); using (var zipStream = await _httpClient.Get(new HttpRequestOptions From d5b657e2e8e44513f0f057cf3b63c2336cca9014 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 13:29:08 -0500 Subject: [PATCH 033/214] use shared image loader --- 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 4da1f42c4..16f5ffeab 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -122,9 +122,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 3f8f0ff11144126676c157ed231e72e31ac9b361 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 00:01:57 -0500 Subject: [PATCH 034/214] add aspect ratio to search results --- MediaBrowser.Api/SearchService.cs | 1 + MediaBrowser.Controller/Dto/IDtoService.cs | 10 ++++++++-- MediaBrowser.Model/Search/SearchHint.cs | 6 ++++++ .../Dto/DtoService.cs | 17 +++++++++++------ .../Library/UserManager.cs | 5 +---- .../LiveTv/LiveTvDtoService.cs | 5 +---- 6 files changed, 28 insertions(+), 16 deletions(-) diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 302b8d834..602119d4f 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -179,6 +179,7 @@ namespace MediaBrowser.Api if (primaryImageTag != null) { result.PrimaryImageTag = primaryImageTag; + result.PrimaryImageAspectRatio = _dtoService.GetPrimaryImageAspectRatio(item); } SetThumbImageInfo(result, item); diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index e4ab29102..77a81d0c8 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -22,8 +22,14 @@ namespace MediaBrowser.Controller.Dto /// /// The dto. /// The item. - /// The fields. - void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List fields); + void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item); + + /// + /// Gets the primary image aspect ratio. + /// + /// The item. + /// System.Nullable<System.Double>. + double? GetPrimaryImageAspectRatio(IHasImages item); /// /// Gets the base item dto. diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index d51c0325d..3a1d45cc4 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -144,5 +144,11 @@ namespace MediaBrowser.Model.Search /// /// The name of the channel. public string ChannelName { get; set; } + + /// + /// Gets or sets the primary image aspect ratio. + /// + /// The primary image aspect ratio. + public double? PrimaryImageAspectRatio { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index bb7f818ba..b0071828e 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -310,7 +310,7 @@ namespace MediaBrowser.Server.Implementations.Dto { try { - AttachPrimaryImageAspectRatio(dto, item, fields); + AttachPrimaryImageAspectRatio(dto, item); } catch (Exception ex) { @@ -1742,15 +1742,19 @@ namespace MediaBrowser.Server.Implementations.Dto /// /// The dto. /// The item. - /// The fields. /// Task. - public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List fields) + public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item) + { + dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); + } + + public double? GetPrimaryImageAspectRatio(IHasImages item) { var imageInfo = item.GetImageInfo(ImageType.Primary, 0); if (imageInfo == null || !imageInfo.IsLocalFile) { - return; + return null; } ImageSize size; @@ -1762,7 +1766,7 @@ namespace MediaBrowser.Server.Implementations.Dto catch (Exception ex) { //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); - return; + return null; } var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList(); @@ -1781,8 +1785,9 @@ namespace MediaBrowser.Server.Implementations.Dto if (size.Width > 0 && size.Height > 0) { - dto.PrimaryImageAspectRatio = size.Width / size.Height; + return size.Width / size.Height; } + return null; } } } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 3c29cf15d..cf1853c5e 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -403,10 +403,7 @@ namespace MediaBrowser.Server.Implementations.Library try { - _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user, new List - { - ItemFields.PrimaryImageAspectRatio - }); + _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 9ffd8a500..04f99cdce 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -231,10 +231,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { dto.ImageTags[ImageType.Primary] = imageTag; - _dtoService.AttachPrimaryImageAspectRatio(dto, info, new List - { - ItemFields.PrimaryImageAspectRatio - }); + _dtoService.AttachPrimaryImageAspectRatio(dto, info); } if (currentProgram != null) From 8bcc7f1b3bdeae744a5879a0fe0bf90fe72793cb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 14:25:11 -0500 Subject: [PATCH 035/214] 3.0.5811 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 59a89d676..afc767865 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5810")] +[assembly: AssemblyVersion("3.0.5811")] From 0e1b6d2e7909de4cf1709945179af6a434a7a4c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 22:23:59 -0500 Subject: [PATCH 036/214] update image saver --- MediaBrowser.Providers/Manager/ImageSaver.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index e8eece299..4542c9c42 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -133,6 +133,7 @@ namespace MediaBrowser.Providers.Manager source = memoryStream; var currentImage = GetCurrentImage(item, type, index); + var savedPaths = new List(); using (source) { @@ -146,17 +147,17 @@ namespace MediaBrowser.Providers.Manager { retryPath = retryPaths[currentPathIndex]; } - await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); - + var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); + savedPaths.Add(savedPath); currentPathIndex++; } } // Set the path into the item - SetImagePath(item, type, imageIndex, paths[0]); + SetImagePath(item, type, imageIndex, savedPaths[0]); // Delete the current path - if (currentImage != null && currentImage.IsLocalFile && !paths.Contains(currentImage.Path, StringComparer.OrdinalIgnoreCase)) + if (currentImage != null && currentImage.IsLocalFile && !savedPaths.Contains(currentImage.Path, StringComparer.OrdinalIgnoreCase)) { var currentPath = currentImage.Path; @@ -184,11 +185,12 @@ namespace MediaBrowser.Providers.Manager } } - private async Task SaveImageToLocation(Stream source, string path, string retryPath, CancellationToken cancellationToken) + private async Task SaveImageToLocation(Stream source, string path, string retryPath, CancellationToken cancellationToken) { try { await SaveImageToLocation(source, path, cancellationToken).ConfigureAwait(false); + return path; } catch (UnauthorizedAccessException) { @@ -207,6 +209,7 @@ namespace MediaBrowser.Providers.Manager source.Position = 0; await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false); + return retryPath; } /// From 7987e2092a253db52718ac1eaba5f9a93b3aa999 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 22:24:12 -0500 Subject: [PATCH 037/214] update episode refresh --- .../TV/TvdbEpisodeProvider.cs | 2 + .../TV/TvdbSeriesProvider.cs | 54 +++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 6b902ed8a..d03920742 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -112,6 +112,8 @@ namespace MediaBrowser.Providers.TV if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) && (searchInfo.IndexNumber.HasValue || searchInfo.PremiereDate.HasValue)) { + await TvdbSeriesProvider.Current.EnsureSeriesInfo(searchInfo.SeriesProviderIds, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, searchInfo.SeriesProviderIds); var searchNumbers = new EpisodeNumbers(); diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 022cf241d..9452438cb 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -329,38 +329,48 @@ namespace MediaBrowser.Providers.TV return false; } + private SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1,1); internal async Task EnsureSeriesInfo(Dictionary seriesProviderIds, string preferredMetadataLanguage, CancellationToken cancellationToken) { - string seriesId; - if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) - { - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + await _ensureSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - // Only download if not already there - // The post-scan task will take care of updates so we don't need to re-download here - if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + try + { + string seriesId; + if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesId)) { - await DownloadSeriesZip(seriesId, MetadataProviders.Tvdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + + // Only download if not already there + // The post-scan task will take care of updates so we don't need to re-download here + if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + { + await DownloadSeriesZip(seriesId, MetadataProviders.Tvdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + } + + return seriesDataPath; } - return seriesDataPath; - } - - if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) - { - var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); - - // Only download if not already there - // The post-scan task will take care of updates so we don't need to re-download here - if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesId)) { - await DownloadSeriesZip(seriesId, MetadataProviders.Imdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + var seriesDataPath = GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds); + + // Only download if not already there + // The post-scan task will take care of updates so we don't need to re-download here + if (!IsCacheValid(seriesDataPath, preferredMetadataLanguage)) + { + await DownloadSeriesZip(seriesId, MetadataProviders.Imdb.ToString(), seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); + } + + return seriesDataPath; } - return seriesDataPath; + return null; + } + finally + { + _ensureSemaphore.Release(); } - - return null; } private bool IsCacheValid(string seriesDataPath, string preferredMetadataLanguage) From 9991f4a69c5c2391501411880d9f2467dc438f4d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Jan 2016 22:24:24 -0500 Subject: [PATCH 038/214] update commonio --- Emby.Drawing/Emby.Drawing.csproj | 2 +- Emby.Drawing/packages.config | 2 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 2 +- MediaBrowser.Api/packages.config | 2 +- .../MediaBrowser.Common.Implementations.csproj | 2 +- MediaBrowser.Common.Implementations/packages.config | 2 +- MediaBrowser.Controller/MediaBrowser.Controller.csproj | 2 +- MediaBrowser.Controller/packages.config | 2 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 2 +- MediaBrowser.Dlna/packages.config | 2 +- MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj | 2 +- MediaBrowser.LocalMetadata/packages.config | 2 +- MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj | 2 +- MediaBrowser.MediaEncoding/packages.config | 2 +- MediaBrowser.Providers/MediaBrowser.Providers.csproj | 2 +- MediaBrowser.Providers/packages.config | 2 +- .../MediaBrowser.Server.Implementations.csproj | 2 +- MediaBrowser.Server.Implementations/packages.config | 2 +- MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj | 2 +- MediaBrowser.Server.Mono/packages.config | 2 +- .../MediaBrowser.Server.Startup.Common.csproj | 2 +- MediaBrowser.Server.Startup.Common/packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- MediaBrowser.ServerApplication/packages.config | 2 +- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 2 +- MediaBrowser.WebDashboard/packages.config | 2 +- MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj | 2 +- MediaBrowser.XbmcMetadata/packages.config | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 6cda8b5d0..45ac97ecc 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll False diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 3b8dbcab7..51731c474 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 08b99d5a4..7e55446ae 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -47,7 +47,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index 258a097cd..83890e697 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index e87a6ad16..cb3a284c1 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -49,7 +49,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 84f663268..14f0f4719 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b6dc7365a..2227df3f0 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -46,7 +46,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config index 90b347929..8439bee10 100644 --- a/MediaBrowser.Controller/packages.config +++ b/MediaBrowser.Controller/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index db69a45c8..2d672ee87 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -42,7 +42,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Dlna/packages.config b/MediaBrowser.Dlna/packages.config index 258a097cd..83890e697 100644 --- a/MediaBrowser.Dlna/packages.config +++ b/MediaBrowser.Dlna/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index a74fe7e98..9a641776a 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.LocalMetadata/packages.config b/MediaBrowser.LocalMetadata/packages.config index fad6af08e..28556744d 100644 --- a/MediaBrowser.LocalMetadata/packages.config +++ b/MediaBrowser.LocalMetadata/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index df5ab4651..69f6186c7 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -41,7 +41,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll diff --git a/MediaBrowser.MediaEncoding/packages.config b/MediaBrowser.MediaEncoding/packages.config index e8a1767e3..d6a4fc90f 100644 --- a/MediaBrowser.MediaEncoding/packages.config +++ b/MediaBrowser.MediaEncoding/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 7478b2738..8f6ef1d8f 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -50,7 +50,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll False diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config index 9002f1a40..08f8ef3b0 100644 --- a/MediaBrowser.Providers/packages.config +++ b/MediaBrowser.Providers/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index c5b6c1c42..e5c94a01b 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -43,7 +43,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index aac5951b5..5c04f2782 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index e9f631bf3..9f36599fa 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -54,7 +54,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll False diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config index 6a2a6c1e5..2956d69c6 100644 --- a/MediaBrowser.Server.Mono/packages.config +++ b/MediaBrowser.Server.Mono/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 13b782e40..6dd2066bb 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll False diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config index 6a2a6c1e5..2956d69c6 100644 --- a/MediaBrowser.Server.Startup.Common/packages.config +++ b/MediaBrowser.Server.Startup.Common/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index e8d5b6d27..3e62f4735 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -63,7 +63,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll False diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 3ea97a30e..db2bb5476 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 16f5ffeab..48a8bf253 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -49,7 +49,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 24a8a5316..128a2f162 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj index 353fe31ca..16b6ca995 100644 --- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj +++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.XbmcMetadata/packages.config b/MediaBrowser.XbmcMetadata/packages.config index fad6af08e..28556744d 100644 --- a/MediaBrowser.XbmcMetadata/packages.config +++ b/MediaBrowser.XbmcMetadata/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file From cfdb59850c87c5202643f708c0b8b0618bdbd163 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jan 2016 01:42:02 -0500 Subject: [PATCH 039/214] 3.0.5812 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index afc767865..21be099f2 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5811")] +[assembly: AssemblyVersion("3.0.5812")] From e173a9ec7f7b032e5c2b4a34eb0d234b9b3bea01 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 17 Jan 2016 21:03:34 -0500 Subject: [PATCH 040/214] update library monitor --- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 8f3006e11..31d4592c8 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -119,7 +119,7 @@ namespace MediaBrowser.Server.Mono.Native { get { - return Environment.OperatingSystem == Startup.Common.OperatingSystem.Linux; + return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx; } } From 821b6894e555eb0dc1071911273e98baceff4f22 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 17 Jan 2016 21:03:48 -0500 Subject: [PATCH 041/214] update CanSelfUpdate --- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index b0f37eeef..21731a3a6 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -970,6 +970,10 @@ namespace MediaBrowser.Server.Startup.Common { get { + if (!ServerConfigurationManager.Configuration.EnableAutoUpdate) + { + return false; + } #if DEBUG return false; #endif From 0ffac65444e0569ad7ea733003ed7e86d5b887ea Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 17 Jan 2016 23:47:55 -0500 Subject: [PATCH 042/214] update schedules direct to automatically reacquire token --- .../LiveTv/Listings/SchedulesDirect.cs | 76 +++++++++++++------ 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 85d3ffdba..87d7ff3eb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -114,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestString = _jsonSerializer.SerializeToString(requestList); _logger.Debug("Request string for schedules is: " + requestString); httpOptions.RequestContent = requestString; - using (var response = await Post(httpOptions).ConfigureAwait(false)) + using (var response = await Post(httpOptions, true, info).ConfigureAwait(false)) { StreamReader reader = new StreamReader(response.Content); string responseString = reader.ReadToEnd(); @@ -138,7 +138,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; httpOptions.RequestContent = requestBody; - using (var innerResponse = await Post(httpOptions).ConfigureAwait(false)) + using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false)) { StreamReader innerReader = new StreamReader(innerResponse.Content); responseString = innerReader.ReadToEnd(); @@ -148,7 +148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings responseString); var programDict = programDetails.ToDictionary(p => p.programID, y => y); - var images = await GetImageForPrograms(programDetails.Where(p => p.hasImageArtwork).Select(p => p.programID).ToList(), cancellationToken); + var images = await GetImageForPrograms(info, programDetails.Where(p => p.hasImageArtwork).Select(p => p.programID).ToList(), cancellationToken); var schedules = dailySchedules.SelectMany(d => d.programs); foreach (ScheduleDirect.Program schedule in schedules) @@ -229,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - using (var response = await Get(httpOptions).ConfigureAwait(false)) + using (var response = await Get(httpOptions, true, info).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); @@ -447,7 +447,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return url; } - private async Task> GetImageForPrograms(List programIds, + private async Task> GetImageForPrograms( + ListingsProviderInfo info, + List programIds, CancellationToken cancellationToken) { var imageIdString = "["; @@ -472,7 +474,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings TimeoutMs = 60000 }; List images; - using (var innerResponse2 = await Post(httpOptions).ConfigureAwait(false)) + using (var innerResponse2 = await Post(httpOptions, true, info).ConfigureAwait(false)) { images = _jsonSerializer.DeserializeFromStream>( innerResponse2.Content); @@ -504,7 +506,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (Stream responce = await Get(options).ConfigureAwait(false)) + using (Stream responce = await Get(options, false, info).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream>(responce); @@ -606,30 +608,58 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } - private async Task Post(HttpRequestOptions options) + private async Task Post(HttpRequestOptions options, + bool enableRetry, + ListingsProviderInfo providerInfo) { try { return await _httpClient.Post(options).ConfigureAwait(false); - } - catch - { - _tokens.Clear(); - throw; - } + } + catch (HttpException ex) + { + _tokens.Clear(); + + if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500) + { + enableRetry = false; + } + + if (!enableRetry) { + throw; + } + } + + var newToken = await GetToken (providerInfo, options.CancellationToken).ConfigureAwait (false); + options.RequestHeaders ["token"] = newToken; + return await Post (options, false, providerInfo).ConfigureAwait (false); } - private async Task Get(HttpRequestOptions options) + private async Task Get(HttpRequestOptions options, + bool enableRetry, + ListingsProviderInfo providerInfo) { try { return await _httpClient.Get(options).ConfigureAwait(false); - } - catch - { - _tokens.Clear(); - throw; - } + } + catch (HttpException ex) + { + _tokens.Clear(); + + if (!ex.StatusCode.HasValue || (int)ex.StatusCode.Value >= 500) + { + enableRetry = false; + } + + if (!enableRetry) { + throw; + } + } + + var newToken = await GetToken (providerInfo, options.CancellationToken).ConfigureAwait (false); + options.RequestHeaders ["token"] = newToken; + return await Get (options, false, providerInfo).ConfigureAwait (false); } private async Task GetTokenInternal(string username, string password, @@ -646,7 +676,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings //_logger.Info("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " + // httpOptions.RequestContent); - using (var responce = await Post(httpOptions).ConfigureAwait(false)) + using (var responce = await Post(httpOptions, false, null).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(responce.Content); if (root.message == "OK") @@ -728,7 +758,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (var response = await Get(options).ConfigureAwait(false)) + using (var response = await Get(options, false, null).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); From 4e567d04f94e267aae10234c03026dad629515d0 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 18 Jan 2016 00:30:50 -0500 Subject: [PATCH 043/214] auto-organize by date Conflicts: MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs --- .../FileOrganization/EpisodeFileOrganizer.cs | 158 +++++++++++++----- 1 file changed, 116 insertions(+), 42 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index ef226a934..26392f5a9 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -74,42 +74,52 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (!string.IsNullOrEmpty(seriesName)) { - var season = episodeInfo.SeasonNumber; + var seasonNumber = episodeInfo.SeasonNumber; - result.ExtractedSeasonNumber = season; + result.ExtractedSeasonNumber = seasonNumber; - if (season.HasValue) - { - // Passing in true will include a few extra regex's - var episode = episodeInfo.EpisodeNumber; + // Passing in true will include a few extra regex's + var episodeNumber = episodeInfo.EpisodeNumber; - result.ExtractedEpisodeNumber = episode; + result.ExtractedEpisodeNumber = episodeNumber; - if (episode.HasValue) - { - _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode); + var premiereDate = episodeInfo.IsByDate ? + new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : + (DateTime?)null; - var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; + if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) + { + if (episodeInfo.IsByDate) + { + _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); + } + else + { + _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); + } - result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; - await OrganizeEpisode(path, seriesName, season.Value, episode.Value, endingEpisodeNumber, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false); - } - else - { - var msg = string.Format("Unable to determine episode number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } - } - else - { - var msg = string.Format("Unable to determine season number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } + result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + + await OrganizeEpisode(path, + seriesName, + seasonNumber, + episodeNumber, + endingEpisodeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken).ConfigureAwait(false); + } + else + { + var msg = string.Format("Unable to determine episode number from {0}", path); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + } } else { @@ -141,14 +151,32 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); - await OrganizeEpisode(result.OriginalPath, series, request.SeasonNumber, request.EpisodeNumber, request.EndingEpisodeNumber, options, true, result, cancellationToken).ConfigureAwait(false); + await OrganizeEpisode(result.OriginalPath, + series, + request.SeasonNumber, + request.EpisodeNumber, + request.EndingEpisodeNumber, + null, + options, + true, + result, + cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return result; } - private Task OrganizeEpisode(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private Task OrganizeEpisode(string sourcePath, + string seriesName, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { var series = GetMatchingSeries(seriesName, result); @@ -161,15 +189,33 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - return OrganizeEpisode(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, overwriteExisting, result, cancellationToken); + return OrganizeEpisode(sourcePath, + series, + seasonNumber, + episodeNumber, + endingEpiosdeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken); } - private async Task OrganizeEpisode(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private async Task OrganizeEpisode(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -278,8 +324,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private List GetOtherDuplicatePaths(string targetPath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber) + private List GetOtherDuplicatePaths(string targetPath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber) { + // TODO: Support date-naming? + if (!seasonNumber.HasValue || episodeNumber.HasValue) + { + return new List (); + } + var episodePaths = series.GetRecursiveChildren() .OfType() .Where(i => @@ -408,7 +464,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The ending episode number. /// The options. /// System.String. - private async Task GetNewPath(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, TvFileOrganizationOptions options, CancellationToken cancellationToken) + private async Task GetNewPath(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + CancellationToken cancellationToken) { var episodeInfo = new EpisodeInfo { @@ -417,7 +480,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization MetadataCountryCode = series.GetPreferredMetadataCountryCode(), MetadataLanguage = series.GetPreferredMetadataLanguage(), ParentIndexNumber = seasonNumber, - SeriesProviderIds = series.ProviderIds + SeriesProviderIds = series.ProviderIds, + PremiereDate = premiereDate }; var searchResults = await _providerManager.GetRemoteSearchResults(new RemoteSearchQuery @@ -427,14 +491,24 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }, cancellationToken).ConfigureAwait(false); var episode = searchResults.FirstOrDefault(); + + string episodeName = string.Empty; if (episode == null) { - _logger.Warn("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); - return null; + var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + _logger.Warn(msg); + //throw new Exception(msg); } + else + { + episodeName = episode.Name; + } - var newPath = GetSeasonFolderPath(series, seasonNumber, options); + seasonNumber = seasonNumber ?? episode.ParentIndexNumber; + episodeNumber = episodeNumber ?? episode.IndexNumber; + + var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); // MAX_PATH - trailing charachter - drive component: 260 - 1 - 3 = 256 // Usually newPath would include the drive component, but use 256 to be sure @@ -449,7 +523,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt) maxFilenameLength -= 4; - var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options, maxFilenameLength); + var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options, maxFilenameLength); if (string.IsNullOrEmpty(episodeFileName)) { @@ -505,7 +579,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - if (episodeTitle == null) + if (string.IsNullOrEmpty(episodeTitle)) { episodeTitle = string.Empty; } From 284cb50c662b0339a15f387d9a1323fbaba21570 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 18 Jan 2016 14:10:12 -0500 Subject: [PATCH 044/214] 3.0.5813 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 21be099f2..1720a6b27 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5812")] +[assembly: AssemblyVersion("3.0.5813")] From bd96e3bb6128ff4c30be7e6bb2d27ab34240c4f4 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Tue, 19 Jan 2016 03:44:27 +0100 Subject: [PATCH 045/214] Capitalize API --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ee0855b7..ead2a2da3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Emby Server Emby Server is a home media server built on top of other popular open source technologies such as **Service Stack**, **jQuery**, **jQuery mobile**, and **Mono**. -It features a REST-based api with built-in documention to facilitate client development. We also have client libraries for our api to enable rapid development. +It features a REST-based API with built-in documention to facilitate client development. We also have client libraries for our API to enable rapid development. ## Emby Apps From 8087515e72e1202716162cd6905a3c3891d5c7a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 10:48:36 -0500 Subject: [PATCH 046/214] update translations --- MediaBrowser.Server.Implementations/Localization/Core/ca.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 33fd30c36..17f4e7b99 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -71,7 +71,7 @@ "ViewTypeTvShowSeries": "S\u00e8ries:", "ViewTypeTvGenres": "G\u00e8neres", "ViewTypeTvFavoriteSeries": "S\u00e8ries Preferides", - "ViewTypeTvFavoriteEpisodes": "Episodis preferits", + "ViewTypeTvFavoriteEpisodes": "Episodis Preferits", "ViewTypeMovieResume": "Resume", "ViewTypeMovieLatest": "Darrers", "ViewTypeMovieMovies": "Pel\u00b7l\u00edcules", @@ -173,5 +173,5 @@ "HeaderWriter": "Escriptors", "HeaderParentalRatings": "Parental Ratings", "HeaderCommunityRatings": "Qualificacions de la comunitat", - "StartupEmbyServerIsLoading": "El servidor d'Emby s'est\u00e0 carregant. Si us plau, torneu-ho a provar de nou en breu." + "StartupEmbyServerIsLoading": "El servidor d'Emby s'està carregant. Si et plau, tornau-ho a provar de nou en breu." } \ No newline at end of file From c4c4237200c3772169c3bf0f91f92b1bafbd58f7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 11:00:28 -0500 Subject: [PATCH 047/214] 3.0.5814 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 1720a6b27..1f9e07f26 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5813")] +[assembly: AssemblyVersion("3.0.5814")] From 14fe4ab95cd08745acd2634ac25a57c4977ac1b4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 11:09:33 -0500 Subject: [PATCH 048/214] add null check in fanart provider --- MediaBrowser.Providers/Music/FanArtAlbumProvider.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index 3c6485fcc..e72378d5d 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -68,7 +68,14 @@ namespace MediaBrowser.Providers.Music var list = new List(); - var artistMusicBrainzId = album.MusicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist); + var musicArtist = album.MusicArtist; + + if (musicArtist == null) + { + return list; + } + + var artistMusicBrainzId = musicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist); if (!string.IsNullOrEmpty(artistMusicBrainzId)) { From b23f9765117820481cce204461df10bcdbc8c466 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 14:03:46 -0500 Subject: [PATCH 049/214] add delete to multi-select --- MediaBrowser.Api/Library/LibraryService.cs | 66 ++++++++++++++----- .../LiveTv/TunerHosts/SatIp.cs | 54 +++++++++++++++ 2 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 319bc13fd..b7066a36d 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -162,6 +162,14 @@ namespace MediaBrowser.Api.Library public string Id { get; set; } } + [Route("/Items", "DELETE", Summary = "Deletes an item from the library and file system")] + [Authenticated] + public class DeleteItems : IReturnVoid + { + [ApiMember(Name = "Ids", Description = "Ids", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Ids { get; set; } + } + [Route("/Items/Counts", "GET")] [Authenticated] public class GetItemCounts : IReturn @@ -711,31 +719,53 @@ namespace MediaBrowser.Api.Library } } + /// + /// Deletes the specified request. + /// + /// The request. + public void Delete(DeleteItems request) + { + var ids = string.IsNullOrWhiteSpace(request.Ids) + ? new string[] { } + : request.Ids.Split(','); + + var tasks = ids.Select(i => + { + var item = _libraryManager.GetItemById(i); + var auth = _authContext.GetAuthorizationInfo(Request); + var user = _userManager.GetUserById(auth.UserId); + + if (!item.CanDelete(user)) + { + if (ids.Length > 1) + { + throw new SecurityException("Unauthorized access"); + } + + return Task.FromResult(true); + } + + if (item is ILiveTvRecording) + { + return _liveTv.DeleteRecording(i); + } + + return _libraryManager.DeleteItem(item); + }).ToArray(); + + Task.WaitAll(tasks); + } + /// /// Deletes the specified request. /// /// The request. public void Delete(DeleteItem request) { - var item = _libraryManager.GetItemById(request.Id); - var auth = _authContext.GetAuthorizationInfo(Request); - var user = _userManager.GetUserById(auth.UserId); - - if (!item.CanDelete(user)) + Delete(new DeleteItems { - throw new SecurityException("Unauthorized access"); - } - - if (item is ILiveTvRecording) - { - var task = _liveTv.DeleteRecording(request.Id); - Task.WaitAll(task); - } - else - { - var task = _libraryManager.DeleteItem(item); - Task.WaitAll(task); - } + Ids = request.Id + }); } /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs new file mode 100644 index 000000000..ecd2864c5 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts +{ + public class SatIp : BaseTunerHost + { + public SatIp(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder) + : base(config, logger, jsonSerializer, mediaEncoder) + { + } + + protected override Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public override string Type + { + get { return "SatIp"; } + } + + protected override Task> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override Task GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override Task IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override bool IsValidChannelId(string channelId) + { + throw new NotImplementedException(); + } + } +} From a3fb7347b9cfe094e8aa6c8d688d1926b0933566 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 14:44:31 -0500 Subject: [PATCH 050/214] fix merge conflict --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ee0855b7..ead2a2da3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Emby Server Emby Server is a home media server built on top of other popular open source technologies such as **Service Stack**, **jQuery**, **jQuery mobile**, and **Mono**. -It features a REST-based api with built-in documention to facilitate client development. We also have client libraries for our api to enable rapid development. +It features a REST-based API with built-in documention to facilitate client development. We also have client libraries for our API to enable rapid development. ## Emby Apps From a5d54256ffb79dd1d0a06df0536f772bbeff9d3d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 14:45:54 -0500 Subject: [PATCH 051/214] fix merge conflict --- .../Emby.Server.Mac.csproj | 517 +++++++++++++++++- 1 file changed, 488 insertions(+), 29 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 6cc96490e..f7a6a8cd6 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -1136,6 +1136,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\requirehtml.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js + Resources\dashboard-ui\bower_components\fastclick\.bower.json @@ -1328,6 +1331,9 @@ 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 @@ -1367,6 +1373,9 @@ Resources\dashboard-ui\bower_components\hls.js\src\remux\mp4-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 @@ -2363,11 +2372,50 @@ Resources\dashboard-ui\bower_components\jquery\.bower.json - - Resources\dashboard-ui\bower_components\jquery\MIT-LICENSE.txt + + Resources\dashboard-ui\bower_components\jquery\.editorconfig - - Resources\dashboard-ui\bower_components\jquery\bower.json + + Resources\dashboard-ui\bower_components\jquery\.gitattributes + + + Resources\dashboard-ui\bower_components\jquery\.gitignore + + + Resources\dashboard-ui\bower_components\jquery\.jscsrc + + + Resources\dashboard-ui\bower_components\jquery\.jshintignore + + + Resources\dashboard-ui\bower_components\jquery\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\.mailmap + + + Resources\dashboard-ui\bower_components\jquery\.npmignore + + + Resources\dashboard-ui\bower_components\jquery\.travis.yml + + + Resources\dashboard-ui\bower_components\jquery\AUTHORS.txt + + + Resources\dashboard-ui\bower_components\jquery\CONTRIBUTING.md + + + Resources\dashboard-ui\bower_components\jquery\Gruntfile.js + + + Resources\dashboard-ui\bower_components\jquery\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\README.md + + + Resources\dashboard-ui\bower_components\jquery\package.json Resources\dashboard-ui\bower_components\jquery\dist\jquery.js @@ -2378,6 +2426,48 @@ Resources\dashboard-ui\bower_components\jquery\dist\jquery.min.map + + Resources\dashboard-ui\bower_components\jquery\external\npo\npo.js + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.css + + + Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.js + + + Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js + + + Resources\dashboard-ui\bower_components\jquery\external\requirejs\require.js + + + Resources\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js + + + Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js + + + 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\ajax.js @@ -2492,9 +2582,15 @@ Resources\dashboard-ui\bower_components\jquery\src\core\ready.js + + Resources\dashboard-ui\bower_components\jquery\src\core\support.js + Resources\dashboard-ui\bower_components\jquery\src\css\addGetHookIf.js + + Resources\dashboard-ui\bower_components\jquery\src\css\adjustCSS.js + Resources\dashboard-ui\bower_components\jquery\src\css\curCSS.js @@ -2504,18 +2600,15 @@ Resources\dashboard-ui\bower_components\jquery\src\css\hiddenVisibleSelectors.js + + Resources\dashboard-ui\bower_components\jquery\src\css\showHide.js + Resources\dashboard-ui\bower_components\jquery\src\css\support.js - - Resources\dashboard-ui\bower_components\jquery\src\css\swap.js - Resources\dashboard-ui\bower_components\jquery\src\data\Data.js - - Resources\dashboard-ui\bower_components\jquery\src\data\accepts.js - Resources\dashboard-ui\bower_components\jquery\src\effects\Tween.js @@ -2528,9 +2621,15 @@ Resources\dashboard-ui\bower_components\jquery\src\event\alias.js + + Resources\dashboard-ui\bower_components\jquery\src\event\focusin.js + Resources\dashboard-ui\bower_components\jquery\src\event\support.js + + Resources\dashboard-ui\bower_components\jquery\src\event\trigger.js + Resources\dashboard-ui\bower_components\jquery\src\exports\amd.js @@ -2540,24 +2639,387 @@ Resources\dashboard-ui\bower_components\jquery\src\manipulation\_evalUrl.js + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js + + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js + + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\setGlobalEval.js + Resources\dashboard-ui\bower_components\jquery\src\manipulation\support.js + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\wrapMap.js + Resources\dashboard-ui\bower_components\jquery\src\queue\delay.js - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.js - - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.min.js - - - Resources\dashboard-ui\bower_components\jquery\src\sizzle\dist\sizzle.min.map - Resources\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js + + Resources\dashboard-ui\bower_components\jquery\test\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\test\delegatetest.html + + + Resources\dashboard-ui\bower_components\jquery\test\hovertest.html + + + Resources\dashboard-ui\bower_components\jquery\test\index.html + + + Resources\dashboard-ui\bower_components\jquery\test\jquery.js + + + Resources\dashboard-ui\bower_components\jquery\test\localfile.html + + + Resources\dashboard-ui\bower_components\jquery\test\networkerror.html + + + Resources\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js + + + Resources\dashboard-ui\bower_components\jquery\test\readywait.html + + + Resources\dashboard-ui\bower_components\jquery\test\xhtml.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\1x1.jpg + + + Resources\dashboard-ui\bower_components\jquery\test\data\atom+xml.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\badcall.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\badjson.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\cleanScript.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\dashboard.xml + + + Resources\dashboard-ui\bower_components\jquery\test\data\echoData.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\echoQuery.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\errorWithText.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\etag.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\headers.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\iframe.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\json.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\json_obj.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\jsonp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\name.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\name.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\nocontent.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\params_html.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\script.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\statusText.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\test.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\test.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\test2.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\test3.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\testbar.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\testinit.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\testrunner.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\testsuite.css + + + Resources\dashboard-ui\bower_components\jquery\test\data\text.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\with_fries.xml + + + Resources\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\method.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\aliased.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\core\onready.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\body.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\relative.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\static.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\offset\table.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.js + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.php + + + Resources\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js + + + Resources\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html + + + Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js + + + Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\ajax.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\attributes.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\basic.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\callbacks.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\core.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\css.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\data.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\deferred.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\deprecated.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\dimensions.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\effects.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\event.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\exports.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\manipulation.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\offset.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\queue.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\ready.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\selector.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\serialize.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\support.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\traversing.js + + + Resources\dashboard-ui\bower_components\jquery\test\unit\wrap.js + Resources\dashboard-ui\bower_components\jstree\.bower.json @@ -2726,6 +3188,9 @@ 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 @@ -2819,8 +3284,8 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\index.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\shared.css + + Resources\dashboard-ui\bower_components\neon-animation\demo\shared-styles.html Resources\dashboard-ui\bower_components\neon-animation\demo\card\index.html @@ -2834,8 +3299,8 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\declarative\index.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\basic.html + + Resources\dashboard-ui\bower_components\neon-animation\demo\doc\index.html Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-animatable.html @@ -2843,9 +3308,6 @@ Resources\dashboard-ui\bower_components\neon-animation\demo\doc\my-dialog.html - - Resources\dashboard-ui\bower_components\neon-animation\demo\doc\types.html - Resources\dashboard-ui\bower_components\neon-animation\demo\dropdown\animated-dropdown.html @@ -4121,9 +4583,6 @@ Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js - - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js.gz - Resources\dashboard-ui\bower_components\web-animations-js\web-animations.min.js.map From 76bfde2675f832ad389f8d83148cddb66c214f0e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 14:46:59 -0500 Subject: [PATCH 052/214] fix merge conflicts --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 10 +++++----- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d5645ce0e..ba0790bf3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -492,11 +492,11 @@ namespace MediaBrowser.MediaEncoding.Encoder if (isAudio) { - //if (imageStreamIndex.HasValue && imageStreamIndex.Value > 0) - //{ - // // It seems for audio files we need to subtract 1 (for the audio stream??) - // imageStreamIndex = imageStreamIndex.Value - 1; - //} + if (imageStreamIndex.HasValue && imageStreamIndex.Value > 0) + { + // It seems for audio files we need to subtract 1 (for the audio stream??) + imageStreamIndex = imageStreamIndex.Value - 1; + } } else { diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 8f3006e11..31d4592c8 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -119,7 +119,7 @@ namespace MediaBrowser.Server.Mono.Native { get { - return Environment.OperatingSystem == Startup.Common.OperatingSystem.Linux; + return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx; } } From e951dd20d95c81da29d4f9d8a2cb927e7639518b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 14:52:08 -0500 Subject: [PATCH 053/214] fix merge conflict --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index a23f384f5..1f9e07f26 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5786.0")] +[assembly: AssemblyVersion("3.0.5814")] From b959b7d44792d7624a50b577ae14c8c83666f6ca Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 22:02:14 -0500 Subject: [PATCH 054/214] add back api keys --- MediaBrowser.Api/Session/SessionsService.cs | 3 ++- .../Security/AuthenticationInfoQuery.cs | 6 ++++++ .../Security/AuthenticationRepository.cs | 12 ++++++++++++ .../MediaBrowser.WebDashboard.csproj | 6 ++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 1160f685c..416c4fff9 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -355,7 +355,8 @@ namespace MediaBrowser.Api.Session { var result = _authRepo.Get(new AuthenticationInfoQuery { - IsActive = true + IsActive = true, + HasUser = false }); return ToOptimizedResult(result); diff --git a/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs b/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs index 3234b0350..273dfd43c 100644 --- a/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs +++ b/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs @@ -27,6 +27,12 @@ namespace MediaBrowser.Controller.Security /// null if [is active] contains no value, true if [is active]; otherwise, false. public bool? IsActive { get; set; } + /// + /// Gets or sets a value indicating whether this instance has user. + /// + /// null if [has user] contains no value, true if [has user]; otherwise, false. + public bool? HasUser { get; set; } + /// /// Gets or sets the start index. /// diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs index df7cc47f4..b36db51b3 100644 --- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs +++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs @@ -185,6 +185,18 @@ namespace MediaBrowser.Server.Implementations.Security cmd.Parameters.Add(cmd, "@IsActive", DbType.Boolean).Value = query.IsActive.Value; } + if (query.HasUser.HasValue) + { + if (query.HasUser.Value) + { + whereClauses.Add("UserId not null"); + } + else + { + whereClauses.Add("UserId is null"); + } + } + var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 48a8bf253..2a2515197 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -293,6 +293,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -323,6 +326,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 1055c1c77e385ade8653972bac16ff3368ea4a09 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 22:02:26 -0500 Subject: [PATCH 055/214] normalize remote ip --- .../SocketSharp/WebSocketSharpRequest.cs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index b3fbd2d1d..5df37118d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -136,11 +136,27 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { return remoteIp ?? (remoteIp = XForwardedFor ?? - (XRealIp ?? - ((request.RemoteEndPoint != null) ? request.RemoteEndPoint.Address.ToString() : null))); + (NormalizeIp(XRealIp) ?? + ((request.RemoteEndPoint != null) ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null))); } } + private string NormalizeIp(string ip) + { + if (!string.IsNullOrWhiteSpace(ip)) + { + // Handle ipv4 mapped to ipv6 + const string srch = "::ffff:"; + var index = ip.IndexOf(srch, StringComparison.OrdinalIgnoreCase); + if (index == 0) + { + ip = ip.Substring(srch.Length); + } + } + + return ip; + } + public bool IsSecureConnection { get { return request.IsSecureConnection || XForwardedProtocol == "https"; } From d9c678afaf5cdeaaa771ec6378e24661df55883b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 19 Jan 2016 22:05:56 -0500 Subject: [PATCH 056/214] 3.0.5815 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 1f9e07f26..056572276 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5814")] +[assembly: AssemblyVersion("3.0.5815")] From 7f7d80bf64fb9847741ec24b222d9416636c22d1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 13:11:02 -0500 Subject: [PATCH 057/214] trim logging --- MediaBrowser.Api/ApiEntryPoint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 818b40b20..55f191f1a 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -294,7 +294,7 @@ namespace MediaBrowser.Api public void OnTranscodeEndRequest(TranscodingJob job) { job.ActiveRequestCount--; - Logger.Debug("OnTranscodeEndRequest job.ActiveRequestCount={0}", job.ActiveRequestCount); + //Logger.Debug("OnTranscodeEndRequest job.ActiveRequestCount={0}", job.ActiveRequestCount); if (job.ActiveRequestCount <= 0) { PingTimer(job, false); @@ -307,7 +307,7 @@ namespace MediaBrowser.Api throw new ArgumentNullException("playSessionId"); } - Logger.Debug("PingTranscodingJob PlaySessionId={0}", playSessionId); + //Logger.Debug("PingTranscodingJob PlaySessionId={0}", playSessionId); var jobs = new List(); From 17680d59b6e2de318ab5e540e39f8c0c776114c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 13:38:09 -0500 Subject: [PATCH 058/214] 3.0.5816 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 056572276..706b83996 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5815")] +[assembly: AssemblyVersion("3.0.5816")] From bf38997dc64295f1a72ba05a7a027fa4467e4fb7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 14:54:06 -0500 Subject: [PATCH 059/214] resolve config caching issue --- MediaBrowser.Api/BaseApiService.cs | 15 --------------- MediaBrowser.Api/ConfigurationService.cs | 8 +------- MediaBrowser.Api/PluginService.cs | 6 +----- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 7a14ace77..c9b1c5c53 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -58,21 +58,6 @@ namespace MediaBrowser.Api return ResultFactory.GetOptimizedResult(Request, result); } - /// - /// To the optimized result using cache. - /// - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// The factory function. - /// System.Object. - protected object ToOptimizedResultUsingCache(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, Func factoryFn) - where T : class - { - return ResultFactory.GetOptimizedResultUsingCache(Request, cacheKey, lastDateModified, cacheDuration, factoryFn); - } - protected void AssertCanUpdateUser(IUserManager userManager, string userId) { var auth = AuthorizationContext.GetAuthorizationInfo(Request); diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index f33a30892..3c0b7f140 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -105,13 +105,7 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetConfiguration request) { - var configPath = _configurationManager.ApplicationPaths.SystemConfigurationFilePath; - - var dateModified = _fileSystem.GetLastWriteTimeUtc(configPath); - - var cacheKey = (configPath + dateModified.Ticks).GetMD5(); - - return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration); + return ToOptimizedResult(_configurationManager.Configuration); } public object Get(GetNamedConfiguration request) diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index 74b37df92..2d7444f60 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -250,11 +250,7 @@ namespace MediaBrowser.Api var guid = new Guid(request.Id); var plugin = _appHost.Plugins.First(p => p.Id == guid); - var dateModified = plugin.ConfigurationDateLastModified; - - var cacheKey = (plugin.Version.ToString() + dateModified.Ticks).GetMD5(); - - return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => plugin.Configuration); + return ToOptimizedResult(plugin.Configuration); } /// From 1e4ee3f60e291c50cd7158125d3e960171ad706f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 15:25:46 -0500 Subject: [PATCH 060/214] 3.0.5840 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 706b83996..6f6d43209 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5816")] +[assembly: AssemblyVersion("3.0.5840")] From 086713064ca884655b41f15f6cb61766c5bf2ea0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 20:05:14 -0500 Subject: [PATCH 061/214] update image loader --- 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 2a2515197..cc153a010 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1045,9 +1045,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From aaf316884d4e705a9dc47002f492f28649e4821b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 03:23:02 -0500 Subject: [PATCH 062/214] support photo orientation --- Emby.Drawing/GDI/GDIImageEncoder.cs | 2 +- Emby.Drawing/IImageEncoder.cs | 3 +- .../ImageMagick/ImageMagickEncoder.cs | 20 +++++++++++- Emby.Drawing/ImageProcessor.cs | 31 ++++++++++++++++++- Emby.Drawing/NullImageEncoder.cs | 2 +- .../Dto/DtoService.cs | 26 ++++++++++++++-- 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 3df84cf11..51b4605c3 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -89,7 +89,7 @@ namespace Emby.Drawing.GDI } } - public void EncodeImage(string inputPath, string cacheFilePath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string cacheFilePath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { var hasPostProcessing = !string.IsNullOrEmpty(options.BackgroundColor) || options.UnplayedCount.HasValue || options.AddPlayedIndicator || options.PercentPlayed > 0; diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index bfd382bb7..f36498be7 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -27,12 +27,13 @@ namespace Emby.Drawing /// /// The input path. /// The output path. + /// The rotation angle. /// The width. /// The height. /// The quality. /// The options. /// The output format. - void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 6858c6d52..fd9ed5f1e 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -139,7 +139,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); @@ -150,6 +150,11 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); + if (rotationAngle > 0) + { + RotateImage(originalImage, rotationAngle); + } + DrawIndicator(originalImage, width, height, options); originalImage.CurrentImage.CompressionQuality = quality; @@ -166,6 +171,11 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); + if (rotationAngle > 0) + { + RotateImage(originalImage, rotationAngle); + } + wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0); DrawIndicator(wand, width, height, options); @@ -179,6 +189,14 @@ namespace Emby.Drawing.ImageMagick SaveDelay(); } + public static void RotateImage(MagickWand wand, float angle) + { + using (var pixelWand = new PixelWand("none", 1)) + { + wand.CurrentImage.RotateImage(pixelWand, angle); + } + } + private void ScaleImage(MagickWand wand, int width, int height) { var highQuality = false; diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index e1b92bbff..9de6d2042 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -257,7 +257,7 @@ namespace Emby.Drawing imageProcessingLockTaken = true; - _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options, outputFormat); + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, GetRotationAngle(options.Item), newWidth, newHeight, quality, options, outputFormat); } return new Tuple(cacheFilePath, GetMimeType(outputFormat, cacheFilePath)); @@ -281,6 +281,35 @@ namespace Emby.Drawing } } + private int GetRotationAngle(IHasImages item) + { + var photo = item as Photo; + if (photo != null && photo.Orientation.HasValue) + { + switch (photo.Orientation.Value) + { + case ImageOrientation.TopLeft: + return 0; + case ImageOrientation.TopRight: + return 0; + case ImageOrientation.BottomLeft: + return 270; + case ImageOrientation.BottomRight: + return 180; + case ImageOrientation.LeftBottom: + return -90; + case ImageOrientation.LeftTop: + return 0; + case ImageOrientation.RightBottom: + return 0; + case ImageOrientation.RightTop: + return 90; + } + } + + return 0; + } + private string GetMimeType(ImageFormat format, string path) { if (format == ImageFormat.Bmp) diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 1638a675a..032335a46 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index b0071828e..0cd551f6a 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1783,11 +1783,31 @@ namespace MediaBrowser.Server.Implementations.Dto } } - if (size.Width > 0 && size.Height > 0) + var width = size.Width; + var height = size.Height; + + if (width == 0 || height == 0) { - return size.Width / size.Height; + return null; } - return null; + + var photo = item as Photo; + if (photo != null && photo.Orientation.HasValue) + { + switch (photo.Orientation.Value) + { + case ImageOrientation.LeftBottom: + case ImageOrientation.LeftTop: + case ImageOrientation.RightBottom: + case ImageOrientation.RightTop: + var temp = height; + height = width; + width = temp; + break; + } + } + + return width / height; } } } From c71a319685b7a5027112ce3059e7fdff3fff3729 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 11:53:03 -0500 Subject: [PATCH 063/214] use image magick for auto-orientation --- Emby.Drawing/Emby.Drawing.csproj | 2 +- Emby.Drawing/GDI/GDIImageEncoder.cs | 2 +- Emby.Drawing/IImageEncoder.cs | 4 +- .../ImageMagick/ImageMagickEncoder.cs | 15 ++++--- Emby.Drawing/ImageProcessor.cs | 41 +++++++++---------- Emby.Drawing/NullImageEncoder.cs | 2 +- Emby.Drawing/packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- .../packages.config | 2 +- 9 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 45ac97ecc..06e042d74 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -37,7 +37,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 51b4605c3..bdd1c5a22 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -89,7 +89,7 @@ namespace Emby.Drawing.GDI } } - public void EncodeImage(string inputPath, string cacheFilePath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string cacheFilePath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { var hasPostProcessing = !string.IsNullOrEmpty(options.BackgroundColor) || options.UnplayedCount.HasValue || options.AddPlayedIndicator || options.PercentPlayed > 0; diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index f36498be7..73b539899 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -27,13 +27,13 @@ namespace Emby.Drawing /// /// The input path. /// The output path. - /// The rotation angle. + /// if set to true [automatic orient]. /// The width. /// The height. /// The quality. /// The options. /// The output format. - void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index fd9ed5f1e..b8300ac97 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -139,7 +139,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); @@ -150,9 +150,9 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); - if (rotationAngle > 0) + if (autoOrient) { - RotateImage(originalImage, rotationAngle); + AutoOrientImage(originalImage); } DrawIndicator(originalImage, width, height, options); @@ -171,9 +171,9 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); - if (rotationAngle > 0) + if (autoOrient) { - RotateImage(originalImage, rotationAngle); + AutoOrientImage(originalImage); } wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0); @@ -189,6 +189,11 @@ namespace Emby.Drawing.ImageMagick SaveDelay(); } + private void AutoOrientImage(MagickWand wand) + { + wand.CurrentImage.AutoOrientImage(); + } + public static void RotateImage(MagickWand wand, float angle) { using (var pixelWand = new PixelWand("none", 1)) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 9de6d2042..e01612700 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -257,7 +257,7 @@ namespace Emby.Drawing imageProcessingLockTaken = true; - _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, GetRotationAngle(options.Item), newWidth, newHeight, quality, options, outputFormat); + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, AutoOrient(options.Item), newWidth, newHeight, quality, options, outputFormat); } return new Tuple(cacheFilePath, GetMimeType(outputFormat, cacheFilePath)); @@ -281,35 +281,32 @@ namespace Emby.Drawing } } - private int GetRotationAngle(IHasImages item) + private bool AutoOrient(IHasImages item) { var photo = item as Photo; if (photo != null && photo.Orientation.HasValue) { - switch (photo.Orientation.Value) - { - case ImageOrientation.TopLeft: - return 0; - case ImageOrientation.TopRight: - return 0; - case ImageOrientation.BottomLeft: - return 270; - case ImageOrientation.BottomRight: - return 180; - case ImageOrientation.LeftBottom: - return -90; - case ImageOrientation.LeftTop: - return 0; - case ImageOrientation.RightBottom: - return 0; - case ImageOrientation.RightTop: - return 90; - } + return true; } - return 0; + return false; } + //private static int[][] OPERATIONS = new int[][] { + // TopLeft + //new int[] { 0, NONE}, + // TopRight + //new int[] { 0, HORIZONTAL}, + //new int[] {180, NONE}, + // LeftTop + //new int[] { 0, VERTICAL}, + //new int[] { 90, HORIZONTAL}, + // RightTop + //new int[] { 90, NONE}, + //new int[] {-90, HORIZONTAL}, + //new int[] {-90, NONE}, + //}; + private string GetMimeType(ImageFormat format, string path) { if (format == ImageFormat.Bmp) diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 032335a46..4fa18ce55 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 51731c474..62a241f1f 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 3e62f4735..c62983192 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -67,7 +67,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll ..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index db2bb5476..be12bcd5c 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,7 +1,7 @@  - + From 06f8047ee6a68fb5429b3d938b2916f1a17a63b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 12:29:14 -0500 Subject: [PATCH 064/214] support system wake on recording schedule --- .../MediaBrowser.Controller.csproj | 1 + .../Power/IPowerManagement.cs | 13 ++++++ .../LiveTv/EmbyTV/EmbyTV.cs | 5 ++- .../LiveTv/EmbyTV/TimerManager.cs | 30 +++++++++++++- .../Native/BaseMonoApp.cs | 14 +++++++ .../ApplicationHost.cs | 2 + .../INativeApp.cs | 7 ++++ .../MediaBrowser.ServerApplication.csproj | 1 + .../Native/WindowsApp.cs | 6 +++ .../Native/WindowsPowerManagement.cs | 40 +++++++++++++++++++ 10 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 MediaBrowser.Controller/Power/IPowerManagement.cs create mode 100644 MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 2227df3f0..471aa38d4 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -265,6 +265,7 @@ + diff --git a/MediaBrowser.Controller/Power/IPowerManagement.cs b/MediaBrowser.Controller/Power/IPowerManagement.cs new file mode 100644 index 000000000..faa289695 --- /dev/null +++ b/MediaBrowser.Controller/Power/IPowerManagement.cs @@ -0,0 +1,13 @@ +using System; + +namespace MediaBrowser.Controller.Power +{ + public interface IPowerManagement + { + /// + /// Schedules the wake. + /// + /// The UTC time. + void ScheduleWake(DateTime utcTime); + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 356d0d83d..3d1d9e0ba 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -28,6 +28,7 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Power; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -55,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder, IPowerManagement powerManagement) { Current = this; @@ -75,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _recordingProvider = new ItemDataProvider(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)); _seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers")); - _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers")); + _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"), powerManagement, _logger); _timerProvider.TimerFired += _timerProvider_TimerFired; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 80bb671fa..ca20379b6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -8,19 +8,23 @@ using System.Collections.Concurrent; using System.Linq; using System.Threading; using CommonIO; -using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Power; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public class TimerManager : ItemDataProvider { private readonly ConcurrentDictionary _timers = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private readonly IPowerManagement _powerManagement; + private readonly ILogger _logger; public event EventHandler> TimerFired; - public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath) + public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath, IPowerManagement powerManagement, ILogger logger1) : base(fileSystem, jsonSerializer, logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)) { + _powerManagement = powerManagement; + _logger = logger1; } public void RestartTimers() @@ -58,6 +62,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { var timespan = RecordingHelper.GetStartTime(item) - DateTime.UtcNow; timer.Change(timespan, TimeSpan.Zero); + ScheduleWake(item); } else { @@ -74,6 +79,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV base.Add(item); AddTimer(item); + ScheduleWake(item); } private void AddTimer(TimerInfo item) @@ -91,6 +97,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV StartTimer(item, timerLength); } + private void ScheduleWake(TimerInfo info) + { + var startDate = RecordingHelper.GetStartTime(info).AddMinutes(-5); + _logger.Info("Scheduling system wake timer at {0} (UTC)", startDate); + + try + { + _powerManagement.ScheduleWake(startDate); + _logger.Info("Scheduled system wake timer at {0} (UTC)", startDate); + } + catch (NotImplementedException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error scheduling wake timer", ex); + } + } + public void StartTimer(TimerInfo item, TimeSpan length) { StopTimer(item); diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 31d4592c8..e57a651c0 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; +using MediaBrowser.Controller.Power; namespace MediaBrowser.Server.Mono.Native { @@ -203,5 +204,18 @@ namespace MediaBrowser.Server.Mono.Native public string sysname = string.Empty; public string machine = string.Empty; } + + public IPowerManagement GetPowerManagement() + { + return new NullPowerManagement(); + } + } + + public class NullPowerManagement : IPowerManagement + { + public void ScheduleWake(DateTime utcTime) + { + throw new NotImplementedException(); + } } } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 21731a3a6..1db019d8d 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -533,6 +533,8 @@ namespace MediaBrowser.Server.Startup.Common EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager); RegisterSingleInstance(EncodingManager); + RegisterSingleInstance(NativeApp.GetPowerManagement()); + var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index 597caf34c..75b38d0c4 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; +using MediaBrowser.Controller.Power; namespace MediaBrowser.Server.Startup.Common { @@ -90,5 +91,11 @@ namespace MediaBrowser.Server.Startup.Common /// Prevents the system stand by. /// void PreventSystemStandby(); + + /// + /// Gets the power management. + /// + /// IPowerManagement. + IPowerManagement GetPowerManagement(); } } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index c62983192..80e56d6e1 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -120,6 +120,7 @@ + diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index ceab5379d..9ef9c7d50 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -6,6 +6,7 @@ using MediaBrowser.ServerApplication.Networking; using System.Collections.Generic; using System.Reflection; using CommonIO; +using MediaBrowser.Controller.Power; namespace MediaBrowser.ServerApplication.Native { @@ -117,5 +118,10 @@ namespace MediaBrowser.ServerApplication.Native { Standby.PreventSystemStandby(); } + + public IPowerManagement GetPowerManagement() + { + return new WindowsPowerManagement(); + } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs new file mode 100644 index 000000000..6bd78553b --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs @@ -0,0 +1,40 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Threading; +using MediaBrowser.Controller.Power; +using Microsoft.Win32.SafeHandles; + +namespace MediaBrowser.ServerApplication.Native +{ + public class WindowsPowerManagement : IPowerManagement + { + [DllImport("kernel32.dll")] + public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume); + + public void ScheduleWake(DateTime utcTime) + { + long duetime = utcTime.ToFileTime(); + + using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer")) + { + if (SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true)) + { + using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset)) + { + wh.SafeWaitHandle = handle; + wh.WaitOne(); + } + } + else + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + } + } +} From a10347a455fbc27284caa8a42c5e77cda9683eab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 12:45:42 -0500 Subject: [PATCH 065/214] update wake timer --- .../LiveTv/LiveTvManager.cs | 1 + MediaBrowser.ServerApplication/MainStartup.cs | 2 +- .../Native/WindowsApp.cs | 6 +- .../Native/WindowsPowerManagement.cs | 77 ++++++++++++++++--- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index e09e06bd4..8bf1d27b8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1954,6 +1954,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; + _logger.Info("New recording scheduled"); } public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 62cdbd05f..cf174c2d3 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -218,7 +218,7 @@ namespace MediaBrowser.ServerApplication var fileSystem = new WindowsFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem"))); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - var nativeApp = new WindowsApp(fileSystem) + var nativeApp = new WindowsApp(fileSystem, _logger) { IsRunningAsService = runService }; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 9ef9c7d50..fe2fe6de6 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -13,10 +13,12 @@ namespace MediaBrowser.ServerApplication.Native public class WindowsApp : INativeApp { private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; - public WindowsApp(IFileSystem fileSystem) + public WindowsApp(IFileSystem fileSystem, ILogger logger) { _fileSystem = fileSystem; + _logger = logger; } public List GetAssembliesWithParts() @@ -121,7 +123,7 @@ namespace MediaBrowser.ServerApplication.Native public IPowerManagement GetPowerManagement() { - return new WindowsPowerManagement(); + return new WindowsPowerManagement(_logger); } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs index 6bd78553b..3b05febaf 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Runtime.InteropServices; using System.Threading; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.Logging; using Microsoft.Win32.SafeHandles; namespace MediaBrowser.ServerApplication.Native @@ -10,30 +11,82 @@ namespace MediaBrowser.ServerApplication.Native public class WindowsPowerManagement : IPowerManagement { [DllImport("kernel32.dll")] - public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName); + public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, + bool bManualReset, + string lpTimerName); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume); + public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, + [In] ref long pDueTime, + int lPeriod, + IntPtr pfnCompletionRoutine, + IntPtr lpArgToCompletionRoutine, + bool fResume); + + private BackgroundWorker _bgWorker; + private readonly ILogger _logger; + private readonly object _initLock = new object(); + + public WindowsPowerManagement(ILogger logger) + { + _logger = logger; + } public void ScheduleWake(DateTime utcTime) { - long duetime = utcTime.ToFileTime(); + Initialize(); + _bgWorker.RunWorkerAsync(utcTime.ToFileTime()); + } - using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer")) + private void Initialize() + { + lock (_initLock) { - if (SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true)) + if (_bgWorker == null) { - using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset)) + _bgWorker = new BackgroundWorker(); + + _bgWorker.DoWork += bgWorker_DoWork; + _bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted; + } + } + } + + void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + //if (Woken != null) + //{ + // Woken(this, new EventArgs()); + //} + } + + private void bgWorker_DoWork(object sender, DoWorkEventArgs e) + { + try + { + long waketime = (long)e.Argument; + + using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, GetType().Assembly.GetName().Name + "Timer")) + { + if (SetWaitableTimer(handle, ref waketime, 0, IntPtr.Zero, IntPtr.Zero, true)) { - wh.SafeWaitHandle = handle; - wh.WaitOne(); + using (EventWaitHandle wh = new EventWaitHandle(false, + EventResetMode.AutoReset)) + { + wh.SafeWaitHandle = handle; + wh.WaitOne(); + } + } + else + { + throw new Win32Exception(Marshal.GetLastWin32Error()); } } - else - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } + } + catch (Exception ex) + { + _logger.ErrorException("Error scheduling wake timer", ex); } } } From 410f1333e43d27c3af121f3e9e39d152c6eb8a05 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 12:48:07 -0500 Subject: [PATCH 066/214] 3.0.5841 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 6f6d43209..8791b5ec5 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5840")] +[assembly: AssemblyVersion("3.0.5841")] From 105ecae1de194fd35b4d542735a216063c710386 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 20 Jan 2016 20:05:14 -0500 Subject: [PATCH 067/214] update image loader --- 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 2a2515197..cc153a010 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1045,9 +1045,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 5cd032d86b2b5cf34c2dda8b7650df4725a71ae7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 13:50:43 -0500 Subject: [PATCH 068/214] get people info during media refresh --- .../Entities/PeopleHelper.cs | 17 +++++-- MediaBrowser.Controller/Entities/Person.cs | 12 ++++- .../Manager/MetadataService.cs | 43 +++++++++++++++++ .../Movies/GenericMovieDbInfo.cs | 47 +++++++++++++++++-- .../TV/TvdbSeriesProvider.cs | 15 ++++++ 5 files changed, 126 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 3468ca2d5..40a93d9e6 100644 --- a/MediaBrowser.Controller/Entities/PeopleHelper.cs +++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.Controller.Entities if (existing != null) { existing.Type = PersonType.GuestStar; - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); return; } } @@ -67,7 +67,7 @@ namespace MediaBrowser.Controller.Entities existing.Role = person.Role; } - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); } } else @@ -83,11 +83,22 @@ namespace MediaBrowser.Controller.Entities } else { - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); } } } + private static void MergeExisting(PersonInfo existing, PersonInfo person) + { + existing.SortOrder = person.SortOrder ?? existing.SortOrder; + existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl; + + foreach (var id in person.ProviderIds) + { + existing.SetProviderId(id.Key, id.Value); + } + } + public static bool ContainsPerson(List people, string name) { if (string.IsNullOrWhiteSpace(name)) diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 6c277da56..a365b99c6 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Entities { @@ -106,8 +107,13 @@ namespace MediaBrowser.Controller.Entities /// /// This is the small Person stub that is attached to BaseItems /// - public class PersonInfo + public class PersonInfo : IHasProviderIds { + public PersonInfo() + { + ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + public Guid ItemId { get; set; } /// @@ -132,6 +138,10 @@ namespace MediaBrowser.Controller.Entities /// The sort order. public int? SortOrder { get; set; } + public string ImageUrl { get; set; } + + public Dictionary ProviderIds { get; set; } + /// /// Returns a that represents this instance. /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 083c8f1f3..d9f5c30fd 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -254,10 +254,53 @@ namespace MediaBrowser.Providers.Manager if (result.Item.SupportsPeople && result.People != null) { await LibraryManager.UpdatePeople(result.Item as BaseItem, result.People.ToList()); + await SavePeopleMetadata(result.People, cancellationToken).ConfigureAwait(false); } await result.Item.UpdateToRepository(reason, cancellationToken).ConfigureAwait(false); } + private async Task SavePeopleMetadata(List people, CancellationToken cancellationToken) + { + foreach (var person in people) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl)) + { + var updateType = ItemUpdateType.MetadataDownload; + + var saveEntity = false; + var personEntity = LibraryManager.GetPerson(person.Name); + foreach (var id in person.ProviderIds) + { + if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase)) + { + personEntity.SetProviderId(id.Key, id.Value); + saveEntity = true; + } + } + + if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) + { + personEntity.SetImage(new ItemImageInfo + { + Path = person.ImageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); + + saveEntity = true; + updateType = updateType | ItemUpdateType.ImageUpdate; + } + + if (saveEntity) + { + await personEntity.UpdateToRepository(updateType, cancellationToken).ConfigureAwait(false); + } + } + } + } + private readonly Task _cachedTask = Task.FromResult(true); protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 3c2d9c82f..abd4a6202 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -104,7 +104,9 @@ namespace MediaBrowser.Providers.Movies dataFilePath = dataFilePath ?? MovieDbProvider.Current.GetDataFilePath(tmdbId, language); movieInfo = movieInfo ?? _jsonSerializer.DeserializeFromFile(dataFilePath); - ProcessMainInfo(item, preferredCountryCode, movieInfo); + var settings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); + + ProcessMainInfo(item, settings, preferredCountryCode, movieInfo); item.HasMetadata = true; } @@ -115,9 +117,10 @@ namespace MediaBrowser.Providers.Movies /// Processes the main info. /// /// The result item. + /// The settings. /// The preferred country code. /// The movie data. - private void ProcessMainInfo(MetadataResult resultItem, string preferredCountryCode, MovieDbProvider.CompleteMovieData movieData) + private void ProcessMainInfo(MetadataResult resultItem, TmdbSettingsResult settings, string preferredCountryCode, MovieDbProvider.CompleteMovieData movieData) { var movie = resultItem.Item; @@ -247,6 +250,7 @@ namespace MediaBrowser.Providers.Movies } resultItem.ResetPeople(); + var tmdbImageUrl = settings.images.base_url + "original"; //Actors, Directors, Writers - all in People //actors come from cast @@ -254,7 +258,25 @@ namespace MediaBrowser.Providers.Movies { foreach (var actor in movieData.casts.cast.OrderBy(a => a.order)) { - resultItem.AddPerson(new PersonInfo { Name = actor.name.Trim(), Role = actor.character, Type = PersonType.Actor, SortOrder = actor.order }); + var personInfo = new PersonInfo + { + Name = actor.name.Trim(), + Role = actor.character, + Type = PersonType.Actor, + SortOrder = actor.order + }; + + if (!string.IsNullOrWhiteSpace(actor.profile_path)) + { + personInfo.ImageUrl = tmdbImageUrl + actor.profile_path; + } + + if (actor.id > 0) + { + personInfo.SetProviderId(MetadataProviders.Tmdb, actor.id.ToString(CultureInfo.InvariantCulture)); + } + + resultItem.AddPerson(personInfo); } } @@ -270,7 +292,24 @@ namespace MediaBrowser.Providers.Movies type = PersonType.Writer; } - resultItem.AddPerson(new PersonInfo { Name = person.name.Trim(), Role = person.job, Type = type }); + var personInfo = new PersonInfo + { + Name = person.name.Trim(), + Role = person.job, + Type = type + }; + + if (!string.IsNullOrWhiteSpace(person.profile_path)) + { + personInfo.ImageUrl = tmdbImageUrl + person.profile_path; + } + + if (person.id > 0) + { + personInfo.SetProviderId(MetadataProviders.Tmdb, person.id.ToString(CultureInfo.InvariantCulture)); + } + + resultItem.AddPerson(personInfo); } } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 9452438cb..00bc032ca 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -826,6 +826,21 @@ namespace MediaBrowser.Providers.TV break; } + case "id": + { + break; + } + + case "Image": + { + var url = (reader.ReadElementContentAsString() ?? string.Empty).Trim(); + if (!string.IsNullOrWhiteSpace(url)) + { + personInfo.ImageUrl = TVUtils.BannerUrl + url; + } + break; + } + case "SortOrder": { var val = reader.ReadElementContentAsString(); From 9719b8d532fdbf4e611d2f75ba036339e972bc30 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 13:56:28 -0500 Subject: [PATCH 069/214] 3.0.5842 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 8791b5ec5..9054ef0b6 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5841")] +[assembly: AssemblyVersion("3.0.5842")] From 7e0f97b2c371e6d96dc1ed0748f8054e27e82ea1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 14:45:52 -0500 Subject: [PATCH 070/214] trim logging --- .../TV/MissingEpisodeProvider.cs | 2 +- .../HttpServer/HttpListenerHost.cs | 6 +- .../SocketSharp/WebSocketSharpListener.cs | 56 +++++++++++-------- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 19eda4905..9c0e0b873 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Providers.TV } catch (DirectoryNotFoundException) { - _logger.Warn("Series files missing for series id {0}", seriesGroup.Key); + //_logger.Warn("Series files missing for series id {0}", seriesGroup.Key); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 0283c1f7a..6a23a8497 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -154,10 +154,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer return this; } - private void OnRequestReceived(string localEndPoint) - { - } - /// /// Starts the Web Service /// @@ -177,7 +173,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private IHttpListener GetListener() { - return new WebSocketSharpListener(_logger, OnRequestReceived, CertificatePath); + return new WebSocketSharpListener(_logger, CertificatePath); } private void OnWebSocketConnecting(WebSocketConnectingEventArgs args) diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 9f80c8ac9..a91b1e3ed 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -7,6 +7,7 @@ using ServiceStack.Web; using SocketHttpListener.Net; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -18,14 +19,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private HttpListener _listener; private readonly ILogger _logger; - private readonly Action _endpointListener; private readonly string _certificatePath; - public WebSocketSharpListener(ILogger logger, Action endpointListener, - string certificatePath) + public WebSocketSharpListener(ILogger logger, string certificatePath) { _logger = logger; - _endpointListener = endpointListener; _certificatePath = certificatePath; } @@ -80,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { var request = context.Request; - LogHttpRequest(request); + LogRequest(_logger, request); if (request.IsWebSocketRequest) { @@ -96,24 +94,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return RequestHandler(httpReq, request.Url); } - /// - /// Logs the HTTP request. - /// - /// The request. - private void LogHttpRequest(HttpListenerRequest request) - { - var endpoint = request.LocalEndPoint; - - if (endpoint != null) - { - var address = endpoint.ToString(); - - _endpointListener(address); - } - - LogRequest(_logger, request); - } - private void ProcessWebSocketRequest(HttpListenerContext ctx) { try @@ -183,7 +163,35 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp /// The request. private static void LogRequest(ILogger logger, HttpListenerRequest request) { - logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), request.Url, request.UserAgent ?? string.Empty); + var url = request.Url.ToString(); + var extension = Path.GetExtension(url); + + if (string.Equals(extension, ".js", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".css", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".woff", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".woff2", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".ttf", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".html", StringComparison.OrdinalIgnoreCase)) + { + return; + } + + logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), url, request.UserAgent ?? string.Empty); } private void HandleError(Exception ex, HttpListenerContext context) From ccd237c4ded8dda7edfd6b7ab0fa86731cbad1ff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 15:40:20 -0500 Subject: [PATCH 071/214] disable http compression --- .../Security/PluginSecurityManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index d8f350207..a6dbf77e9 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -258,7 +258,17 @@ namespace MediaBrowser.Common.Implementations.Security try { - using (var json = await _httpClient.Post(MBValidateUrl, data, CancellationToken.None).ConfigureAwait(false)) + var options = new HttpRequestOptions + { + Url = MBValidateUrl, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var json = (await _httpClient.Post(options).ConfigureAwait(false)).Content) { reg = _jsonSerializer.DeserializeFromStream(json); success = true; From 5dc32c49a9cf06d96450df59ccbd6a141463e6a6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 21:29:00 -0500 Subject: [PATCH 072/214] update cdart order --- .../Images/LocalImageProvider.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index 1cadef7f2..afbc2640d 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -129,8 +129,19 @@ namespace MediaBrowser.LocalMetadata.Images AddImage(files, images, "logo", imagePrefix, isInMixedFolder, ImageType.Logo); AddImage(files, images, "clearart", imagePrefix, isInMixedFolder, ImageType.Art); - AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); - AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + + // For music albums, prefer cdart before disc + if (item is MusicAlbum) + { + AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); + } + else + { + AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); + AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + } + AddImage(files, images, "box", imagePrefix, isInMixedFolder, ImageType.Box); AddImage(files, images, "back", imagePrefix, isInMixedFolder, ImageType.BoxRear); AddImage(files, images, "boxrear", imagePrefix, isInMixedFolder, ImageType.BoxRear); From b050772b77682922226635675cd8b7a16efa4917 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 22:02:28 -0500 Subject: [PATCH 073/214] 3.0.5843 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 9054ef0b6..05ebe1ef8 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5842")] +[assembly: AssemblyVersion("3.0.5843")] From 570d63d783e4975486f907b5d63d8af954044723 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 14:45:52 -0500 Subject: [PATCH 074/214] trim logging --- .../TV/MissingEpisodeProvider.cs | 2 +- .../HttpServer/HttpListenerHost.cs | 6 +- .../SocketSharp/WebSocketSharpListener.cs | 56 +++++++++++-------- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 19eda4905..9c0e0b873 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Providers.TV } catch (DirectoryNotFoundException) { - _logger.Warn("Series files missing for series id {0}", seriesGroup.Key); + //_logger.Warn("Series files missing for series id {0}", seriesGroup.Key); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 0283c1f7a..6a23a8497 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -154,10 +154,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer return this; } - private void OnRequestReceived(string localEndPoint) - { - } - /// /// Starts the Web Service /// @@ -177,7 +173,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private IHttpListener GetListener() { - return new WebSocketSharpListener(_logger, OnRequestReceived, CertificatePath); + return new WebSocketSharpListener(_logger, CertificatePath); } private void OnWebSocketConnecting(WebSocketConnectingEventArgs args) diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 9f80c8ac9..a91b1e3ed 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -7,6 +7,7 @@ using ServiceStack.Web; using SocketHttpListener.Net; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -18,14 +19,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp private HttpListener _listener; private readonly ILogger _logger; - private readonly Action _endpointListener; private readonly string _certificatePath; - public WebSocketSharpListener(ILogger logger, Action endpointListener, - string certificatePath) + public WebSocketSharpListener(ILogger logger, string certificatePath) { _logger = logger; - _endpointListener = endpointListener; _certificatePath = certificatePath; } @@ -80,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { var request = context.Request; - LogHttpRequest(request); + LogRequest(_logger, request); if (request.IsWebSocketRequest) { @@ -96,24 +94,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return RequestHandler(httpReq, request.Url); } - /// - /// Logs the HTTP request. - /// - /// The request. - private void LogHttpRequest(HttpListenerRequest request) - { - var endpoint = request.LocalEndPoint; - - if (endpoint != null) - { - var address = endpoint.ToString(); - - _endpointListener(address); - } - - LogRequest(_logger, request); - } - private void ProcessWebSocketRequest(HttpListenerContext ctx) { try @@ -183,7 +163,35 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp /// The request. private static void LogRequest(ILogger logger, HttpListenerRequest request) { - logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), request.Url, request.UserAgent ?? string.Empty); + var url = request.Url.ToString(); + var extension = Path.GetExtension(url); + + if (string.Equals(extension, ".js", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".css", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".woff", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".woff2", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".ttf", StringComparison.OrdinalIgnoreCase)) + { + return; + } + if (string.Equals(extension, ".html", StringComparison.OrdinalIgnoreCase)) + { + return; + } + + logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), url, request.UserAgent ?? string.Empty); } private void HandleError(Exception ex, HttpListenerContext context) From 55d3f89d22c7bac5c5da2c83fc7c9a0504185747 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 15:40:20 -0500 Subject: [PATCH 075/214] disable http compression --- .../Security/PluginSecurityManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index d8f350207..a6dbf77e9 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -258,7 +258,17 @@ namespace MediaBrowser.Common.Implementations.Security try { - using (var json = await _httpClient.Post(MBValidateUrl, data, CancellationToken.None).ConfigureAwait(false)) + var options = new HttpRequestOptions + { + Url = MBValidateUrl, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var json = (await _httpClient.Post(options).ConfigureAwait(false)).Content) { reg = _jsonSerializer.DeserializeFromStream(json); success = true; From 6d45337e7bc17e7bf167b041a1b7bebba26711fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 21:29:00 -0500 Subject: [PATCH 076/214] update cdart order --- .../Images/LocalImageProvider.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index 1cadef7f2..afbc2640d 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -129,8 +129,19 @@ namespace MediaBrowser.LocalMetadata.Images AddImage(files, images, "logo", imagePrefix, isInMixedFolder, ImageType.Logo); AddImage(files, images, "clearart", imagePrefix, isInMixedFolder, ImageType.Art); - AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); - AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + + // For music albums, prefer cdart before disc + if (item is MusicAlbum) + { + AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); + } + else + { + AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc); + AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc); + } + AddImage(files, images, "box", imagePrefix, isInMixedFolder, ImageType.Box); AddImage(files, images, "back", imagePrefix, isInMixedFolder, ImageType.BoxRear); AddImage(files, images, "boxrear", imagePrefix, isInMixedFolder, ImageType.BoxRear); From 1fe1908aeea9b1273c63edb19f187cef1f688d7a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 21:59:07 -0500 Subject: [PATCH 077/214] sync image file names --- .../Images/LocalImageProvider.cs | 40 +++++--- MediaBrowser.Providers/Manager/ImageSaver.cs | 91 ++++++++++--------- 2 files changed, 73 insertions(+), 58 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index afbc2640d..c6f81d874 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -122,6 +122,16 @@ namespace MediaBrowser.LocalMetadata.Images private void PopulateImages(IHasImages item, List images, List files, bool supportParentSeriesFiles, IDirectoryService directoryService) { + if (supportParentSeriesFiles) + { + var season = item as Season; + + if (season != null) + { + PopulateSeasonImagesFromSeriesFolder(season, images, directoryService); + } + } + var imagePrefix = item.FileNameWithoutExtension + "-"; var isInMixedFolder = item.IsInMixedFolder; @@ -151,33 +161,33 @@ namespace MediaBrowser.LocalMetadata.Images AddImage(files, images, "banner", imagePrefix, isInMixedFolder, ImageType.Banner); // Thumb - AddImage(files, images, "thumb", imagePrefix, isInMixedFolder, ImageType.Thumb); AddImage(files, images, "landscape", imagePrefix, isInMixedFolder, ImageType.Thumb); + AddImage(files, images, "thumb", imagePrefix, isInMixedFolder, ImageType.Thumb); PopulateBackdrops(item, images, files, imagePrefix, isInMixedFolder, directoryService); PopulateScreenshots(images, files, imagePrefix, isInMixedFolder); - - if (supportParentSeriesFiles) - { - var season = item as Season; - - if (season != null) - { - PopulateSeasonImagesFromSeriesFolder(season, images, directoryService); - } - } } private void PopulatePrimaryImages(IHasImages item, List images, List files, string imagePrefix, bool isInMixedFolder) { var names = new List { - "folder", - "poster", "cover", "default" }; + if (item is MusicAlbum || item is MusicArtist) + { + // these prefer folder + names.Insert(0, "poster"); + names.Insert(0, "folder"); + } + else + { + names.Insert(0, "folder"); + names.Insert(0, "poster"); + } + // Support plex/kodi convention if (item is Series) { @@ -212,8 +222,6 @@ namespace MediaBrowser.LocalMetadata.Images private void PopulateBackdrops(IHasImages item, List images, List files, string imagePrefix, bool isInMixedFolder, IDirectoryService directoryService) { - PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop); - if (!string.IsNullOrEmpty(item.Path)) { var name = item.FileNameWithoutExtension; @@ -241,6 +249,8 @@ namespace MediaBrowser.LocalMetadata.Images { PopulateBackdropsFromExtraFanart(extraFanartFolder.FullName, images, directoryService); } + + PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop); } private void PopulateBackdropsFromExtraFanart(string path, List images, IDirectoryService directoryService) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 4542c9c42..4bec352f6 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -332,7 +332,50 @@ namespace MediaBrowser.Providers.Manager /// private string GetStandardSavePath(IHasImages item, ImageType type, int? imageIndex, string mimeType, bool saveLocally) { + var season = item as Season; + var extension = MimeTypes.ToExtension(mimeType); + + if (type == ImageType.Thumb && saveLocally) + { + if (season != null && season.IndexNumber.HasValue) + { + var seriesFolder = season.SeriesPath; + + var seasonMarker = season.IndexNumber.Value == 0 + ? "-specials" + : season.IndexNumber.Value.ToString("00", UsCulture); + + var imageFilename = "season" + seasonMarker + "-landscape" + extension; + + return Path.Combine(seriesFolder, imageFilename); + } + + if (item.IsInMixedFolder) + { + return GetSavePathForItemInMixedFolder(item, type, "landscape", extension); + } + + return Path.Combine(item.ContainingFolderPath, "landscape" + extension); + } + + if (type == ImageType.Banner && saveLocally) + { + if (season != null && season.IndexNumber.HasValue) + { + var seriesFolder = season.SeriesPath; + + var seasonMarker = season.IndexNumber.Value == 0 + ? "-specials" + : season.IndexNumber.Value.ToString("00", UsCulture); + + var imageFilename = "season" + seasonMarker + "-banner" + extension; + + return Path.Combine(seriesFolder, imageFilename); + } + } + string filename; + var folderName = item is MusicAlbum || item is MusicArtist ? "folder" : "poster"; switch (type) { @@ -342,11 +385,14 @@ namespace MediaBrowser.Providers.Manager case ImageType.BoxRear: filename = "back"; break; + case ImageType.Thumb: + filename = "landscape"; + break; case ImageType.Disc: filename = item is MusicAlbum ? "cdart" : "disc"; break; case ImageType.Primary: - filename = item is Episode ? _fileSystem.GetFileNameWithoutExtension(item.Path) : "folder"; + filename = item is Episode ? _fileSystem.GetFileNameWithoutExtension(item.Path) : folderName; break; case ImageType.Backdrop: filename = GetBackdropSaveFilename(item.GetImages(type), "backdrop", "backdrop", imageIndex); @@ -359,8 +405,6 @@ namespace MediaBrowser.Providers.Manager break; } - var extension = mimeType.Split('/').Last(); - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) { extension = "jpg"; @@ -393,7 +437,7 @@ namespace MediaBrowser.Providers.Manager { if (string.IsNullOrEmpty(filename)) { - filename = "folder"; + filename = folderName; } path = Path.Combine(item.GetInternalMetadataPath(), filename + extension); } @@ -526,45 +570,6 @@ namespace MediaBrowser.Providers.Manager return new[] { Path.Combine(item.ContainingFolderPath, "poster" + extension) }; } - if (type == ImageType.Banner) - { - if (season != null && season.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = season.IndexNumber.Value == 0 - ? "-specials" - : season.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-banner" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - } - - if (type == ImageType.Thumb) - { - if (season != null && season.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = season.IndexNumber.Value == 0 - ? "-specials" - : season.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-landscape" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - - if (item.IsInMixedFolder) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, "landscape", extension) }; - } - - return new[] { Path.Combine(item.ContainingFolderPath, "landscape" + extension) }; - } - // All other paths are the same return new[] { GetStandardSavePath(item, type, imageIndex, mimeType, true) }; } From 8b545fea51eb68c952e928e675c375a984f8ebf0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 23:03:30 -0500 Subject: [PATCH 078/214] update naming project --- .../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 e5c94a01b..b51c688b4 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -48,9 +48,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\MediaBrowser.Naming.1.0.0.41\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.42\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 5c04f2782..4b643fe21 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -2,7 +2,7 @@ - + From 08d9c1fc2d8c64001cc60dd72d15bd7da4162ef2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 23:09:19 -0500 Subject: [PATCH 079/214] 3.0.5817 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 706b83996..76cc4acd2 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5816")] +[assembly: AssemblyVersion("3.0.5817")] From 6d31d60fe174953f98cbfbc55f36b21f8292243b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 12:47:46 -0500 Subject: [PATCH 080/214] update mac project --- MediaBrowser.Server.Mac/Emby.Server.Mac.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index f7a6a8cd6..e3887f637 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -79,7 +79,7 @@ False - ..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll From 86e7f58bb627d7d87f401dd811b1f32bd6e44c20 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 13:20:38 -0500 Subject: [PATCH 081/214] 3.0.5844 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 05ebe1ef8..68d67c063 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5843")] +[assembly: AssemblyVersion("3.0.5844")] From eca02c7360e69fb2c2ef17427d6315587d625e3d Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 22 Jan 2016 13:31:57 -0500 Subject: [PATCH 082/214] update mac project --- .../Emby.Server.Mac.csproj | 24 ++++++++++++++----- MediaBrowser.Server.Mac/Main.cs | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index e3887f637..4e6bfaa43 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -506,6 +506,9 @@ Resources\dashboard-ui\selectserver.html + + Resources\dashboard-ui\serversecurity.html + Resources\dashboard-ui\shared.html @@ -1139,6 +1142,15 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\images\imagehelper.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\images\persistentimagefetcher.js + Resources\dashboard-ui\bower_components\fastclick\.bower.json @@ -1301,6 +1313,9 @@ 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 @@ -4640,9 +4655,6 @@ Resources\dashboard-ui\components\humanedate.js - - Resources\dashboard-ui\components\imagestore.js - Resources\dashboard-ui\components\paperdialoghelper.js @@ -5531,6 +5543,9 @@ Resources\dashboard-ui\scripts\selectserver.js + + Resources\dashboard-ui\scripts\serversecurity.js + Resources\dashboard-ui\scripts\shared.js @@ -5882,9 +5897,6 @@ Resources\dashboard-ui\themes\holiday\theme.js - - Resources\dashboard-ui\thirdparty\jquery.unveil-custom.js - Resources\dashboard-ui\thirdparty\paper-button-style.css diff --git a/MediaBrowser.Server.Mac/Main.cs b/MediaBrowser.Server.Mac/Main.cs index 67effa95f..b7e158c5d 100644 --- a/MediaBrowser.Server.Mac/Main.cs +++ b/MediaBrowser.Server.Mac/Main.cs @@ -96,7 +96,7 @@ namespace MediaBrowser.Server.Mac var nativeApp = new NativeApp(); - AppHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "MBServer.Mono", nativeApp); + AppHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "Emby.Server.Mac.pkg", nativeApp); if (options.ContainsOption("-v")) { Console.WriteLine (AppHost.ApplicationVersion.ToString()); From 24b65b303fcfdd271b885dd4b7eab6c1a04c894e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 14:16:30 -0500 Subject: [PATCH 083/214] adjust default library monitor behavior --- MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 97f082295..85ea8ec57 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -160,7 +160,7 @@ namespace MediaBrowser.Server.Implementations.IO switch (ConfigurationManager.Configuration.EnableLibraryMonitor) { case AutoOnOff.Auto: - return _appHost.SupportsLibraryMonitor; + return Environment.OSVersion.Platform == PlatformID.Win32NT; case AutoOnOff.Enabled: return true; default: From 02ad5527926a3081b828300546b6945978f7da04 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 14:16:30 -0500 Subject: [PATCH 084/214] adjust default library monitor behavior --- MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 97f082295..85ea8ec57 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -160,7 +160,7 @@ namespace MediaBrowser.Server.Implementations.IO switch (ConfigurationManager.Configuration.EnableLibraryMonitor) { case AutoOnOff.Auto: - return _appHost.SupportsLibraryMonitor; + return Environment.OSVersion.Platform == PlatformID.Win32NT; case AutoOnOff.Enabled: return true; default: From db0bb0e070462af70c4aa2c2ae8f53311c1ea931 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:35:43 -0500 Subject: [PATCH 085/214] add dvbsub as not text --- MediaBrowser.Model/Entities/MediaStream.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 7f4cc2f84..1e19a0601 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -195,6 +195,7 @@ namespace MediaBrowser.Model.Entities return StringHelper.IndexOfIgnoreCase(codec, "pgs") == -1 && StringHelper.IndexOfIgnoreCase(codec, "dvd") == -1 && + StringHelper.IndexOfIgnoreCase(codec, "dvbsub") == -1 && !StringHelper.EqualsIgnoreCase(codec, "sub"); } From 636c7cc3ab9bb4444fb6bbb39904c76709d8c3e4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:57:35 -0500 Subject: [PATCH 086/214] add version to all tmdb requests --- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index b7530ebb4..f7e4142fa 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -20,6 +20,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common; using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.Movies @@ -40,10 +41,11 @@ namespace MediaBrowser.Providers.Movies private readonly ILogger _logger; private readonly ILocalizationManager _localization; private readonly ILibraryManager _libraryManager; + private readonly IApplicationHost _appHost; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public MovieDbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization, ILibraryManager libraryManager) + public MovieDbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization, ILibraryManager libraryManager, IApplicationHost appHost) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; @@ -52,6 +54,7 @@ namespace MediaBrowser.Providers.Movies _logger = logger; _localization = localization; _libraryManager = libraryManager; + _appHost = appHost; Current = this; } @@ -160,7 +163,8 @@ namespace MediaBrowser.Providers.Movies { Url = string.Format(TmdbConfigUrl, ApiKey), CancellationToken = cancellationToken, - AcceptHeader = AcceptHeader + AcceptHeader = AcceptHeader, + UserAgent = "Emby/" + _appHost.ApplicationVersion }).ConfigureAwait(false)) { From 468a498768a87f5a2388a3fef9d0b6ab760e32f5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:58:22 -0500 Subject: [PATCH 087/214] update movie db user agent --- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index f7e4142fa..593c6f180 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -163,8 +163,7 @@ namespace MediaBrowser.Providers.Movies { Url = string.Format(TmdbConfigUrl, ApiKey), CancellationToken = cancellationToken, - AcceptHeader = AcceptHeader, - UserAgent = "Emby/" + _appHost.ApplicationVersion + AcceptHeader = AcceptHeader }).ConfigureAwait(false)) { @@ -391,6 +390,8 @@ namespace MediaBrowser.Providers.Movies options.ResourcePool = MovieDbResourcePool; _lastRequestTicks = DateTime.UtcNow.Ticks; + options.UserAgent = "Emby/" + _appHost.ApplicationVersion; + return await _httpClient.Get(options).ConfigureAwait(false); } From 3f0927fb60560b0fb4aed7ef7215a688f2f548da Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 21:32:14 -0500 Subject: [PATCH 088/214] throttle people requests --- MediaBrowser.Api/ItemRefreshService.cs | 3 +- .../Providers/ImageRefreshOptions.cs | 2 + .../Providers/ItemLookupInfo.cs | 4 +- .../Manager/MetadataService.cs | 1 + .../People/MovieDbPersonProvider.cs | 38 ++++++++++++++++++- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index af1f1c90a..1e912c92d 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -76,7 +76,8 @@ namespace MediaBrowser.Api ImageRefreshMode = request.ImageRefreshMode, ReplaceAllImages = request.ReplaceAllImages, ReplaceAllMetadata = request.ReplaceAllMetadata, - ForceSave = true + ForceSave = true, + IsAutomated = false }; } } diff --git a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs index a66cc6f22..9b21a2972 100644 --- a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs @@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Providers public bool ReplaceAllImages { get; set; } public List ReplaceImages { get; set; } + public bool IsAutomated { get; set; } public ImageRefreshOptions(IDirectoryService directoryService) { @@ -18,6 +19,7 @@ namespace MediaBrowser.Controller.Providers DirectoryService = directoryService; ReplaceImages = new List(); + IsAutomated = true; } public bool IsReplacingImage(ImageType type) diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs index 7114cde3e..dc7a04135 100644 --- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs @@ -33,10 +33,12 @@ namespace MediaBrowser.Controller.Providers public int? Year { get; set; } public int? IndexNumber { get; set; } public int? ParentIndexNumber { get; set; } - public DateTime? PremiereDate { get; set; } + public DateTime? PremiereDate { get; set; } + public bool IsAutomated { get; set; } public ItemLookupInfo() { + IsAutomated = true; ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index d9f5c30fd..e18da565d 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -138,6 +138,7 @@ namespace MediaBrowser.Providers.Manager var id = itemOfType.GetLookupInfo(); //await FindIdentities(id, cancellationToken).ConfigureAwait(false); + id.IsAutomated = refreshOptions.IsAutomated; var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 4e652a428..0dab24b11 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; using MediaBrowser.Providers.Movies; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -18,6 +19,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.People @@ -32,14 +34,30 @@ namespace MediaBrowser.Providers.People private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _configurationManager; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient) + private int _requestCount; + private readonly object _requestCountLock = new object(); + private Timer _requestCountReset; + + public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger) { _fileSystem = fileSystem; _configurationManager = configurationManager; _jsonSerializer = jsonSerializer; _httpClient = httpClient; + _logger = logger; Current = this; + + _requestCountReset = new Timer(OnRequestThrottleTimerFired, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); + } + + private void OnRequestThrottleTimerFired(object state) + { + lock (_requestCountLock) + { + _requestCount = 0; + } } public string Name @@ -79,6 +97,24 @@ namespace MediaBrowser.Providers.People return new[] { result }; } + if (searchInfo.IsAutomated) + { + lock (_requestCountLock) + { + var requestCount = _requestCount; + + if (requestCount >= 5) + { + _logger.Debug("Throttling Tmdb people"); + + // This needs to be throttled + return new List(); + } + + _requestCount = requestCount + 1; + } + } + var url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions From 1e62332d3d98ffad615b927c1a9960e118db75bd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 22:10:11 -0500 Subject: [PATCH 089/214] trim logging --- MediaBrowser.Providers/People/MovieDbPersonProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 0dab24b11..5c5919709 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Providers.People if (requestCount >= 5) { - _logger.Debug("Throttling Tmdb people"); + //_logger.Debug("Throttling Tmdb people"); // This needs to be throttled return new List(); From 111cf1d31522385fa62d8ee4b0cd310a567986d1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 22:10:21 -0500 Subject: [PATCH 090/214] trim logging --- .../HttpServer/HttpListenerHost.cs | 34 +++++++++++++-- .../HttpServer/LoggerUtils.cs | 19 +++++++++ .../SocketSharp/WebSocketSharpListener.cs | 42 +------------------ 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 6a23a8497..8d8d7f6f7 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -256,6 +256,25 @@ namespace MediaBrowser.Server.Implementations.HttpServer } } + private readonly Dictionary _skipLogExtensions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + {".js", 0}, + {".css", 0}, + {".woff", 0}, + {".woff2", 0}, + {".ttf", 0}, + {".html", 0} + }; + + private bool EnableLogging(string url) + { + var parts = url.Split(new[] { '?' }, 2); + + var extension = Path.GetExtension(parts[0]); + + return string.IsNullOrWhiteSpace(extension) || !_skipLogExtensions.ContainsKey(extension); + } + /// /// Overridable method that can be used to implement a custom hnandler /// @@ -271,6 +290,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer var operationName = httpReq.OperationName; var localPath = url.LocalPath; + var urlString = url.ToString(); + var enableLog = EnableLogging(urlString); + + if (enableLog) + { + LoggerUtils.LogRequest(_logger, urlString, httpReq.HttpMethod, httpReq.UserAgent); + } + if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase)) { @@ -333,15 +360,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer task.ContinueWith(x => httpRes.Close(), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent); //Matches Exceptions handled in HttpListenerBase.InitTask() - var urlString = url.ToString(); - task.ContinueWith(x => { var statusCode = httpRes.StatusCode; var duration = DateTime.Now - date; - LoggerUtils.LogResponse(_logger, statusCode, urlString, remoteIp, duration); + if (enableLog) + { + LoggerUtils.LogResponse(_logger, statusCode, urlString, remoteIp, duration); + } }, TaskContinuationOptions.None); return task; diff --git a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs index fae702023..0b8caaa6e 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs @@ -1,11 +1,30 @@ using MediaBrowser.Model.Logging; using System; using System.Globalization; +using System.IO; +using SocketHttpListener.Net; namespace MediaBrowser.Server.Implementations.HttpServer { public static class LoggerUtils { + /// + /// Logs the request. + /// + /// The logger. + /// The request. + public static void LogRequest(ILogger logger, HttpListenerRequest request) + { + var url = request.Url.ToString(); + + logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), url, request.UserAgent ?? string.Empty); + } + + public static void LogRequest(ILogger logger, string url, string method, string userAgent) + { + logger.Info("{0} {1}. UserAgent: {2}", ("HTTP " + method), url, userAgent ?? string.Empty); + } + /// /// Logs the response. /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index a91b1e3ed..a029e0955 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -78,10 +78,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { var request = context.Request; - LogRequest(_logger, request); - if (request.IsWebSocketRequest) { + LoggerUtils.LogRequest(_logger, request); + ProcessWebSocketRequest(context); return Task.FromResult(true); } @@ -156,44 +156,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return req; } - /// - /// Logs the request. - /// - /// The logger. - /// The request. - private static void LogRequest(ILogger logger, HttpListenerRequest request) - { - var url = request.Url.ToString(); - var extension = Path.GetExtension(url); - - if (string.Equals(extension, ".js", StringComparison.OrdinalIgnoreCase)) - { - return; - } - if (string.Equals(extension, ".css", StringComparison.OrdinalIgnoreCase)) - { - return; - } - if (string.Equals(extension, ".woff", StringComparison.OrdinalIgnoreCase)) - { - return; - } - if (string.Equals(extension, ".woff2", StringComparison.OrdinalIgnoreCase)) - { - return; - } - if (string.Equals(extension, ".ttf", StringComparison.OrdinalIgnoreCase)) - { - return; - } - if (string.Equals(extension, ".html", StringComparison.OrdinalIgnoreCase)) - { - return; - } - - logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), url, request.UserAgent ?? string.Empty); - } - private void HandleError(Exception ex, HttpListenerContext context) { var httpReq = GetRequest(context); From 084404eaa13e69c464addc7ed3024c46082bf5d9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 22:11:37 -0500 Subject: [PATCH 091/214] 3.0.5845 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 68d67c063..5953093f9 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5844")] +[assembly: AssemblyVersion("3.0.5845")] From ed49e931182b240f623e96422604e75a61d50e91 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 03:23:02 -0500 Subject: [PATCH 092/214] support photo orientation --- Emby.Drawing/GDI/GDIImageEncoder.cs | 2 +- Emby.Drawing/IImageEncoder.cs | 3 +- .../ImageMagick/ImageMagickEncoder.cs | 20 +++++++++++- Emby.Drawing/ImageProcessor.cs | 31 ++++++++++++++++++- Emby.Drawing/NullImageEncoder.cs | 2 +- .../Dto/DtoService.cs | 26 ++++++++++++++-- 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 3df84cf11..51b4605c3 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -89,7 +89,7 @@ namespace Emby.Drawing.GDI } } - public void EncodeImage(string inputPath, string cacheFilePath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string cacheFilePath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { var hasPostProcessing = !string.IsNullOrEmpty(options.BackgroundColor) || options.UnplayedCount.HasValue || options.AddPlayedIndicator || options.PercentPlayed > 0; diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index bfd382bb7..f36498be7 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -27,12 +27,13 @@ namespace Emby.Drawing /// /// The input path. /// The output path. + /// The rotation angle. /// The width. /// The height. /// The quality. /// The options. /// The output format. - void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 6858c6d52..fd9ed5f1e 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -139,7 +139,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); @@ -150,6 +150,11 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); + if (rotationAngle > 0) + { + RotateImage(originalImage, rotationAngle); + } + DrawIndicator(originalImage, width, height, options); originalImage.CurrentImage.CompressionQuality = quality; @@ -166,6 +171,11 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); + if (rotationAngle > 0) + { + RotateImage(originalImage, rotationAngle); + } + wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0); DrawIndicator(wand, width, height, options); @@ -179,6 +189,14 @@ namespace Emby.Drawing.ImageMagick SaveDelay(); } + public static void RotateImage(MagickWand wand, float angle) + { + using (var pixelWand = new PixelWand("none", 1)) + { + wand.CurrentImage.RotateImage(pixelWand, angle); + } + } + private void ScaleImage(MagickWand wand, int width, int height) { var highQuality = false; diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index e1b92bbff..9de6d2042 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -257,7 +257,7 @@ namespace Emby.Drawing imageProcessingLockTaken = true; - _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options, outputFormat); + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, GetRotationAngle(options.Item), newWidth, newHeight, quality, options, outputFormat); } return new Tuple(cacheFilePath, GetMimeType(outputFormat, cacheFilePath)); @@ -281,6 +281,35 @@ namespace Emby.Drawing } } + private int GetRotationAngle(IHasImages item) + { + var photo = item as Photo; + if (photo != null && photo.Orientation.HasValue) + { + switch (photo.Orientation.Value) + { + case ImageOrientation.TopLeft: + return 0; + case ImageOrientation.TopRight: + return 0; + case ImageOrientation.BottomLeft: + return 270; + case ImageOrientation.BottomRight: + return 180; + case ImageOrientation.LeftBottom: + return -90; + case ImageOrientation.LeftTop: + return 0; + case ImageOrientation.RightBottom: + return 0; + case ImageOrientation.RightTop: + return 90; + } + } + + return 0; + } + private string GetMimeType(ImageFormat format, string path) { if (format == ImageFormat.Bmp) diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 1638a675a..032335a46 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index b0071828e..0cd551f6a 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1783,11 +1783,31 @@ namespace MediaBrowser.Server.Implementations.Dto } } - if (size.Width > 0 && size.Height > 0) + var width = size.Width; + var height = size.Height; + + if (width == 0 || height == 0) { - return size.Width / size.Height; + return null; } - return null; + + var photo = item as Photo; + if (photo != null && photo.Orientation.HasValue) + { + switch (photo.Orientation.Value) + { + case ImageOrientation.LeftBottom: + case ImageOrientation.LeftTop: + case ImageOrientation.RightBottom: + case ImageOrientation.RightTop: + var temp = height; + height = width; + width = temp; + break; + } + } + + return width / height; } } } From de83adb38c10ccb98f68e2904e419dc77119978c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 11:53:03 -0500 Subject: [PATCH 093/214] use image magick for auto-orientation --- Emby.Drawing/Emby.Drawing.csproj | 2 +- Emby.Drawing/GDI/GDIImageEncoder.cs | 2 +- Emby.Drawing/IImageEncoder.cs | 4 +- .../ImageMagick/ImageMagickEncoder.cs | 15 ++++--- Emby.Drawing/ImageProcessor.cs | 41 +++++++++---------- Emby.Drawing/NullImageEncoder.cs | 2 +- Emby.Drawing/packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- .../packages.config | 2 +- 9 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 45ac97ecc..06e042d74 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -37,7 +37,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 51b4605c3..bdd1c5a22 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -89,7 +89,7 @@ namespace Emby.Drawing.GDI } } - public void EncodeImage(string inputPath, string cacheFilePath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string cacheFilePath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { var hasPostProcessing = !string.IsNullOrEmpty(options.BackgroundColor) || options.UnplayedCount.HasValue || options.AddPlayedIndicator || options.PercentPlayed > 0; diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index f36498be7..73b539899 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -27,13 +27,13 @@ namespace Emby.Drawing /// /// The input path. /// The output path. - /// The rotation angle. + /// if set to true [automatic orient]. /// The width. /// The height. /// The quality. /// The options. /// The output format. - void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index fd9ed5f1e..b8300ac97 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -139,7 +139,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); @@ -150,9 +150,9 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); - if (rotationAngle > 0) + if (autoOrient) { - RotateImage(originalImage, rotationAngle); + AutoOrientImage(originalImage); } DrawIndicator(originalImage, width, height, options); @@ -171,9 +171,9 @@ namespace Emby.Drawing.ImageMagick { ScaleImage(originalImage, width, height); - if (rotationAngle > 0) + if (autoOrient) { - RotateImage(originalImage, rotationAngle); + AutoOrientImage(originalImage); } wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0); @@ -189,6 +189,11 @@ namespace Emby.Drawing.ImageMagick SaveDelay(); } + private void AutoOrientImage(MagickWand wand) + { + wand.CurrentImage.AutoOrientImage(); + } + public static void RotateImage(MagickWand wand, float angle) { using (var pixelWand = new PixelWand("none", 1)) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 9de6d2042..e01612700 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -257,7 +257,7 @@ namespace Emby.Drawing imageProcessingLockTaken = true; - _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, GetRotationAngle(options.Item), newWidth, newHeight, quality, options, outputFormat); + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, AutoOrient(options.Item), newWidth, newHeight, quality, options, outputFormat); } return new Tuple(cacheFilePath, GetMimeType(outputFormat, cacheFilePath)); @@ -281,35 +281,32 @@ namespace Emby.Drawing } } - private int GetRotationAngle(IHasImages item) + private bool AutoOrient(IHasImages item) { var photo = item as Photo; if (photo != null && photo.Orientation.HasValue) { - switch (photo.Orientation.Value) - { - case ImageOrientation.TopLeft: - return 0; - case ImageOrientation.TopRight: - return 0; - case ImageOrientation.BottomLeft: - return 270; - case ImageOrientation.BottomRight: - return 180; - case ImageOrientation.LeftBottom: - return -90; - case ImageOrientation.LeftTop: - return 0; - case ImageOrientation.RightBottom: - return 0; - case ImageOrientation.RightTop: - return 90; - } + return true; } - return 0; + return false; } + //private static int[][] OPERATIONS = new int[][] { + // TopLeft + //new int[] { 0, NONE}, + // TopRight + //new int[] { 0, HORIZONTAL}, + //new int[] {180, NONE}, + // LeftTop + //new int[] { 0, VERTICAL}, + //new int[] { 90, HORIZONTAL}, + // RightTop + //new int[] { 90, NONE}, + //new int[] {-90, HORIZONTAL}, + //new int[] {-90, NONE}, + //}; + private string GetMimeType(ImageFormat format, string path) { if (format == ImageFormat.Bmp) diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 032335a46..4fa18ce55 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, string outputPath, int rotationAngle, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 51731c474..62a241f1f 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 3e62f4735..c62983192 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -67,7 +67,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.17\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll ..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index db2bb5476..be12bcd5c 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,7 +1,7 @@  - + From aa6d6d8ec7f5e9a53d9519daa24cbc6cbdb0b33a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 13:50:43 -0500 Subject: [PATCH 094/214] get people info during media refresh --- .../Entities/PeopleHelper.cs | 17 +++++-- MediaBrowser.Controller/Entities/Person.cs | 12 ++++- .../Manager/MetadataService.cs | 43 +++++++++++++++++ .../Movies/GenericMovieDbInfo.cs | 47 +++++++++++++++++-- .../TV/TvdbSeriesProvider.cs | 15 ++++++ 5 files changed, 126 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 3468ca2d5..40a93d9e6 100644 --- a/MediaBrowser.Controller/Entities/PeopleHelper.cs +++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.Controller.Entities if (existing != null) { existing.Type = PersonType.GuestStar; - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); return; } } @@ -67,7 +67,7 @@ namespace MediaBrowser.Controller.Entities existing.Role = person.Role; } - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); } } else @@ -83,11 +83,22 @@ namespace MediaBrowser.Controller.Entities } else { - existing.SortOrder = person.SortOrder ?? existing.SortOrder; + MergeExisting(existing, person); } } } + private static void MergeExisting(PersonInfo existing, PersonInfo person) + { + existing.SortOrder = person.SortOrder ?? existing.SortOrder; + existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl; + + foreach (var id in person.ProviderIds) + { + existing.SetProviderId(id.Key, id.Value); + } + } + public static bool ContainsPerson(List people, string name) { if (string.IsNullOrWhiteSpace(name)) diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 6c277da56..a365b99c6 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Entities { @@ -106,8 +107,13 @@ namespace MediaBrowser.Controller.Entities /// /// This is the small Person stub that is attached to BaseItems /// - public class PersonInfo + public class PersonInfo : IHasProviderIds { + public PersonInfo() + { + ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + public Guid ItemId { get; set; } /// @@ -132,6 +138,10 @@ namespace MediaBrowser.Controller.Entities /// The sort order. public int? SortOrder { get; set; } + public string ImageUrl { get; set; } + + public Dictionary ProviderIds { get; set; } + /// /// Returns a that represents this instance. /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 083c8f1f3..d9f5c30fd 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -254,10 +254,53 @@ namespace MediaBrowser.Providers.Manager if (result.Item.SupportsPeople && result.People != null) { await LibraryManager.UpdatePeople(result.Item as BaseItem, result.People.ToList()); + await SavePeopleMetadata(result.People, cancellationToken).ConfigureAwait(false); } await result.Item.UpdateToRepository(reason, cancellationToken).ConfigureAwait(false); } + private async Task SavePeopleMetadata(List people, CancellationToken cancellationToken) + { + foreach (var person in people) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl)) + { + var updateType = ItemUpdateType.MetadataDownload; + + var saveEntity = false; + var personEntity = LibraryManager.GetPerson(person.Name); + foreach (var id in person.ProviderIds) + { + if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase)) + { + personEntity.SetProviderId(id.Key, id.Value); + saveEntity = true; + } + } + + if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) + { + personEntity.SetImage(new ItemImageInfo + { + Path = person.ImageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); + + saveEntity = true; + updateType = updateType | ItemUpdateType.ImageUpdate; + } + + if (saveEntity) + { + await personEntity.UpdateToRepository(updateType, cancellationToken).ConfigureAwait(false); + } + } + } + } + private readonly Task _cachedTask = Task.FromResult(true); protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 3c2d9c82f..abd4a6202 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -104,7 +104,9 @@ namespace MediaBrowser.Providers.Movies dataFilePath = dataFilePath ?? MovieDbProvider.Current.GetDataFilePath(tmdbId, language); movieInfo = movieInfo ?? _jsonSerializer.DeserializeFromFile(dataFilePath); - ProcessMainInfo(item, preferredCountryCode, movieInfo); + var settings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); + + ProcessMainInfo(item, settings, preferredCountryCode, movieInfo); item.HasMetadata = true; } @@ -115,9 +117,10 @@ namespace MediaBrowser.Providers.Movies /// Processes the main info. /// /// The result item. + /// The settings. /// The preferred country code. /// The movie data. - private void ProcessMainInfo(MetadataResult resultItem, string preferredCountryCode, MovieDbProvider.CompleteMovieData movieData) + private void ProcessMainInfo(MetadataResult resultItem, TmdbSettingsResult settings, string preferredCountryCode, MovieDbProvider.CompleteMovieData movieData) { var movie = resultItem.Item; @@ -247,6 +250,7 @@ namespace MediaBrowser.Providers.Movies } resultItem.ResetPeople(); + var tmdbImageUrl = settings.images.base_url + "original"; //Actors, Directors, Writers - all in People //actors come from cast @@ -254,7 +258,25 @@ namespace MediaBrowser.Providers.Movies { foreach (var actor in movieData.casts.cast.OrderBy(a => a.order)) { - resultItem.AddPerson(new PersonInfo { Name = actor.name.Trim(), Role = actor.character, Type = PersonType.Actor, SortOrder = actor.order }); + var personInfo = new PersonInfo + { + Name = actor.name.Trim(), + Role = actor.character, + Type = PersonType.Actor, + SortOrder = actor.order + }; + + if (!string.IsNullOrWhiteSpace(actor.profile_path)) + { + personInfo.ImageUrl = tmdbImageUrl + actor.profile_path; + } + + if (actor.id > 0) + { + personInfo.SetProviderId(MetadataProviders.Tmdb, actor.id.ToString(CultureInfo.InvariantCulture)); + } + + resultItem.AddPerson(personInfo); } } @@ -270,7 +292,24 @@ namespace MediaBrowser.Providers.Movies type = PersonType.Writer; } - resultItem.AddPerson(new PersonInfo { Name = person.name.Trim(), Role = person.job, Type = type }); + var personInfo = new PersonInfo + { + Name = person.name.Trim(), + Role = person.job, + Type = type + }; + + if (!string.IsNullOrWhiteSpace(person.profile_path)) + { + personInfo.ImageUrl = tmdbImageUrl + person.profile_path; + } + + if (person.id > 0) + { + personInfo.SetProviderId(MetadataProviders.Tmdb, person.id.ToString(CultureInfo.InvariantCulture)); + } + + resultItem.AddPerson(personInfo); } } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 9452438cb..00bc032ca 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -826,6 +826,21 @@ namespace MediaBrowser.Providers.TV break; } + case "id": + { + break; + } + + case "Image": + { + var url = (reader.ReadElementContentAsString() ?? string.Empty).Trim(); + if (!string.IsNullOrWhiteSpace(url)) + { + personInfo.ImageUrl = TVUtils.BannerUrl + url; + } + break; + } + case "SortOrder": { var val = reader.ReadElementContentAsString(); From 975f8d8f3f41bc08c1b8e4720a5dd1876b278142 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Jan 2016 21:59:07 -0500 Subject: [PATCH 095/214] sync image file names --- .../Images/LocalImageProvider.cs | 40 +++++--- MediaBrowser.Providers/Manager/ImageSaver.cs | 91 ++++++++++--------- 2 files changed, 73 insertions(+), 58 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index afbc2640d..c6f81d874 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -122,6 +122,16 @@ namespace MediaBrowser.LocalMetadata.Images private void PopulateImages(IHasImages item, List images, List files, bool supportParentSeriesFiles, IDirectoryService directoryService) { + if (supportParentSeriesFiles) + { + var season = item as Season; + + if (season != null) + { + PopulateSeasonImagesFromSeriesFolder(season, images, directoryService); + } + } + var imagePrefix = item.FileNameWithoutExtension + "-"; var isInMixedFolder = item.IsInMixedFolder; @@ -151,33 +161,33 @@ namespace MediaBrowser.LocalMetadata.Images AddImage(files, images, "banner", imagePrefix, isInMixedFolder, ImageType.Banner); // Thumb - AddImage(files, images, "thumb", imagePrefix, isInMixedFolder, ImageType.Thumb); AddImage(files, images, "landscape", imagePrefix, isInMixedFolder, ImageType.Thumb); + AddImage(files, images, "thumb", imagePrefix, isInMixedFolder, ImageType.Thumb); PopulateBackdrops(item, images, files, imagePrefix, isInMixedFolder, directoryService); PopulateScreenshots(images, files, imagePrefix, isInMixedFolder); - - if (supportParentSeriesFiles) - { - var season = item as Season; - - if (season != null) - { - PopulateSeasonImagesFromSeriesFolder(season, images, directoryService); - } - } } private void PopulatePrimaryImages(IHasImages item, List images, List files, string imagePrefix, bool isInMixedFolder) { var names = new List { - "folder", - "poster", "cover", "default" }; + if (item is MusicAlbum || item is MusicArtist) + { + // these prefer folder + names.Insert(0, "poster"); + names.Insert(0, "folder"); + } + else + { + names.Insert(0, "folder"); + names.Insert(0, "poster"); + } + // Support plex/kodi convention if (item is Series) { @@ -212,8 +222,6 @@ namespace MediaBrowser.LocalMetadata.Images private void PopulateBackdrops(IHasImages item, List images, List files, string imagePrefix, bool isInMixedFolder, IDirectoryService directoryService) { - PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop); - if (!string.IsNullOrEmpty(item.Path)) { var name = item.FileNameWithoutExtension; @@ -241,6 +249,8 @@ namespace MediaBrowser.LocalMetadata.Images { PopulateBackdropsFromExtraFanart(extraFanartFolder.FullName, images, directoryService); } + + PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop); } private void PopulateBackdropsFromExtraFanart(string path, List images, IDirectoryService directoryService) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 4542c9c42..4bec352f6 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -332,7 +332,50 @@ namespace MediaBrowser.Providers.Manager /// private string GetStandardSavePath(IHasImages item, ImageType type, int? imageIndex, string mimeType, bool saveLocally) { + var season = item as Season; + var extension = MimeTypes.ToExtension(mimeType); + + if (type == ImageType.Thumb && saveLocally) + { + if (season != null && season.IndexNumber.HasValue) + { + var seriesFolder = season.SeriesPath; + + var seasonMarker = season.IndexNumber.Value == 0 + ? "-specials" + : season.IndexNumber.Value.ToString("00", UsCulture); + + var imageFilename = "season" + seasonMarker + "-landscape" + extension; + + return Path.Combine(seriesFolder, imageFilename); + } + + if (item.IsInMixedFolder) + { + return GetSavePathForItemInMixedFolder(item, type, "landscape", extension); + } + + return Path.Combine(item.ContainingFolderPath, "landscape" + extension); + } + + if (type == ImageType.Banner && saveLocally) + { + if (season != null && season.IndexNumber.HasValue) + { + var seriesFolder = season.SeriesPath; + + var seasonMarker = season.IndexNumber.Value == 0 + ? "-specials" + : season.IndexNumber.Value.ToString("00", UsCulture); + + var imageFilename = "season" + seasonMarker + "-banner" + extension; + + return Path.Combine(seriesFolder, imageFilename); + } + } + string filename; + var folderName = item is MusicAlbum || item is MusicArtist ? "folder" : "poster"; switch (type) { @@ -342,11 +385,14 @@ namespace MediaBrowser.Providers.Manager case ImageType.BoxRear: filename = "back"; break; + case ImageType.Thumb: + filename = "landscape"; + break; case ImageType.Disc: filename = item is MusicAlbum ? "cdart" : "disc"; break; case ImageType.Primary: - filename = item is Episode ? _fileSystem.GetFileNameWithoutExtension(item.Path) : "folder"; + filename = item is Episode ? _fileSystem.GetFileNameWithoutExtension(item.Path) : folderName; break; case ImageType.Backdrop: filename = GetBackdropSaveFilename(item.GetImages(type), "backdrop", "backdrop", imageIndex); @@ -359,8 +405,6 @@ namespace MediaBrowser.Providers.Manager break; } - var extension = mimeType.Split('/').Last(); - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) { extension = "jpg"; @@ -393,7 +437,7 @@ namespace MediaBrowser.Providers.Manager { if (string.IsNullOrEmpty(filename)) { - filename = "folder"; + filename = folderName; } path = Path.Combine(item.GetInternalMetadataPath(), filename + extension); } @@ -526,45 +570,6 @@ namespace MediaBrowser.Providers.Manager return new[] { Path.Combine(item.ContainingFolderPath, "poster" + extension) }; } - if (type == ImageType.Banner) - { - if (season != null && season.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = season.IndexNumber.Value == 0 - ? "-specials" - : season.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-banner" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - } - - if (type == ImageType.Thumb) - { - if (season != null && season.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = season.IndexNumber.Value == 0 - ? "-specials" - : season.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-landscape" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - - if (item.IsInMixedFolder) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, "landscape", extension) }; - } - - return new[] { Path.Combine(item.ContainingFolderPath, "landscape" + extension) }; - } - // All other paths are the same return new[] { GetStandardSavePath(item, type, imageIndex, mimeType, true) }; } From 4f26c7496cc1e388b653fd2124b8d2c2d9d5e68c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:35:43 -0500 Subject: [PATCH 096/214] add dvbsub as not text --- MediaBrowser.Model/Entities/MediaStream.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 7f4cc2f84..1e19a0601 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -195,6 +195,7 @@ namespace MediaBrowser.Model.Entities return StringHelper.IndexOfIgnoreCase(codec, "pgs") == -1 && StringHelper.IndexOfIgnoreCase(codec, "dvd") == -1 && + StringHelper.IndexOfIgnoreCase(codec, "dvbsub") == -1 && !StringHelper.EqualsIgnoreCase(codec, "sub"); } From 49d88278ff8f3d09188288db14a57aa57851090e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:57:35 -0500 Subject: [PATCH 097/214] add version to all tmdb requests --- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index b7530ebb4..f7e4142fa 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -20,6 +20,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common; using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.Movies @@ -40,10 +41,11 @@ namespace MediaBrowser.Providers.Movies private readonly ILogger _logger; private readonly ILocalizationManager _localization; private readonly ILibraryManager _libraryManager; + private readonly IApplicationHost _appHost; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public MovieDbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization, ILibraryManager libraryManager) + public MovieDbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization, ILibraryManager libraryManager, IApplicationHost appHost) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; @@ -52,6 +54,7 @@ namespace MediaBrowser.Providers.Movies _logger = logger; _localization = localization; _libraryManager = libraryManager; + _appHost = appHost; Current = this; } @@ -160,7 +163,8 @@ namespace MediaBrowser.Providers.Movies { Url = string.Format(TmdbConfigUrl, ApiKey), CancellationToken = cancellationToken, - AcceptHeader = AcceptHeader + AcceptHeader = AcceptHeader, + UserAgent = "Emby/" + _appHost.ApplicationVersion }).ConfigureAwait(false)) { From 84684434103c008006ffb6804a2af8e3a0b1ed78 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:58:22 -0500 Subject: [PATCH 098/214] update movie db user agent --- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index f7e4142fa..593c6f180 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -163,8 +163,7 @@ namespace MediaBrowser.Providers.Movies { Url = string.Format(TmdbConfigUrl, ApiKey), CancellationToken = cancellationToken, - AcceptHeader = AcceptHeader, - UserAgent = "Emby/" + _appHost.ApplicationVersion + AcceptHeader = AcceptHeader }).ConfigureAwait(false)) { @@ -391,6 +390,8 @@ namespace MediaBrowser.Providers.Movies options.ResourcePool = MovieDbResourcePool; _lastRequestTicks = DateTime.UtcNow.Ticks; + options.UserAgent = "Emby/" + _appHost.ApplicationVersion; + return await _httpClient.Get(options).ConfigureAwait(false); } From 0181383d1e5a05b1a6950faf5e872133c987f676 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 21:32:14 -0500 Subject: [PATCH 099/214] throttle people requests --- MediaBrowser.Api/ItemRefreshService.cs | 3 +- .../Providers/ImageRefreshOptions.cs | 2 + .../Providers/ItemLookupInfo.cs | 4 +- .../Manager/MetadataService.cs | 1 + .../People/MovieDbPersonProvider.cs | 38 ++++++++++++++++++- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index af1f1c90a..1e912c92d 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -76,7 +76,8 @@ namespace MediaBrowser.Api ImageRefreshMode = request.ImageRefreshMode, ReplaceAllImages = request.ReplaceAllImages, ReplaceAllMetadata = request.ReplaceAllMetadata, - ForceSave = true + ForceSave = true, + IsAutomated = false }; } } diff --git a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs index a66cc6f22..9b21a2972 100644 --- a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs @@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Providers public bool ReplaceAllImages { get; set; } public List ReplaceImages { get; set; } + public bool IsAutomated { get; set; } public ImageRefreshOptions(IDirectoryService directoryService) { @@ -18,6 +19,7 @@ namespace MediaBrowser.Controller.Providers DirectoryService = directoryService; ReplaceImages = new List(); + IsAutomated = true; } public bool IsReplacingImage(ImageType type) diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs index 7114cde3e..dc7a04135 100644 --- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs @@ -33,10 +33,12 @@ namespace MediaBrowser.Controller.Providers public int? Year { get; set; } public int? IndexNumber { get; set; } public int? ParentIndexNumber { get; set; } - public DateTime? PremiereDate { get; set; } + public DateTime? PremiereDate { get; set; } + public bool IsAutomated { get; set; } public ItemLookupInfo() { + IsAutomated = true; ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index d9f5c30fd..e18da565d 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -138,6 +138,7 @@ namespace MediaBrowser.Providers.Manager var id = itemOfType.GetLookupInfo(); //await FindIdentities(id, cancellationToken).ConfigureAwait(false); + id.IsAutomated = refreshOptions.IsAutomated; var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 4e652a428..0dab24b11 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; using MediaBrowser.Providers.Movies; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -18,6 +19,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; namespace MediaBrowser.Providers.People @@ -32,14 +34,30 @@ namespace MediaBrowser.Providers.People private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _configurationManager; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient) + private int _requestCount; + private readonly object _requestCountLock = new object(); + private Timer _requestCountReset; + + public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger) { _fileSystem = fileSystem; _configurationManager = configurationManager; _jsonSerializer = jsonSerializer; _httpClient = httpClient; + _logger = logger; Current = this; + + _requestCountReset = new Timer(OnRequestThrottleTimerFired, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); + } + + private void OnRequestThrottleTimerFired(object state) + { + lock (_requestCountLock) + { + _requestCount = 0; + } } public string Name @@ -79,6 +97,24 @@ namespace MediaBrowser.Providers.People return new[] { result }; } + if (searchInfo.IsAutomated) + { + lock (_requestCountLock) + { + var requestCount = _requestCount; + + if (requestCount >= 5) + { + _logger.Debug("Throttling Tmdb people"); + + // This needs to be throttled + return new List(); + } + + _requestCount = requestCount + 1; + } + } + var url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions From 0eb664ccfffd8b4e4b13c1bc538b6451ffd81036 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 22:10:11 -0500 Subject: [PATCH 100/214] trim logging --- MediaBrowser.Providers/People/MovieDbPersonProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 0dab24b11..5c5919709 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Providers.People if (requestCount >= 5) { - _logger.Debug("Throttling Tmdb people"); + //_logger.Debug("Throttling Tmdb people"); // This needs to be throttled return new List(); From 478c82126593ca69890a9c086386fb7b92b0dbea Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 12:12:11 -0500 Subject: [PATCH 101/214] fix image extension --- MediaBrowser.Providers/Manager/ImageSaver.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 4bec352f6..32ea47425 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -405,12 +405,12 @@ namespace MediaBrowser.Providers.Manager break; } - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase)) { - extension = "jpg"; + extension = ".jpg"; } - extension = "." + extension.ToLower(); + extension = extension.ToLower(); string path = null; From 7a2ab5d0285ae294d02f87e52497e7f89d96512b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 12:12:11 -0500 Subject: [PATCH 102/214] fix image extension --- MediaBrowser.Providers/Manager/ImageSaver.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 4bec352f6..32ea47425 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -405,12 +405,12 @@ namespace MediaBrowser.Providers.Manager break; } - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase)) { - extension = "jpg"; + extension = ".jpg"; } - extension = "." + extension.ToLower(); + extension = extension.ToLower(); string path = null; From 9168829afc3ca74b444092d5a809baba5bcd75c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 12:15:35 -0500 Subject: [PATCH 103/214] 3.0.5846 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 5953093f9..f92aeb944 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5845")] +[assembly: AssemblyVersion("3.0.5846")] From 5636b53ed110b5db20de04641cca878937271d1f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 13:21:35 -0500 Subject: [PATCH 104/214] update http compression --- .../Connect/ConnectEntryPoint.cs | 5 ++- .../EntryPoints/UsageReporter.cs | 36 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index af81b4eea..6dab136a5 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -66,7 +66,10 @@ namespace MediaBrowser.Server.Implementations.Connect { Url = ipLookupUrl, UserAgent = "Emby/" + _appHost.ApplicationVersion, - LogErrors = logErrors + LogErrors = logErrors, + + // Seeing block length errors with our server + EnableHttpCompression = false }).ConfigureAwait(false)) { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index 5496bd9b2..be2817fd2 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _logger = logger; } - public Task ReportServerUsage(CancellationToken cancellationToken) + public async Task ReportServerUsage(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -51,10 +51,24 @@ namespace MediaBrowser.Server.Implementations.EntryPoints data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray()); - return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken); + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } } - public Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) + public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(app.DeviceId)) { @@ -79,7 +93,21 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { "platform", app.DeviceName }, }; - return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken); + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } } } From 18cd0dd98cb00068ffef082ad8a0dc6c18040471 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 13:21:35 -0500 Subject: [PATCH 105/214] update http compression --- .../Connect/ConnectEntryPoint.cs | 5 ++- .../EntryPoints/UsageReporter.cs | 36 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index af81b4eea..6dab136a5 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -66,7 +66,10 @@ namespace MediaBrowser.Server.Implementations.Connect { Url = ipLookupUrl, UserAgent = "Emby/" + _appHost.ApplicationVersion, - LogErrors = logErrors + LogErrors = logErrors, + + // Seeing block length errors with our server + EnableHttpCompression = false }).ConfigureAwait(false)) { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index 5496bd9b2..be2817fd2 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _logger = logger; } - public Task ReportServerUsage(CancellationToken cancellationToken) + public async Task ReportServerUsage(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -51,10 +51,24 @@ namespace MediaBrowser.Server.Implementations.EntryPoints data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray()); - return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken); + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } } - public Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) + public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(app.DeviceId)) { @@ -79,7 +93,21 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { "platform", app.DeviceName }, }; - return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken); + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } } } From 4e9cb26761b9195153b5c646b57072572ea66342 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 14:06:45 -0500 Subject: [PATCH 106/214] 3.0.5847 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index f92aeb944..76c8b56b2 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5846")] +[assembly: AssemblyVersion("3.0.5847")] From e08ab66dd61860bc13d3a5149afe0d7fbbddd93e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 14:13:45 -0500 Subject: [PATCH 107/214] 3.0.5818 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 76cc4acd2..26718c700 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5817")] +[assembly: AssemblyVersion("3.0.5818")] From 5710ef6892ef352195f772c40adc2189973f1af1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 23:21:31 -0500 Subject: [PATCH 108/214] improve reaction to image stub failures Conflicts: MediaBrowser.Server.Implementations/Library/LibraryManager.cs --- .../Manager/ItemImageProvider.cs | 35 ++++++++-------- .../Library/LibraryManager.cs | 40 ++++++++++++++----- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index f99aa967f..370187801 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -480,22 +480,21 @@ namespace MediaBrowser.Providers.Manager ImageType type, CancellationToken cancellationToken) { - foreach (var image in images.Where(i => i.Type == type)) + var eligibleImages = images + .Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth)) + .ToList(); + + if (EnableImageStub(item, type) && eligibleImages.Count > 0) { - if (image.Width.HasValue && image.Width.Value < minWidth) - { - continue; - } + SaveImageStub(item, type, eligibleImages.Select(i => i.Url)); + result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; + return true; + } + foreach (var image in eligibleImages) + { var url = image.Url; - if (EnableImageStub(item, type)) - { - SaveImageStub(item, type, url); - result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; - return true; - } - try { var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); @@ -557,18 +556,20 @@ namespace MediaBrowser.Providers.Manager } } - private void SaveImageStub(IHasImages item, ImageType imageType, string url) + private void SaveImageStub(IHasImages item, ImageType imageType, IEnumerable urls) { var newIndex = item.AllowsMultipleImages(imageType) ? item.GetImages(imageType).Count() : 0; - SaveImageStub(item, imageType, url, newIndex); + SaveImageStub(item, imageType, urls, newIndex); } - private void SaveImageStub(IHasImages item, ImageType imageType, string url, int newIndex) + private void SaveImageStub(IHasImages item, ImageType imageType, IEnumerable urls, int newIndex) { + var path = string.Join("|", urls.Take(1).ToArray()); + item.SetImage(new ItemImageInfo { - Path = url, + Path = path, Type = imageType }, newIndex); @@ -592,7 +593,7 @@ namespace MediaBrowser.Providers.Manager if (EnableImageStub(item, imageType)) { - SaveImageStub(item, imageType, url); + SaveImageStub(item, imageType, new[] { url }); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; continue; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f27f35c48..d0e72ac63 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2387,20 +2387,40 @@ namespace MediaBrowser.Server.Implementations.Library private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim(1,1); public async Task ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex) { - _logger.Debug("ConvertImageToLocal item {0}", item.Id); - - await _providerManagerFactory().SaveImage(item, image.Path, _dynamicImageResourcePool, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); - - var newImage = item.GetImageInfo(image.Type, imageIndex); - - if (newImage != null) + foreach (var url in image.Path.Split('|')) { - newImage.IsPlaceholder = image.IsPlaceholder; + try + { + _logger.Debug("ConvertImageToLocal item {0} - image url: {1}", item.Id, url); + + await _providerManagerFactory().SaveImage(item, url, _dynamicImageResourcePool, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); + + var newImage = item.GetImageInfo(image.Type, imageIndex); + + if (newImage != null) + { + newImage.IsPlaceholder = image.IsPlaceholder; + } + + await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); + + return item.GetImageInfo(image.Type, imageIndex); + } + catch (HttpException ex) + { + if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) + { + continue; + } + throw; + } } + // Remove this image to prevent it from retrying over and over + item.RemoveImage(image); await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); - - return item.GetImageInfo(image.Type, imageIndex); + + throw new InvalidOperationException(); } } } From cbeb9ca7622b0e9092299ddba77fb8d9ff71e213 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 17:00:44 -0500 Subject: [PATCH 109/214] update ffmpeg for osx --- .../FFMpeg/FFMpegDownloadInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 0314fcc7e..b055c250b 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg switch (environment.SystemArchitecture) { case Architecture.X86_X64: - info.Version = "20150917"; + info.Version = "20160124"; break; case Architecture.X86: info.Version = "20150110"; @@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.0.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.5.7z" }; case Architecture.X86: return new[] From 9b422977fe7d87a39e3dd6a4ce240a6199465c0a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 17:09:54 -0500 Subject: [PATCH 110/214] 3.0.5848 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 76c8b56b2..6b4b25470 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5847")] +[assembly: AssemblyVersion("3.0.5848")] From 80a6360f77595043e0c1db11018ebde6bc512139 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 17:11:46 -0500 Subject: [PATCH 111/214] fix merge error --- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d0e72ac63..0cb5174c9 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -32,10 +32,12 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Net; using MoreLinq; using SortOrder = MediaBrowser.Model.Entities.SortOrder; From b74d091833935779f76083c4098338858fd54602 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 23:12:47 -0500 Subject: [PATCH 112/214] fix pt-br from tvdb --- MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs | 4 +--- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index d03920742..392033048 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -169,10 +169,8 @@ namespace MediaBrowser.Providers.TV /// /// Gets the episode XML files. /// - /// The season number. - /// The episode number. - /// The ending episode number. /// The series data path. + /// The search information. /// List{FileInfo}. internal List GetEpisodeXmlNodes(string seriesDataPath, EpisodeInfo searchInfo) { diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 00bc032ca..313ca9074 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -58,6 +58,17 @@ namespace MediaBrowser.Providers.TV private const string SeriesGetZip = "http://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip"; private const string GetSeriesByImdbId = "http://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}"; + private string NormalizeLanguage(string language) + { + if (string.IsNullOrWhiteSpace(language)) + { + return language; + } + + // pt-br is just pt to tvdb + return language.Split('-')[0].ToLower(); + } + public async Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { if (IsValidSeries(searchInfo.ProviderIds)) @@ -270,7 +281,7 @@ namespace MediaBrowser.Providers.TV private async Task GetSeriesByRemoteId(string id, string idType, string language, CancellationToken cancellationToken) { - var url = string.Format(GetSeriesByImdbId, id, language); + var url = string.Format(GetSeriesByImdbId, id, NormalizeLanguage(language)); using (var result = await _httpClient.Get(new HttpRequestOptions { @@ -455,7 +466,7 @@ namespace MediaBrowser.Providers.TV private async Task> FindSeriesInternal(string name, string language, CancellationToken cancellationToken) { - var url = string.Format(SeriesSearchUrl, WebUtility.UrlEncode(name), language.ToLower()); + var url = string.Format(SeriesSearchUrl, WebUtility.UrlEncode(name), NormalizeLanguage(language)); var doc = new XmlDocument(); using (var results = await _httpClient.Get(new HttpRequestOptions From 53a1fbeb61b3641100ea93023ca3adb443d9a044 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 17:00:44 -0500 Subject: [PATCH 113/214] update ffmpeg for osx --- .../FFMpeg/FFMpegDownloadInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 0314fcc7e..b055c250b 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg switch (environment.SystemArchitecture) { case Architecture.X86_X64: - info.Version = "20150917"; + info.Version = "20160124"; break; case Architecture.X86: info.Version = "20150110"; @@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.0.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.5.7z" }; case Architecture.X86: return new[] From 51c70ab84005932f594c49f4db4563f4fb2e951b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 23:12:47 -0500 Subject: [PATCH 114/214] fix pt-br from tvdb --- MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs | 4 +--- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index d03920742..392033048 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -169,10 +169,8 @@ namespace MediaBrowser.Providers.TV /// /// Gets the episode XML files. /// - /// The season number. - /// The episode number. - /// The ending episode number. /// The series data path. + /// The search information. /// List{FileInfo}. internal List GetEpisodeXmlNodes(string seriesDataPath, EpisodeInfo searchInfo) { diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 00bc032ca..313ca9074 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -58,6 +58,17 @@ namespace MediaBrowser.Providers.TV private const string SeriesGetZip = "http://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip"; private const string GetSeriesByImdbId = "http://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}"; + private string NormalizeLanguage(string language) + { + if (string.IsNullOrWhiteSpace(language)) + { + return language; + } + + // pt-br is just pt to tvdb + return language.Split('-')[0].ToLower(); + } + public async Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { if (IsValidSeries(searchInfo.ProviderIds)) @@ -270,7 +281,7 @@ namespace MediaBrowser.Providers.TV private async Task GetSeriesByRemoteId(string id, string idType, string language, CancellationToken cancellationToken) { - var url = string.Format(GetSeriesByImdbId, id, language); + var url = string.Format(GetSeriesByImdbId, id, NormalizeLanguage(language)); using (var result = await _httpClient.Get(new HttpRequestOptions { @@ -455,7 +466,7 @@ namespace MediaBrowser.Providers.TV private async Task> FindSeriesInternal(string name, string language, CancellationToken cancellationToken) { - var url = string.Format(SeriesSearchUrl, WebUtility.UrlEncode(name), language.ToLower()); + var url = string.Format(SeriesSearchUrl, WebUtility.UrlEncode(name), NormalizeLanguage(language)); var doc = new XmlDocument(); using (var results = await _httpClient.Get(new HttpRequestOptions From d317bedd851b04bc427a6c7c396a09c48ea7a069 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Jan 2016 23:21:31 -0500 Subject: [PATCH 115/214] improve reaction to image stub failures Conflicts: MediaBrowser.Server.Implementations/Library/LibraryManager.cs --- .../Manager/ItemImageProvider.cs | 35 ++++++++-------- .../Library/LibraryManager.cs | 40 ++++++++++++++----- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index f99aa967f..370187801 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -480,22 +480,21 @@ namespace MediaBrowser.Providers.Manager ImageType type, CancellationToken cancellationToken) { - foreach (var image in images.Where(i => i.Type == type)) + var eligibleImages = images + .Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth)) + .ToList(); + + if (EnableImageStub(item, type) && eligibleImages.Count > 0) { - if (image.Width.HasValue && image.Width.Value < minWidth) - { - continue; - } + SaveImageStub(item, type, eligibleImages.Select(i => i.Url)); + result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; + return true; + } + foreach (var image in eligibleImages) + { var url = image.Url; - if (EnableImageStub(item, type)) - { - SaveImageStub(item, type, url); - result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; - return true; - } - try { var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); @@ -557,18 +556,20 @@ namespace MediaBrowser.Providers.Manager } } - private void SaveImageStub(IHasImages item, ImageType imageType, string url) + private void SaveImageStub(IHasImages item, ImageType imageType, IEnumerable urls) { var newIndex = item.AllowsMultipleImages(imageType) ? item.GetImages(imageType).Count() : 0; - SaveImageStub(item, imageType, url, newIndex); + SaveImageStub(item, imageType, urls, newIndex); } - private void SaveImageStub(IHasImages item, ImageType imageType, string url, int newIndex) + private void SaveImageStub(IHasImages item, ImageType imageType, IEnumerable urls, int newIndex) { + var path = string.Join("|", urls.Take(1).ToArray()); + item.SetImage(new ItemImageInfo { - Path = url, + Path = path, Type = imageType }, newIndex); @@ -592,7 +593,7 @@ namespace MediaBrowser.Providers.Manager if (EnableImageStub(item, imageType)) { - SaveImageStub(item, imageType, url); + SaveImageStub(item, imageType, new[] { url }); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; continue; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f27f35c48..d0e72ac63 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2387,20 +2387,40 @@ namespace MediaBrowser.Server.Implementations.Library private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim(1,1); public async Task ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex) { - _logger.Debug("ConvertImageToLocal item {0}", item.Id); - - await _providerManagerFactory().SaveImage(item, image.Path, _dynamicImageResourcePool, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); - - var newImage = item.GetImageInfo(image.Type, imageIndex); - - if (newImage != null) + foreach (var url in image.Path.Split('|')) { - newImage.IsPlaceholder = image.IsPlaceholder; + try + { + _logger.Debug("ConvertImageToLocal item {0} - image url: {1}", item.Id, url); + + await _providerManagerFactory().SaveImage(item, url, _dynamicImageResourcePool, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); + + var newImage = item.GetImageInfo(image.Type, imageIndex); + + if (newImage != null) + { + newImage.IsPlaceholder = image.IsPlaceholder; + } + + await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); + + return item.GetImageInfo(image.Type, imageIndex); + } + catch (HttpException ex) + { + if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) + { + continue; + } + throw; + } } + // Remove this image to prevent it from retrying over and over + item.RemoveImage(image); await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); - - return item.GetImageInfo(image.Type, imageIndex); + + throw new InvalidOperationException(); } } } From 50e983e3a1784f35eb72c340613f639ba7eae9d7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 24 Jan 2016 17:11:46 -0500 Subject: [PATCH 116/214] fix merge error --- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d0e72ac63..0cb5174c9 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -32,10 +32,12 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Net; using MoreLinq; using SortOrder = MediaBrowser.Model.Entities.SortOrder; From db8d8ff2892935e4085b1fa31888a1a50f2463b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 00:52:40 -0500 Subject: [PATCH 117/214] 3.0.5849 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 6b4b25470..91e41c34b 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5848")] +[assembly: AssemblyVersion("3.0.5849")] From 1f9023a8d7bebe10029cab2c73d1ed21f4ad6f47 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 11:38:52 -0500 Subject: [PATCH 118/214] update wdtv live profile --- MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs | 10 +++++----- MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs index 5bfd37726..98e780a25 100644 --- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs +++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Dlna.Profiles Container = "avi", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", - AudioCodec = "ac3,dca,mp2,mp3,pcm" + AudioCodec = "ac3,dca,mp2,mp3,pcm,dca" }, new DirectPlayProfile @@ -66,7 +66,7 @@ namespace MediaBrowser.Dlna.Profiles Container = "mpeg", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video", - AudioCodec = "ac3,dca,mp2,mp3,pcm" + AudioCodec = "ac3,dca,mp2,mp3,pcm,dca" }, new DirectPlayProfile @@ -74,7 +74,7 @@ namespace MediaBrowser.Dlna.Profiles Container = "mkv", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", - AudioCodec = "ac3,dca,aac,mp2,mp3,pcm" + AudioCodec = "ac3,dca,aac,mp2,mp3,pcm,dca" }, new DirectPlayProfile @@ -82,7 +82,7 @@ namespace MediaBrowser.Dlna.Profiles Container = "ts", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,h264,vc1", - AudioCodec = "ac3,dca,mp2,mp3,aac" + AudioCodec = "ac3,dca,mp2,mp3,aac,dca" }, new DirectPlayProfile @@ -90,7 +90,7 @@ namespace MediaBrowser.Dlna.Profiles Container = "mp4,mov", Type = DlnaProfileType.Video, VideoCodec = "h264,mpeg4", - AudioCodec = "ac3,aac,mp2,mp3" + AudioCodec = "ac3,aac,mp2,mp3,dca" }, new DirectPlayProfile diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index 10b642bba..e17fc087b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -37,11 +37,11 @@ true - - - - - + + + + + From 4d04acb3215e041bf0bb5d353fd84b37bd0bf8d5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:18:06 -0500 Subject: [PATCH 119/214] update naming project --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index b51c688b4..7761125d0 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -48,9 +48,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\MediaBrowser.Naming.1.0.0.42\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.43\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll From 80ea0f06f3f61c0f28c10cf062bcc48e6ef95a93 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:18:21 -0500 Subject: [PATCH 120/214] rework device concurrency --- .../Devices/DeviceRepository.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs index 43b1e693c..9e4a45253 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.Devices private readonly ILogger _logger; private readonly IFileSystem _fileSystem; - private ConcurrentBag _devices; + private List _devices; public DeviceRepository(IApplicationPaths appPaths, IJsonSerializer json, ILogger logger, IFileSystem fileSystem) { @@ -93,17 +93,14 @@ namespace MediaBrowser.Server.Implementations.Devices public IEnumerable GetDevices() { - if (_devices == null) + lock (_syncLock) { - lock (_syncLock) + if (_devices == null) { - if (_devices == null) - { - _devices = new ConcurrentBag(LoadDevices()); - } + _devices = LoadDevices().ToList(); } + return _devices.ToList(); } - return _devices.ToList(); } private IEnumerable LoadDevices() From 6693c47bf65e8801de2ffc8f3948fdbbe6ff19c9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:18:35 -0500 Subject: [PATCH 121/214] update naming project --- MediaBrowser.Server.Implementations/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 4b643fe21..8d7e77df0 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -2,7 +2,7 @@ - + From fcd12c831478f0ca9715b786c999b60681b7e5dd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:18:54 -0500 Subject: [PATCH 122/214] add recording logging --- .../LiveTv/EmbyTV/EmbyTV.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 3d1d9e0ba..dff57adf3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -22,6 +22,7 @@ using MediaBrowser.Server.Implementations.FileOrganization; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -604,6 +605,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { await RecordStream(timer, recordingEndDate, cancellationTokenSource.Token).ConfigureAwait(false); } + else + { + _logger.Info("Skipping RecordStream because it's already in progress."); + } } catch (OperationCanceledException) { @@ -722,7 +727,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.AddOrUpdate(recording); - _logger.Info("Beginning recording."); + _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)); httpRequestOptions.BufferContent = false; var durationToken = new CancellationTokenSource(duration); From fae18c57bc2177172ec6a4ffc24d4e1201e39a17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:26:04 -0500 Subject: [PATCH 123/214] merge from dev --- MediaBrowser.Api/StartupWizardService.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 399c81ae8..69639a5f9 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -66,8 +66,6 @@ namespace MediaBrowser.Api { _config.Configuration.IsStartupWizardCompleted = true; _config.Configuration.EnableLocalizedGuids = true; - _config.Configuration.MergeMetadataAndImagesByName = true; - _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableCustomPathSubFolders = true; _config.Configuration.DisableXmlSavers = true; From c81388689e03c40987b00dfd629150eb85494554 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 13:19:05 -0500 Subject: [PATCH 124/214] deprecate options Conflicts: MediaBrowser.Api/StartupWizardService.cs --- .../Configuration/ServerConfiguration.cs | 3 --- .../ServerConfigurationManager.cs | 27 ++----------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 7208ccb1d..3aea370c8 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -180,9 +180,6 @@ namespace MediaBrowser.Model.Configuration /// The dashboard source path. public string DashboardSourcePath { get; set; } - public bool MergeMetadataAndImagesByName { get; set; } - public bool EnableStandaloneMetadata { get; set; } - /// /// Gets or sets the image saving convention. /// diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index a7d3854e7..6b668da47 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -35,7 +35,6 @@ namespace MediaBrowser.Server.Implementations.Configuration public ServerConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem) : base(applicationPaths, logManager, xmlSerializer, fileSystem) { - UpdateItemsByNamePath(); UpdateMetadataPath(); } @@ -73,7 +72,6 @@ namespace MediaBrowser.Server.Implementations.Configuration /// protected override void OnConfigurationUpdated() { - UpdateItemsByNamePath(); UpdateMetadataPath(); base.OnConfigurationUpdated(); @@ -86,19 +84,6 @@ namespace MediaBrowser.Server.Implementations.Configuration UpdateTranscodingTempPath(); } - /// - /// Updates the items by name path. - /// - private void UpdateItemsByNamePath() - { - if (!Configuration.MergeMetadataAndImagesByName) - { - ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = string.IsNullOrEmpty(Configuration.ItemsByNamePath) ? - null : - Configuration.ItemsByNamePath; - } - } - /// /// Updates the metadata path. /// @@ -121,20 +106,12 @@ namespace MediaBrowser.Server.Implementations.Configuration ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = metadataPath; - if (Configuration.MergeMetadataAndImagesByName) - { - ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath; - } + ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath; } private string GetInternalMetadataPath() { - if (Configuration.EnableStandaloneMetadata) - { - return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); - } - - return null; + return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); } /// From c0d26560db1778b4f9fd26a784a1b8804ce2e501 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 14:06:02 -0500 Subject: [PATCH 125/214] fix pt-br with tvdb --- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 313ca9074..4a7ae57fb 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -238,7 +238,7 @@ namespace MediaBrowser.Providers.TV throw new ArgumentNullException("seriesId"); } - var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); + var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, NormalizeLanguage(preferredMetadataLanguage)); using (var zipStream = await _httpClient.Get(new HttpRequestOptions { @@ -268,7 +268,7 @@ namespace MediaBrowser.Providers.TV await SanitizeXmlFile(file).ConfigureAwait(false); } - var downloadLangaugeXmlFile = Path.Combine(seriesDataPath, preferredMetadataLanguage + ".xml"); + var downloadLangaugeXmlFile = Path.Combine(seriesDataPath, NormalizeLanguage(preferredMetadataLanguage) + ".xml"); var saveAsLanguageXmlFile = Path.Combine(seriesDataPath, saveAsMetadataLanguage + ".xml"); if (!string.Equals(downloadLangaugeXmlFile, saveAsLanguageXmlFile, StringComparison.OrdinalIgnoreCase)) From 42a629078d95c1278177af75292fbaf88e6471f1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 01:06:02 -0500 Subject: [PATCH 126/214] remove xml savers --- MediaBrowser.Api/StartupWizardService.cs | 1 - .../MediaBrowser.LocalMetadata.csproj | 3 - .../Savers/EpisodeXmlSaver.cs | 166 ------------------ .../Savers/MovieXmlSaver.cs | 147 ---------------- .../Savers/SeriesXmlSaver.cs | 154 ---------------- .../Configuration/ServerConfiguration.cs | 1 - 6 files changed, 472 deletions(-) delete mode 100644 MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs delete mode 100644 MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs delete mode 100644 MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 69639a5f9..554d63ac1 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -68,7 +68,6 @@ namespace MediaBrowser.Api _config.Configuration.EnableLocalizedGuids = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableCustomPathSubFolders = true; - _config.Configuration.DisableXmlSavers = true; _config.Configuration.DisableStartupScan = true; _config.Configuration.EnableUserViews = true; _config.Configuration.EnableDateLastRefresh = true; diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 9a641776a..c673c01df 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -79,14 +79,11 @@ - - - diff --git a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs deleted file mode 100644 index dc8a16cd8..000000000 --- a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs +++ /dev/null @@ -1,166 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - public class EpisodeXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IItemRepository _itemRepository; - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public EpisodeXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _itemRepository = itemRepository; - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - return item is Episode && updateType >= ItemUpdateType.MetadataDownload; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var episode = (Episode)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - if (!string.IsNullOrEmpty(item.Name)) - { - builder.Append("" + SecurityElement.Escape(episode.Name) + ""); - } - - if (episode.IndexNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.IndexNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.IndexNumberEnd.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + ""); - } - - if (episode.AirsAfterSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + ""); - } - if (episode.AirsBeforeEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - if (episode.AirsBeforeSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.ParentIndexNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.ParentIndexNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.AbsoluteEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AbsoluteEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.DvdEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.DvdSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.PremiereDate.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); - } - - XmlSaverHelpers.AddCommonNodes(episode, _libraryManager, builder); - XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - "FirstAired", - "SeasonNumber", - "EpisodeNumber", - "EpisodeName", - "EpisodeNumberEnd", - "airsafter_season", - "airsbefore_episode", - "airsbefore_season", - "DVD_episodenumber", - "DVD_season", - "absolute_number" - - }, _config, _fileSystem); - } - - /// - /// Gets the save path. - /// - /// The item. - /// System.String. - public string GetSavePath(IHasMetadata item) - { - var filename = Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"); - - return Path.Combine(Path.GetDirectoryName(item.Path), "metadata", filename); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs deleted file mode 100644 index 2e3e7aaa1..000000000 --- a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs +++ /dev/null @@ -1,147 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using System.Collections.Generic; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - /// - /// Saves movie.xml for movies, trailers and music videos - /// - public class MovieXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IItemRepository _itemRepository; - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public MovieXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _itemRepository = itemRepository; - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - var video = item as Video; - - // Check parent for null to avoid running this against things like video backdrops - if (video != null && !(item is Episode) && !video.IsOwnedItem) - { - return updateType >= ItemUpdateType.MetadataDownload; - } - - return false; - } - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var video = (Video)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - XmlSaverHelpers.AddCommonNodes(video, _libraryManager, builder); - - var musicVideo = item as MusicVideo; - - if (musicVideo != null) - { - if (musicVideo.Artists.Count > 0) - { - builder.Append("<Artist>" + SecurityElement.Escape(string.Join(";", musicVideo.Artists.ToArray())) + "</Artist>"); - } - if (!string.IsNullOrEmpty(musicVideo.Album)) - { - builder.Append("<Album>" + SecurityElement.Escape(musicVideo.Album) + "</Album>"); - } - } - - var movie = item as Movie; - - if (movie != null) - { - if (!string.IsNullOrEmpty(movie.TmdbCollectionName)) - { - builder.Append("<TmdbCollectionName>" + SecurityElement.Escape(movie.TmdbCollectionName) + "</TmdbCollectionName>"); - } - } - - XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - // Deprecated. No longer saving in this field. - "IMDBrating", - - // Deprecated. No longer saving in this field. - "Description", - - "Artist", - "Album", - "TmdbCollectionName" - }, _config, _fileSystem); - } - - public string GetSavePath(IHasMetadata item) - { - return GetMovieSavePath((Video)item); - } - - public static string GetMovieSavePath(Video item) - { - if (item.IsInMixedFolder) - { - return Path.ChangeExtension(item.Path, ".xml"); - } - - return Path.Combine(item.ContainingFolderPath, "movie.xml"); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs deleted file mode 100644 index 9806c4216..000000000 --- a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs +++ /dev/null @@ -1,154 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Entities; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - public class SeriesXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public SeriesXmlProvider(IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - return item is Series && updateType >= ItemUpdateType.MetadataDownload; - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var series = (Series)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - var tvdb = item.GetProviderId(MetadataProviders.Tvdb); - - if (!string.IsNullOrEmpty(tvdb)) - { - builder.Append("" + SecurityElement.Escape(tvdb) + ""); - } - - if (series.Status.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.Status.Value.ToString()) + ""); - } - - if (series.Studios.Count > 0) - { - builder.Append("" + SecurityElement.Escape(series.Studios[0]) + ""); - } - - if (!string.IsNullOrEmpty(series.AirTime)) - { - builder.Append("" + SecurityElement.Escape(series.AirTime) + ""); - } - - if (series.AirDays != null) - { - if (series.AirDays.Count == 7) - { - builder.Append("" + SecurityElement.Escape("Daily") + ""); - } - else if (series.AirDays.Count > 0) - { - builder.Append("" + SecurityElement.Escape(series.AirDays[0].ToString()) + ""); - } - } - - if (series.PremiereDate.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); - } - - if (series.AnimeSeriesIndex.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.AnimeSeriesIndex.Value.ToString(UsCulture)) + ""); - } - - XmlSaverHelpers.AddCommonNodes(series, _libraryManager, builder); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - "id", - "Status", - "Network", - "Airs_Time", - "Airs_DayOfWeek", - "FirstAired", - - // Don't preserve old series node - "Series", - - "SeriesName", - - // Deprecated. No longer saving in this field. - "AnimeSeriesIndex" - }, _config, _fileSystem); - } - - /// - /// Gets the save path. - /// - /// The item. - /// System.String. - public string GetSavePath(IHasMetadata item) - { - return Path.Combine(item.Path, "series.xml"); - } - } -} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 3aea370c8..77bce5cbd 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -216,7 +216,6 @@ namespace MediaBrowser.Model.Configuration public int SharingExpirationDays { get; set; } - public bool DisableXmlSavers { get; set; } public bool EnableWindowsShortcuts { get; set; } public bool EnableVideoFrameByFrameAnalysis { get; set; } From 1ea2ec9bdc8fe7cca63b79b69434217627167963 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Jan 2016 14:55:33 -0500 Subject: [PATCH 127/214] support itunes episode naming --- .../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 7761125d0..c54ea42a5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -48,9 +48,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\MediaBrowser.Naming.1.0.0.43\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.44\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 8d7e77df0..b7f5533ce 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -2,7 +2,7 @@ - + From 9a83394e5d09c8685841f2fe951f5d1b8d5e43b1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 01:06:45 -0500 Subject: [PATCH 128/214] disable wake timer --- .../Native/WindowsPowerManagement.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs index 3b05febaf..abfbab50c 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs @@ -35,8 +35,8 @@ namespace MediaBrowser.ServerApplication.Native public void ScheduleWake(DateTime utcTime) { - Initialize(); - _bgWorker.RunWorkerAsync(utcTime.ToFileTime()); + //Initialize(); + //_bgWorker.RunWorkerAsync(utcTime.ToFileTime()); } private void Initialize() From 51cd5e90b0a926ea728f9b98e5b9f380948b5cce Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 01:07:01 -0500 Subject: [PATCH 129/214] restart timers on wake --- .../LiveTv/EmbyTV/EmbyTV.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index dff57adf3..c27f60712 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -30,6 +30,7 @@ using System.Threading.Tasks; using CommonIO; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Power; +using Microsoft.Win32; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -84,6 +85,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public void Start() { _timerProvider.RestartTimers(); + + SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + + } + + void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) + { + if (e.Mode == PowerModes.Resume) + { + _timerProvider.RestartTimers(); + } } public event EventHandler DataSourceChanged; From c48a4cfb992d486cf55f8d687b6ff0559ae38783 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 01:06:02 -0500 Subject: [PATCH 130/214] remove xml savers --- MediaBrowser.Api/StartupWizardService.cs | 1 - .../MediaBrowser.LocalMetadata.csproj | 3 - .../Savers/EpisodeXmlSaver.cs | 166 ------------------ .../Savers/MovieXmlSaver.cs | 147 ---------------- .../Savers/SeriesXmlSaver.cs | 154 ---------------- .../Configuration/ServerConfiguration.cs | 1 - 6 files changed, 472 deletions(-) delete mode 100644 MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs delete mode 100644 MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs delete mode 100644 MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 399c81ae8..afe3da710 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -70,7 +70,6 @@ namespace MediaBrowser.Api _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableCustomPathSubFolders = true; - _config.Configuration.DisableXmlSavers = true; _config.Configuration.DisableStartupScan = true; _config.Configuration.EnableUserViews = true; _config.Configuration.EnableDateLastRefresh = true; diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 9a641776a..c673c01df 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -79,14 +79,11 @@ - - - diff --git a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs deleted file mode 100644 index dc8a16cd8..000000000 --- a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs +++ /dev/null @@ -1,166 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - public class EpisodeXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IItemRepository _itemRepository; - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public EpisodeXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _itemRepository = itemRepository; - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - return item is Episode && updateType >= ItemUpdateType.MetadataDownload; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var episode = (Episode)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - if (!string.IsNullOrEmpty(item.Name)) - { - builder.Append("" + SecurityElement.Escape(episode.Name) + ""); - } - - if (episode.IndexNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.IndexNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.IndexNumberEnd.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + ""); - } - - if (episode.AirsAfterSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + ""); - } - if (episode.AirsBeforeEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - if (episode.AirsBeforeSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.ParentIndexNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.ParentIndexNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.AbsoluteEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.AbsoluteEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.DvdEpisodeNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.DvdSeasonNumber.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + ""); - } - - if (episode.PremiereDate.HasValue) - { - builder.Append("" + SecurityElement.Escape(episode.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); - } - - XmlSaverHelpers.AddCommonNodes(episode, _libraryManager, builder); - XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - "FirstAired", - "SeasonNumber", - "EpisodeNumber", - "EpisodeName", - "EpisodeNumberEnd", - "airsafter_season", - "airsbefore_episode", - "airsbefore_season", - "DVD_episodenumber", - "DVD_season", - "absolute_number" - - }, _config, _fileSystem); - } - - /// - /// Gets the save path. - /// - /// The item. - /// System.String. - public string GetSavePath(IHasMetadata item) - { - var filename = Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"); - - return Path.Combine(Path.GetDirectoryName(item.Path), "metadata", filename); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs deleted file mode 100644 index 2e3e7aaa1..000000000 --- a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs +++ /dev/null @@ -1,147 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using System.Collections.Generic; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - /// - /// Saves movie.xml for movies, trailers and music videos - /// - public class MovieXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IItemRepository _itemRepository; - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public MovieXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _itemRepository = itemRepository; - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - var video = item as Video; - - // Check parent for null to avoid running this against things like video backdrops - if (video != null && !(item is Episode) && !video.IsOwnedItem) - { - return updateType >= ItemUpdateType.MetadataDownload; - } - - return false; - } - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var video = (Video)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - XmlSaverHelpers.AddCommonNodes(video, _libraryManager, builder); - - var musicVideo = item as MusicVideo; - - if (musicVideo != null) - { - if (musicVideo.Artists.Count > 0) - { - builder.Append("<Artist>" + SecurityElement.Escape(string.Join(";", musicVideo.Artists.ToArray())) + "</Artist>"); - } - if (!string.IsNullOrEmpty(musicVideo.Album)) - { - builder.Append("<Album>" + SecurityElement.Escape(musicVideo.Album) + "</Album>"); - } - } - - var movie = item as Movie; - - if (movie != null) - { - if (!string.IsNullOrEmpty(movie.TmdbCollectionName)) - { - builder.Append("<TmdbCollectionName>" + SecurityElement.Escape(movie.TmdbCollectionName) + "</TmdbCollectionName>"); - } - } - - XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - // Deprecated. No longer saving in this field. - "IMDBrating", - - // Deprecated. No longer saving in this field. - "Description", - - "Artist", - "Album", - "TmdbCollectionName" - }, _config, _fileSystem); - } - - public string GetSavePath(IHasMetadata item) - { - return GetMovieSavePath((Video)item); - } - - public static string GetMovieSavePath(Video item) - { - if (item.IsInMixedFolder) - { - return Path.ChangeExtension(item.Path, ".xml"); - } - - return Path.Combine(item.ContainingFolderPath, "movie.xml"); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs deleted file mode 100644 index 9806c4216..000000000 --- a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs +++ /dev/null @@ -1,154 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Entities; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security; -using System.Text; -using System.Threading; -using CommonIO; -using MediaBrowser.Common.IO; - -namespace MediaBrowser.LocalMetadata.Savers -{ - public class SeriesXmlProvider : IMetadataFileSaver, IConfigurableProvider - { - private readonly IServerConfigurationManager _config; - private readonly ILibraryManager _libraryManager; - private IFileSystem _fileSystem; - - public SeriesXmlProvider(IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem) - { - _config = config; - _libraryManager = libraryManager; - _fileSystem = fileSystem; - } - - public string Name - { - get - { - return XmlProviderUtils.Name; - } - } - - /// - /// Determines whether [is enabled for] [the specified item]. - /// - /// The item. - /// Type of the update. - /// true if [is enabled for] [the specified item]; otherwise, false. - public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) - { - if (!item.SupportsLocalMetadata) - { - return false; - } - - return item is Series && updateType >= ItemUpdateType.MetadataDownload; - } - - public bool IsEnabled - { - get { return !_config.Configuration.DisableXmlSavers; } - } - - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// Saves the specified item. - /// - /// The item. - /// The cancellation token. - /// Task. - public void Save(IHasMetadata item, CancellationToken cancellationToken) - { - var series = (Series)item; - - var builder = new StringBuilder(); - - builder.Append(""); - - var tvdb = item.GetProviderId(MetadataProviders.Tvdb); - - if (!string.IsNullOrEmpty(tvdb)) - { - builder.Append("" + SecurityElement.Escape(tvdb) + ""); - } - - if (series.Status.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.Status.Value.ToString()) + ""); - } - - if (series.Studios.Count > 0) - { - builder.Append("" + SecurityElement.Escape(series.Studios[0]) + ""); - } - - if (!string.IsNullOrEmpty(series.AirTime)) - { - builder.Append("" + SecurityElement.Escape(series.AirTime) + ""); - } - - if (series.AirDays != null) - { - if (series.AirDays.Count == 7) - { - builder.Append("" + SecurityElement.Escape("Daily") + ""); - } - else if (series.AirDays.Count > 0) - { - builder.Append("" + SecurityElement.Escape(series.AirDays[0].ToString()) + ""); - } - } - - if (series.PremiereDate.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + ""); - } - - if (series.AnimeSeriesIndex.HasValue) - { - builder.Append("" + SecurityElement.Escape(series.AnimeSeriesIndex.Value.ToString(UsCulture)) + ""); - } - - XmlSaverHelpers.AddCommonNodes(series, _libraryManager, builder); - - builder.Append(""); - - var xmlFilePath = GetSavePath(item); - - XmlSaverHelpers.Save(builder, xmlFilePath, new List - { - "id", - "Status", - "Network", - "Airs_Time", - "Airs_DayOfWeek", - "FirstAired", - - // Don't preserve old series node - "Series", - - "SeriesName", - - // Deprecated. No longer saving in this field. - "AnimeSeriesIndex" - }, _config, _fileSystem); - } - - /// - /// Gets the save path. - /// - /// The item. - /// System.String. - public string GetSavePath(IHasMetadata item) - { - return Path.Combine(item.Path, "series.xml"); - } - } -} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 7208ccb1d..fb22637f9 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -219,7 +219,6 @@ namespace MediaBrowser.Model.Configuration public int SharingExpirationDays { get; set; } - public bool DisableXmlSavers { get; set; } public bool EnableWindowsShortcuts { get; set; } public bool EnableVideoFrameByFrameAnalysis { get; set; } From 106a2f3e1a0bfee9e056ef22b94599c7b2a47530 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 01:31:31 -0500 Subject: [PATCH 131/214] add back MergeMetadataAndImagesByName Conflicts: MediaBrowser.Model/Configuration/ServerConfiguration.cs --- MediaBrowser.Api/StartupWizardService.cs | 1 + .../Configuration/ServerConfiguration.cs | 2 ++ .../Configuration/ServerConfigurationManager.cs | 15 +++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 554d63ac1..b05a1bd20 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -71,6 +71,7 @@ namespace MediaBrowser.Api _config.Configuration.DisableStartupScan = true; _config.Configuration.EnableUserViews = true; _config.Configuration.EnableDateLastRefresh = true; + _config.Configuration.MergeMetadataAndImagesByName = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 77bce5cbd..91e20c3e0 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -180,6 +180,8 @@ namespace MediaBrowser.Model.Configuration /// The dashboard source path. public string DashboardSourcePath { get; set; } + public bool MergeMetadataAndImagesByName { get; set; } + /// /// Gets or sets the image saving convention. /// diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index 6b668da47..d7df37332 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -35,6 +35,7 @@ namespace MediaBrowser.Server.Implementations.Configuration public ServerConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem) : base(applicationPaths, logManager, xmlSerializer, fileSystem) { + UpdateItemsByNamePath(); UpdateMetadataPath(); } @@ -72,6 +73,7 @@ namespace MediaBrowser.Server.Implementations.Configuration /// protected override void OnConfigurationUpdated() { + UpdateItemsByNamePath(); UpdateMetadataPath(); base.OnConfigurationUpdated(); @@ -84,6 +86,19 @@ namespace MediaBrowser.Server.Implementations.Configuration UpdateTranscodingTempPath(); } + /// + /// Updates the items by name path. + /// + private void UpdateItemsByNamePath() + { + if (!Configuration.MergeMetadataAndImagesByName) + { + ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = string.IsNullOrEmpty(Configuration.ItemsByNamePath) ? + null : + Configuration.ItemsByNamePath; + } + } + /// /// Updates the metadata path. /// From 2b8cf9b89d9eeeff0affe9ca0c2501e3a0984ca4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 11:58:08 -0500 Subject: [PATCH 132/214] add logging --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c27f60712..250b5655f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -92,6 +92,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) { + _logger.Info("Power mode changed to {0}", e.Mode); + if (e.Mode == PowerModes.Resume) { _timerProvider.RestartTimers(); From c167f792383e9f2cff320efc840c42efe7fbbdbb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 12:34:23 -0500 Subject: [PATCH 133/214] update photo resolver to exclude generated images --- .../Library/Resolvers/PhotoResolver.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 407aac53d..8beb03b71 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -51,8 +51,17 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers { var filename = Path.GetFileNameWithoutExtension(path) ?? string.Empty; - return !IgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) - && imageProcessor.SupportedInputFormats.Contains((Path.GetExtension(path) ?? string.Empty).TrimStart('.'), StringComparer.OrdinalIgnoreCase); + if (IgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + if (IgnoreFiles.Any(i => filename.IndexOf("-" + i, StringComparison.OrdinalIgnoreCase) != -1)) + { + return false; + } + + return imageProcessor.SupportedInputFormats.Contains((Path.GetExtension(path) ?? string.Empty).TrimStart('.'), StringComparer.OrdinalIgnoreCase); } } From ddf7fdbcef9c987092a7591848801f28aa5baedd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 13:35:37 -0500 Subject: [PATCH 134/214] fixes #1421 - LogRequest() in WebSocketSharpListener broken for Reports --- .../HttpServer/HttpListenerHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 8d8d7f6f7..038116703 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -290,7 +290,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer var operationName = httpReq.OperationName; var localPath = url.LocalPath; - var urlString = url.ToString(); + var urlString = url.OriginalString; var enableLog = EnableLogging(urlString); if (enableLog) From 2bd0464322331b668be97a77a90ef486914d95ac Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 13:42:19 -0500 Subject: [PATCH 135/214] fixes #1410 - Entire server locks up, when files are locked during.. things.. --- .../Configuration/ServerConfiguration.cs | 4 ++-- .../IO/LibraryMonitor.cs | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 91e20c3e0..152bdd993 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -164,7 +164,7 @@ namespace MediaBrowser.Model.Configuration /// different directories and files. /// /// The file watcher delay. - public int RealtimeLibraryMonitorDelay { get; set; } + public int LibraryMonitorDelay { get; set; } /// /// Gets or sets a value indicating whether [enable dashboard response caching]. @@ -255,7 +255,7 @@ namespace MediaBrowser.Model.Configuration MinResumeDurationSeconds = 300; EnableLibraryMonitor = AutoOnOff.Auto; - RealtimeLibraryMonitorDelay = 40; + LibraryMonitorDelay = 60; EnableInternetProviders = true; FindInternetTrailers = true; diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 85ea8ec57..184b72d8f 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -471,11 +471,11 @@ namespace MediaBrowser.Server.Implementations.IO { if (_updateTimer == null) { - _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeLibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); } else { - _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeLibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); } } } @@ -513,12 +513,18 @@ namespace MediaBrowser.Server.Implementations.IO private bool IsFileLocked(string path) { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + // Causing lockups on linux + return false; + } + try { var data = _fileSystem.GetFileSystemInfo(path); if (!data.Exists - || data.Attributes.HasFlag(FileAttributes.Directory) + || data.IsDirectory // Opening a writable stream will fail with readonly files || data.Attributes.HasFlag(FileAttributes.ReadOnly)) From f0adb2e89173ae0a9b041dfaa45edca119bc7f4a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 14:28:12 -0500 Subject: [PATCH 136/214] restore channel view setting --- MediaBrowser.Model/Configuration/UserConfiguration.cs | 1 + .../Library/UserViewManager.cs | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index ab3a861a3..819948909 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -48,6 +48,7 @@ namespace MediaBrowser.Model.Configuration public string[] PlainFolderViews { get; set; } public bool HidePlayedInLatest { get; set; } + public bool DisplayChannelsInline { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 30a720a62..0df4742bd 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -163,7 +163,14 @@ namespace MediaBrowser.Server.Implementations.Library var channels = channelResult.Items; - list.AddRange(channels); + if (user.Configuration.DisplayChannelsInline && channels.Length > 0) + { + list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false)); + } + else + { + list.AddRange(channels); + } if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId)) { From 9dd55c15c0dd62568e0410127f5d91c1d13d3b5e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 14:28:33 -0500 Subject: [PATCH 137/214] fix changing added value --- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 10 +++++++--- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index c5184ec3d..0fbf2fd11 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -215,7 +215,11 @@ namespace MediaBrowser.XbmcMetadata.Parsers if (!string.IsNullOrWhiteSpace(val)) { DateTime added; - if (DateTime.TryParse(val, out added)) + if (DateTime.TryParseExact(val, BaseNfoSaver.DateAddedFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out added)) + { + item.EndDate = added.ToUniversalTime(); + } + else if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out added)) { item.DateCreated = added.ToUniversalTime(); } @@ -976,11 +980,11 @@ namespace MediaBrowser.XbmcMetadata.Parsers if (!string.IsNullOrWhiteSpace(val) && !string.IsNullOrWhiteSpace(userDataUserId)) { DateTime parsedValue; - if (DateTime.TryParseExact(val, "yyyy-MM-dd HH:mm:ss", _usCulture, DateTimeStyles.None, out parsedValue)) + if (DateTime.TryParseExact(val, "yyyy-MM-dd HH:mm:ss", _usCulture, DateTimeStyles.AssumeLocal, out parsedValue)) { var userData = GetOrAdd(itemResult, userDataUserId); - userData.LastPlayedDate = parsedValue; + userData.LastPlayedDate = parsedValue.ToUniversalTime(); } } break; diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 0da53f575..c114f9dd9 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -416,6 +416,8 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteEndElement(); } + public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss"; + /// /// Adds the common nodes. /// @@ -472,7 +474,7 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteElementString("type", item.DisplayMediaType); } - writer.WriteElementString("dateadded", item.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")); + writer.WriteElementString("dateadded", item.DateCreated.ToLocalTime().ToString(DateAddedFormat)); writer.WriteElementString("title", item.Name ?? string.Empty); writer.WriteElementString("originaltitle", item.Name ?? string.Empty); @@ -949,7 +951,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (userdata.LastPlayedDate.HasValue) { - writer.WriteElementString("lastplayed", userdata.LastPlayedDate.Value.ToString("yyyy-MM-dd HH:mm:ss").ToLower()); + writer.WriteElementString("lastplayed", userdata.LastPlayedDate.Value.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss").ToLower()); } writer.WriteStartElement("resume"); From 8c7296b560af1f926115ac23bad519b8d6fc5d7f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Jan 2016 14:39:10 -0500 Subject: [PATCH 138/214] update translations --- .../Localization/Core/ca.json | 22 +++++++++---------- .../Localization/Core/nl.json | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 40dfcd2c3..83d72030f 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -1,6 +1,6 @@ { - "AppDeviceValues": "App: {0}, Device: {1}", - "UserDownloadingItemWithValues": "{0} is downloading {1}", + "AppDeviceValues": "App: {0}, Dispositiu: {1}", + "UserDownloadingItemWithValues": "{0} est\u00e0 descarregant {1}", "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Pel\u00b7l\u00edcules", "FolderTypeMusic": "M\u00fasica", @@ -12,10 +12,10 @@ "FolderTypeBooks": "Llibres", "FolderTypeTvShows": "TV", "FolderTypeInherit": "Heretat", - "HeaderCastCrew": "Repartiment i equip", + "HeaderCastCrew": "Repartiment i Equip", "HeaderPeople": "People", "ValueSpecialEpisodeName": "Special - {0}", - "LabelChapterName": "Chapter {0}", + "LabelChapterName": "Cap\u00edtol {0}", "NameSeasonNumber": "Temporada {0}", "LabelExit": "Sortir", "LabelVisitCommunity": "Visita la comunitat", @@ -77,7 +77,7 @@ "ViewTypeMovieMovies": "Pel\u00b7l\u00edcules", "ViewTypeMovieCollections": "Col\u00b7leccions", "ViewTypeMovieFavorites": "Preferides", - "ViewTypeMovieGenres": "Genres", + "ViewTypeMovieGenres": "G\u00e8neres", "ViewTypeMusicLatest": "Novetats", "ViewTypeMusicPlaylists": "Llistes de reproducci\u00f3", "ViewTypeMusicAlbums": "\u00c0lbums", @@ -89,7 +89,7 @@ "ViewTypeMusicFavoriteArtists": "Artistes Preferits", "ViewTypeMusicFavoriteSongs": "Can\u00e7ons Preferides", "ViewTypeFolders": "Directoris", - "ViewTypeLiveTvRecordingGroups": "Recordings", + "ViewTypeLiveTvRecordingGroups": "Enregistraments", "ViewTypeLiveTvChannels": "Canals", "ScheduledTaskFailedWithName": "{0} failed", "LabelRunningTimeValue": "Running time: {0}", @@ -103,7 +103,7 @@ "LabelIpAddressValue": "Ip address: {0}", "DeviceOnlineWithName": "{0} is connected", "UserOnlineFromDevice": "{0} is online from {1}", - "ProviderValue": "Provider: {0}", + "ProviderValue": "Prove\u00efdor: {0}", "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", "UserCreatedWithName": "User {0} has been created", @@ -113,12 +113,12 @@ "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", "MessageApplicationUpdated": "Emby Server has been updated", "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", - "AuthenticationSucceededWithUserName": "{0} successfully authenticated", + "AuthenticationSucceededWithUserName": "{0} autenticat correctament", "DeviceOfflineWithName": "{0} has disconnected", "UserLockedOutWithName": "User {0} has been locked out", "UserOfflineFromDevice": "{0} has disconnected from {1}", - "UserStartedPlayingItemWithValues": "{0} has started playing {1}", - "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", + "UserStartedPlayingItemWithValues": "{0} ha comen\u00e7at a reproduir {1}", + "UserStoppedPlayingItemWithValues": "{0} ha parat de reproduir {1}", "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", "HeaderUnidentified": "Unidentified", "HeaderImagePrimary": "Primary", @@ -164,7 +164,7 @@ "HeaderTracks": "Tracks", "HeaderMusicArtist": "M\u00fasic", "HeaderLocked": "Locked", - "HeaderStudios": "Studios", + "HeaderStudios": "Estudis", "HeaderActor": "Actors", "HeaderComposer": "Compositors", "HeaderDirector": "Directors", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/nl.json b/MediaBrowser.Server.Implementations/Localization/Core/nl.json index b32ebefc3..fd0c586a2 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/nl.json @@ -63,7 +63,7 @@ "ViewTypeLatestGames": "Nieuwste games", "ViewTypeRecentlyPlayedGames": "Recent gespeelt", "ViewTypeGameFavorites": "Favorieten", - "ViewTypeGameSystems": "Gam systemen", + "ViewTypeGameSystems": "Game systemen", "ViewTypeGameGenres": "Genres", "ViewTypeTvResume": "Hervatten", "ViewTypeTvNextUp": "Volgende", @@ -147,7 +147,7 @@ "HeaderCommunityRating": "Gemeenschap cijfer", "HeaderTrailers": "Trailers", "HeaderSpecials": "Specials", - "HeaderGameSystems": "Spel systemen", + "HeaderGameSystems": "Game systemen", "HeaderPlayers": "Spelers:", "HeaderAlbumArtists": "Album artiesten", "HeaderAlbums": "Albums", From 8a50392ba73605fcd5a22c299352845bae0b7700 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 01:38:35 -0500 Subject: [PATCH 139/214] reduce server pinging --- .../ApplicationHost.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 1db019d8d..2d625f810 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -210,7 +210,6 @@ namespace MediaBrowser.Server.Startup.Common private readonly string _releaseAssetFilename; internal INativeApp NativeApp { get; set; } - private Timer _ipAddressCacheTimer; /// /// Initializes a new instance of the class. @@ -234,8 +233,6 @@ namespace MediaBrowser.Server.Startup.Common NativeApp = nativeApp; SetBaseExceptionMessage(); - - _ipAddressCacheTimer = new Timer(OnCacheClearTimerFired, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3)); } private Version _version; @@ -534,7 +531,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(EncodingManager); RegisterSingleInstance(NativeApp.GetPowerManagement()); - + var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); @@ -972,10 +969,10 @@ namespace MediaBrowser.Server.Startup.Common { get { - if (!ServerConfigurationManager.Configuration.EnableAutoUpdate) - { - return false; - } + if (!ServerConfigurationManager.Configuration.EnableAutoUpdate) + { + return false; + } #if DEBUG return false; #endif @@ -1159,7 +1156,12 @@ namespace MediaBrowser.Server.Startup.Common } private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private DateTime _lastAddressCacheClear; private bool IsIpAddressValid(IPAddress address) + { + return IsIpAddressValidInternal(address).Result; + } + private async Task IsIpAddressValidInternal(IPAddress address) { if (IPAddress.IsLoopback(address)) { @@ -1169,6 +1171,12 @@ namespace MediaBrowser.Server.Startup.Common var apiUrl = GetLocalApiUrl(address.ToString()); apiUrl += "/system/ping"; + if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 5) + { + _lastAddressCacheClear = DateTime.UtcNow; + _validAddressResults.Clear(); + } + bool cachedResult; if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) { @@ -1177,14 +1185,15 @@ namespace MediaBrowser.Server.Startup.Common try { - using (var response = HttpClient.SendAsync(new HttpRequestOptions + using (var response = await HttpClient.SendAsync(new HttpRequestOptions { Url = apiUrl, LogErrorResponseBody = false, LogErrors = false, - LogRequest = false + LogRequest = false, + TimeoutMs = 30000 - }, "POST").Result) + }, "POST").ConfigureAwait(false)) { using (var reader = new StreamReader(response.Content)) { @@ -1192,25 +1201,20 @@ namespace MediaBrowser.Server.Startup.Common var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); - Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); + //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); return valid; } } } catch { - Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); + //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false); return false; } } - private void OnCacheClearTimerFired(object state) - { - _validAddressResults.Clear(); - } - public string FriendlyName { get From af599ed5d74c886d390ea7a79123f0443543d0c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 01:39:02 -0500 Subject: [PATCH 140/214] add logging --- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index 7002a3703..08c6b0ba4 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -370,6 +370,8 @@ namespace MediaBrowser.Api.UserLibrary public void Post(ReportPlaybackStopped request) { + Logger.Debug("ReportPlaybackStopped PlaySessionId: {0}", request.PlaySessionId ?? string.Empty); + if (!string.IsNullOrWhiteSpace(request.PlaySessionId)) { ApiEntryPoint.Instance.KillTranscodingJobs(AuthorizationContext.GetAuthorizationInfo(Request).DeviceId, request.PlaySessionId, s => true); From 2d97423a404228f742976dc6abe4a43746bc23fb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 13:29:41 -0500 Subject: [PATCH 141/214] don't organize episode if series has no provider ids --- .../FileOrganization/EpisodeFileOrganizer.cs | 211 +++++++++--------- 1 file changed, 110 insertions(+), 101 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 26392f5a9..ae40ed6b5 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -76,50 +76,50 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { var seasonNumber = episodeInfo.SeasonNumber; - result.ExtractedSeasonNumber = seasonNumber; + result.ExtractedSeasonNumber = seasonNumber; - // Passing in true will include a few extra regex's - var episodeNumber = episodeInfo.EpisodeNumber; + // Passing in true will include a few extra regex's + var episodeNumber = episodeInfo.EpisodeNumber; - result.ExtractedEpisodeNumber = episodeNumber; + result.ExtractedEpisodeNumber = episodeNumber; - var premiereDate = episodeInfo.IsByDate ? - new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : - (DateTime?)null; + var premiereDate = episodeInfo.IsByDate ? + new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : + (DateTime?)null; - if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) - { - if (episodeInfo.IsByDate) - { - _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); - } - else - { - _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); - } + if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) + { + if (episodeInfo.IsByDate) + { + _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); + } + else + { + _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); + } - var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; + var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; - result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; - await OrganizeEpisode(path, - seriesName, - seasonNumber, - episodeNumber, - endingEpisodeNumber, - premiereDate, - options, - overwriteExisting, - result, - cancellationToken).ConfigureAwait(false); - } - else - { - var msg = string.Format("Unable to determine episode number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } + await OrganizeEpisode(path, + seriesName, + seasonNumber, + episodeNumber, + endingEpisodeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken).ConfigureAwait(false); + } + else + { + var msg = string.Format("Unable to determine episode number from {0}", path); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + } } else { @@ -151,32 +151,32 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); - await OrganizeEpisode(result.OriginalPath, - series, - request.SeasonNumber, - request.EpisodeNumber, - request.EndingEpisodeNumber, - null, - options, - true, - result, - cancellationToken).ConfigureAwait(false); + await OrganizeEpisode(result.OriginalPath, + series, + request.SeasonNumber, + request.EpisodeNumber, + request.EndingEpisodeNumber, + null, + options, + true, + result, + cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return result; } - private Task OrganizeEpisode(string sourcePath, - string seriesName, - int? seasonNumber, - int? episodeNumber, - int? endingEpiosdeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - bool overwriteExisting, - FileOrganizationResult result, - CancellationToken cancellationToken) + private Task OrganizeEpisode(string sourcePath, + string seriesName, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { var series = GetMatchingSeries(seriesName, result); @@ -189,33 +189,42 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - return OrganizeEpisode(sourcePath, - series, - seasonNumber, - episodeNumber, - endingEpiosdeNumber, - premiereDate, - options, - overwriteExisting, - result, - cancellationToken); + if (!series.ProviderIds.Any()) + { + var msg = string.Format("Series has not yet been identified: {0}. If you just added the series, please run a library scan or use the identify feature to identify it.", seriesName); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + return Task.FromResult(true); + } + + return OrganizeEpisode(sourcePath, + series, + seasonNumber, + episodeNumber, + endingEpiosdeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken); } - private async Task OrganizeEpisode(string sourcePath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpiosdeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - bool overwriteExisting, - FileOrganizationResult result, - CancellationToken cancellationToken) + private async Task OrganizeEpisode(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -324,17 +333,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private List GetOtherDuplicatePaths(string targetPath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpisodeNumber) + private List GetOtherDuplicatePaths(string targetPath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber) { - // TODO: Support date-naming? - if (!seasonNumber.HasValue || episodeNumber.HasValue) - { - return new List (); - } + // TODO: Support date-naming? + if (!seasonNumber.HasValue || episodeNumber.HasValue) + { + return new List(); + } var episodePaths = series.GetRecursiveChildren() .OfType() @@ -464,14 +473,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The ending episode number. /// The options. /// System.String. - private async Task GetNewPath(string sourcePath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpisodeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - CancellationToken cancellationToken) + private async Task GetNewPath(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + CancellationToken cancellationToken) { var episodeInfo = new EpisodeInfo { @@ -481,7 +490,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization MetadataLanguage = series.GetPreferredMetadataLanguage(), ParentIndexNumber = seasonNumber, SeriesProviderIds = series.ProviderIds, - PremiereDate = premiereDate + PremiereDate = premiereDate }; var searchResults = await _providerManager.GetRemoteSearchResults(new RemoteSearchQuery @@ -491,7 +500,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }, cancellationToken).ConfigureAwait(false); var episode = searchResults.FirstOrDefault(); - + string episodeName = string.Empty; if (episode == null) @@ -503,10 +512,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization else { episodeName = episode.Name; - } + } - seasonNumber = seasonNumber ?? episode.ParentIndexNumber; - episodeNumber = episodeNumber ?? episode.IndexNumber; + seasonNumber = seasonNumber ?? episode.ParentIndexNumber; + episodeNumber = episodeNumber ?? episode.IndexNumber; var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); From 258b07a4164d9f3f3a2385f3f2a8cdaf5d857f63 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 13:38:40 -0500 Subject: [PATCH 142/214] handle empty person name --- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 0fbf2fd11..40b974ee7 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -631,7 +631,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers { var person = GetPersonFromXmlNode(subtree); - itemResult.AddPerson(person); + if (!string.IsNullOrWhiteSpace(person.Name)) + { + itemResult.AddPerson(person); + } } break; } From 9d6f1a8b6151c2bfcb43ca0b358bab087044de83 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 14:10:56 -0500 Subject: [PATCH 143/214] update recording logging --- .../LiveTv/EmbyTV/TimerManager.cs | 9 +++++++-- .../Native/WindowsPowerManagement.cs | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index ca20379b6..94381cdac 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; +using System.Globalization; using System.Linq; using System.Threading; using CommonIO; @@ -100,7 +101,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void ScheduleWake(TimerInfo info) { var startDate = RecordingHelper.GetStartTime(info).AddMinutes(-5); - _logger.Info("Scheduling system wake timer at {0} (UTC)", startDate); try { @@ -123,9 +123,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var timer = new Timer(TimerCallback, item.Id, length, TimeSpan.Zero); - if (!_timers.TryAdd(item.Id, timer)) + if (_timers.TryAdd(item.Id, timer)) + { + _logger.Warn("Creating recording timer for {0}, {1}. Timer will fire in {2} minutes", item.Id, item.Name, length.TotalMinutes.ToString(CultureInfo.InvariantCulture)); + } + else { timer.Dispose(); + _logger.Warn("Timer already exists for item {0}", item.Id); } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs index abfbab50c..866272639 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs @@ -37,6 +37,7 @@ namespace MediaBrowser.ServerApplication.Native { //Initialize(); //_bgWorker.RunWorkerAsync(utcTime.ToFileTime()); + throw new NotImplementedException(); } private void Initialize() From f08084920ca4528dac50fcefb7004ebec80b6bd5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 15:13:01 -0500 Subject: [PATCH 144/214] 3.0.5850 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 91e41c34b..ba3eaa378 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5849")] +[assembly: AssemblyVersion("3.0.5850")] From 5763ce5a425aa2216ec4cb7f1787a26cd6d5dd19 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 20:15:59 -0500 Subject: [PATCH 145/214] catch BDInfo errors --- .../MediaInfo/FFProbeVideoInfo.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index efa6ff0cf..8094aa58d 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -213,7 +213,7 @@ namespace MediaBrowser.Providers.MediaInfo } var chapters = mediaInfo.Chapters ?? new List(); - if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay)) + if (blurayInfo != null) { FetchBdInfo(video, chapters, mediaStreams, blurayInfo); } @@ -360,7 +360,15 @@ namespace MediaBrowser.Providers.MediaInfo /// VideoStream. private BlurayDiscInfo GetBDInfo(string path) { - return _blurayExaminer.GetDiscInfo(path); + try + { + return _blurayExaminer.GetDiscInfo(path); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting BDInfo", ex); + return null; + } } private void FetchEmbeddedInfo(Video video, Model.MediaInfo.MediaInfo data, MetadataRefreshOptions options) @@ -628,7 +636,7 @@ namespace MediaBrowser.Providers.MediaInfo FetchFromDvdLib(item, mount); } - if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType.Value == IsoType.BluRay)) + if (blurayDiscInfo != null) { item.PlayableStreamFileNames = blurayDiscInfo.Files.ToList(); } From a72c26d891a589b4d7005a21a38c4c0cf0137534 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 21:27:19 -0500 Subject: [PATCH 146/214] 3.0.5851 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index ba3eaa378..50a0ae7e9 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5850")] +[assembly: AssemblyVersion("3.0.5851")] From 74d85e8b193d89378d4c2a9ccf9fbf6f6668964e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 22:43:20 -0500 Subject: [PATCH 147/214] update recording logging --- .../LiveTv/EmbyTV/TimerManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 94381cdac..5d462f106 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (_timers.TryAdd(item.Id, timer)) { - _logger.Warn("Creating recording timer for {0}, {1}. Timer will fire in {2} minutes", item.Id, item.Name, length.TotalMinutes.ToString(CultureInfo.InvariantCulture)); + _logger.Info("Creating recording timer for {0}, {1}. Timer will fire in {2} minutes", item.Id, item.Name, length.TotalMinutes.ToString(CultureInfo.InvariantCulture)); } else { From 83d96f9bdad194172cfa2f943cf433ea0e68c355 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 22:45:29 -0500 Subject: [PATCH 148/214] update network cache Conflicts: MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs --- .../Networking/BaseNetworkManager.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index bc3dc360f..ff11c889a 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; -using System.Threading; using MoreLinq; namespace MediaBrowser.Common.Implementations.Networking @@ -14,22 +13,11 @@ namespace MediaBrowser.Common.Implementations.Networking public abstract class BaseNetworkManager { protected ILogger Logger { get; private set; } - private Timer _clearCacheTimer; + private DateTime _lastRefresh; protected BaseNetworkManager(ILogger logger) { Logger = logger; - - // Can't use network change events due to a crash in Linux - _clearCacheTimer = new Timer(ClearCacheTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); - } - - private void ClearCacheTimerCallback(object state) - { - lock (_localIpAddressSyncLock) - { - _localIpAddresses = null; - } } private volatile List _localIpAddresses; @@ -41,15 +29,21 @@ namespace MediaBrowser.Common.Implementations.Networking /// IPAddress. public IEnumerable GetLocalIpAddresses() { - if (_localIpAddresses == null) + const int cacheMinutes = 3; + var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + + if (_localIpAddresses == null || forceRefresh) { lock (_localIpAddressSyncLock) { - if (_localIpAddresses == null) + forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + + if (_localIpAddresses == null || forceRefresh) { var addresses = GetLocalIpAddressesInternal().ToList(); _localIpAddresses = addresses; + _lastRefresh = DateTime.UtcNow; return addresses; } From 51899f1880ebdd7ae05fdfe501476cdf68f713f2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 21:59:00 -0500 Subject: [PATCH 149/214] fixes #1218 - Dlna server doesn't work after resuming to sleep. --- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 134 ++++---------------------- 1 file changed, 17 insertions(+), 117 deletions(-) diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 32c369a8f..f800a12c1 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -33,12 +33,8 @@ namespace MediaBrowser.Dlna.Ssdp private readonly IPAddress _ssdpIp = IPAddress.Parse(SSDPAddr); private readonly IPEndPoint _ssdpEndp = new IPEndPoint(IPAddress.Parse(SSDPAddr), SSDPPort); - private Timer _queueTimer; private Timer _notificationTimer; - private readonly AutoResetEvent _datagramPosted = new AutoResetEvent(false); - private readonly ConcurrentQueue _messageQueue = new ConcurrentQueue(); - private bool _isDisposed; private readonly ConcurrentDictionary> _devices = new ConcurrentDictionary>(); @@ -121,9 +117,13 @@ namespace MediaBrowser.Dlna.Ssdp public void Start() { - RestartSocketListener(); + DisposeSocket(); + StopAliveNotifier(); + RestartSocketListener(); ReloadAliveNotifier(); + + SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; } @@ -131,7 +131,7 @@ namespace MediaBrowser.Dlna.Ssdp { if (e.Mode == PowerModes.Resume) { - NotifyAll(); + Start(); } } @@ -154,7 +154,7 @@ namespace MediaBrowser.Dlna.Ssdp SendDatagram("M-SEARCH * HTTP/1.1", values, _ssdpEndp, localIp, true, 2); } - public void SendDatagram(string header, + public async void SendDatagram(string header, Dictionary values, EndPoint endpoint, EndPoint localAddress, @@ -162,28 +162,18 @@ namespace MediaBrowser.Dlna.Ssdp int sendCount) { var msg = new SsdpMessageBuilder().BuildMessage(header, values); - var queued = false; var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLogging; for (var i = 0; i < sendCount; i++) { + if (i > 0) + { + await Task.Delay(500).ConfigureAwait(false); + } + var dgram = new Datagram(endpoint, localAddress, _logger, msg, isBroadcast, enableDebugLogging); - - if (_messageQueue.Count == 0) - { - dgram.Send(); - } - else - { - _messageQueue.Enqueue(dgram); - queued = true; - } - } - - if (queued) - { - StartQueueTimer(); + dgram.Send(); } } @@ -254,47 +244,10 @@ namespace MediaBrowser.Dlna.Ssdp } } - private readonly object _queueTimerSyncLock = new object(); - private void StartQueueTimer() - { - lock (_queueTimerSyncLock) - { - if (_queueTimer == null) - { - _queueTimer = new Timer(QueueTimerCallback, null, 500, Timeout.Infinite); - } - else - { - _queueTimer.Change(500, Timeout.Infinite); - } - } - } - - private void QueueTimerCallback(object state) - { - Datagram msg; - while (_messageQueue.TryDequeue(out msg)) - { - msg.Send(); - } - - _datagramPosted.Set(); - - if (_messageQueue.Count > 0) - { - StartQueueTimer(); - } - else - { - DisposeQueueTimer(); - } - } - private void RestartSocketListener() { if (_isDisposed) { - StopSocketRetryTimer(); return; } @@ -304,8 +257,6 @@ namespace MediaBrowser.Dlna.Ssdp _logger.Info("MultiCast socket created"); - StopSocketRetryTimer(); - Receive(); } catch (Exception ex) @@ -315,31 +266,6 @@ namespace MediaBrowser.Dlna.Ssdp } } - private Timer _socketRetryTimer; - private readonly object _socketRetryLock = new object(); - private void StartSocketRetryTimer() - { - lock (_socketRetryLock) - { - if (_socketRetryTimer == null) - { - _socketRetryTimer = new Timer(s => RestartSocketListener(), null, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); - } - } - } - - private void StopSocketRetryTimer() - { - lock (_socketRetryLock) - { - if (_socketRetryTimer != null) - { - _socketRetryTimer.Dispose(); - _socketRetryTimer = null; - } - } - } - private void Receive() { try @@ -448,16 +374,9 @@ namespace MediaBrowser.Dlna.Ssdp SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; _isDisposed = true; - while (_messageQueue.Count != 0) - { - _datagramPosted.WaitOne(); - } DisposeSocket(); - DisposeQueueTimer(); - DisposeNotificationTimer(); - - _datagramPosted.Dispose(); + StopAliveNotifier(); } private void DisposeSocket() @@ -470,18 +389,6 @@ namespace MediaBrowser.Dlna.Ssdp } } - private void DisposeQueueTimer() - { - lock (_queueTimerSyncLock) - { - if (_queueTimer != null) - { - _queueTimer.Dispose(); - _queueTimer = null; - } - } - } - private Socket CreateMulticastSocket() { var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); @@ -534,14 +441,7 @@ namespace MediaBrowser.Dlna.Ssdp public void RegisterNotification(Guid uuid, Uri descriptionUri, IPAddress address, IEnumerable services) { - List list; - lock (_devices) - { - if (!_devices.TryGetValue(uuid, out list)) - { - _devices.TryAdd(uuid, list = new List()); - } - } + var list = _devices.GetOrAdd(uuid, new List()); list.AddRange(services.Select(i => new UpnpDevice(uuid, i, descriptionUri, address))); @@ -572,7 +472,7 @@ namespace MediaBrowser.Dlna.Ssdp if (!config.BlastAliveMessages) { - DisposeNotificationTimer(); + StopAliveNotifier(); return; } @@ -599,7 +499,7 @@ namespace MediaBrowser.Dlna.Ssdp } } - private void DisposeNotificationTimer() + private void StopAliveNotifier() { lock (_notificationTimerSyncLock) { From cfa8f6c6eca1b58a34a684c17a51b14fb4306f8b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 22:40:21 -0500 Subject: [PATCH 150/214] reduce use of timers throughout the system Conflicts: MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs --- .../Networking/BaseNetworkManager.cs | 13 +++- .../MediaBrowser.Common.csproj | 1 + .../Threading/PeriodicTimer.cs | 67 +++++++++++++++++++ .../People/MovieDbPersonProvider.cs | 18 ++--- .../Channels/ChannelManager.cs | 61 +---------------- .../Connect/ConnectEntryPoint.cs | 5 +- .../EntryPoints/ExternalPortForwarding.cs | 5 +- .../EntryPoints/UsageEntryPoint.cs | 16 ++--- 8 files changed, 99 insertions(+), 87 deletions(-) create mode 100644 MediaBrowser.Common/Threading/PeriodicTimer.cs diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index ff11c889a..527a5fb3e 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -20,6 +20,14 @@ namespace MediaBrowser.Common.Implementations.Networking Logger = logger; } + private void ClearCacheTimerCallback(object state) + { + lock (_localIpAddressSyncLock) + { + _localIpAddresses = null; + } + } + private volatile List _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); @@ -29,14 +37,13 @@ namespace MediaBrowser.Common.Implementations.Networking /// IPAddress. public IEnumerable GetLocalIpAddresses() { - const int cacheMinutes = 3; - var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1; if (_localIpAddresses == null || forceRefresh) { lock (_localIpAddressSyncLock) { - forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1; if (_localIpAddresses == null || forceRefresh) { diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index ccdb319fe..17f211d84 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -90,6 +90,7 @@ + diff --git a/MediaBrowser.Common/Threading/PeriodicTimer.cs b/MediaBrowser.Common/Threading/PeriodicTimer.cs new file mode 100644 index 000000000..cb562a80d --- /dev/null +++ b/MediaBrowser.Common/Threading/PeriodicTimer.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading; +using Microsoft.Win32; + +namespace MediaBrowser.Common.Threading +{ + public class PeriodicTimer : IDisposable + { + public Action Callback { get; set; } + private Timer _timer; + private readonly object _state; + private readonly object _timerLock = new object(); + private readonly TimeSpan _period; + + public PeriodicTimer(Action callback, object state, TimeSpan dueTime, TimeSpan period) + { + Callback = callback; + _period = period; + _state = state; + + StartTimer(dueTime); + } + + void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) + { + if (e.Mode == PowerModes.Resume) + { + DisposeTimer(); + StartTimer(Timeout.InfiniteTimeSpan); + } + } + + private void TimerCallback(object state) + { + Callback(state); + } + + private void StartTimer(TimeSpan dueTime) + { + lock (_timerLock) + { + _timer = new Timer(TimerCallback, _state, dueTime, _period); + + SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + } + } + + private void DisposeTimer() + { + SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; + + lock (_timerLock) + { + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + } + } + + public void Dispose() + { + DisposeTimer(); + } + } +} diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 5c5919709..14304c2eb 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.People private int _requestCount; private readonly object _requestCountLock = new object(); - private Timer _requestCountReset; + private DateTime _lastRequestCountReset; public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger) { @@ -48,16 +48,6 @@ namespace MediaBrowser.Providers.People _httpClient = httpClient; _logger = logger; Current = this; - - _requestCountReset = new Timer(OnRequestThrottleTimerFired, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); - } - - private void OnRequestThrottleTimerFired(object state) - { - lock (_requestCountLock) - { - _requestCount = 0; - } } public string Name @@ -101,6 +91,12 @@ namespace MediaBrowser.Providers.People { lock (_requestCountLock) { + if ((DateTime.UtcNow - _lastRequestCountReset).TotalHours >= 1) + { + _requestCount = 0; + _lastRequestCountReset = DateTime.UtcNow; + } + var requestCount = _requestCount; if (requestCount >= 5) diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index b115c3bfd..284556c72 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -29,7 +29,7 @@ using CommonIO; namespace MediaBrowser.Server.Implementations.Channels { - public class ChannelManager : IChannelManager, IDisposable + public class ChannelManager : IChannelManager { private IChannel[] _channels; @@ -47,11 +47,6 @@ namespace MediaBrowser.Server.Implementations.Channels private readonly ILocalizationManager _localization; private readonly ConcurrentDictionary _refreshedItems = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _downloadCounts = new ConcurrentDictionary(); - - private Timer _refreshTimer; - private Timer _clearDownloadCountsTimer; - public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IUserDataManager userDataManager, IJsonSerializer jsonSerializer, ILocalizationManager localization, IHttpClient httpClient, IProviderManager providerManager) { _userManager = userManager; @@ -65,9 +60,6 @@ namespace MediaBrowser.Server.Implementations.Channels _localization = localization; _httpClient = httpClient; _providerManager = providerManager; - - _refreshTimer = new Timer(s => _refreshedItems.Clear(), null, TimeSpan.FromHours(3), TimeSpan.FromHours(3)); - _clearDownloadCountsTimer = new Timer(s => _downloadCounts.Clear(), null, TimeSpan.FromHours(24), TimeSpan.FromHours(24)); } private TimeSpan CacheLength @@ -206,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.Channels public async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { + _refreshedItems.Clear(); + var allChannelsList = GetAllChannels().ToList(); var numComplete = 0; @@ -1471,12 +1465,6 @@ namespace MediaBrowser.Server.Implementations.Channels var limit = features.DailyDownloadLimit; - if (!ValidateDownloadLimit(host, limit)) - { - _logger.Error(string.Format("Download limit has been reached for {0}", channel.Name)); - throw new ChannelDownloadException(string.Format("Download limit has been reached for {0}", channel.Name)); - } - foreach (var header in source.RequiredHttpHeaders) { options.RequestHeaders[header.Key] = header.Value; @@ -1495,8 +1483,6 @@ namespace MediaBrowser.Server.Implementations.Channels }; } - IncrementDownloadCount(host, limit); - if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) { var extension = response.ContentType.Split('/') @@ -1531,46 +1517,5 @@ namespace MediaBrowser.Server.Implementations.Channels } } - - private void IncrementDownloadCount(string key, int? limit) - { - if (!limit.HasValue) - { - return; - } - - int current; - _downloadCounts.TryGetValue(key, out current); - - current++; - _downloadCounts.AddOrUpdate(key, current, (k, v) => current); - } - - private bool ValidateDownloadLimit(string key, int? limit) - { - if (!limit.HasValue) - { - return true; - } - - int current; - _downloadCounts.TryGetValue(key, out current); - - return current < limit.Value; - } - - public void Dispose() - { - if (_clearDownloadCountsTimer != null) - { - _clearDownloadCountsTimer.Dispose(); - _clearDownloadCountsTimer = null; - } - if (_refreshTimer != null) - { - _refreshTimer.Dispose(); - _refreshTimer = null; - } - } } } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 6dab136a5..0d6b8ac26 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -13,12 +13,13 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Common.IO; +using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.Connect { public class ConnectEntryPoint : IServerEntryPoint { - private Timer _timer; + private PeriodicTimer _timer; private readonly IHttpClient _httpClient; private readonly IApplicationPaths _appPaths; private readonly ILogger _logger; @@ -43,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Connect { Task.Run(() => LoadCachedAddress()); - _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); + _timer = new PeriodicTimer(null, new TimerCallback(TimerCallback), TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" }; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index a2ffa9aff..2b2c338dd 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -11,6 +11,7 @@ using System.IO; using System.Net; using System.Text; using System.Threading; +using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -21,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly IServerConfigurationManager _config; private readonly ISsdpHandler _ssdp; - private Timer _timer; + private PeriodicTimer _timer; private bool _isStarted; public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, ISsdpHandler ssdp) @@ -95,7 +96,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints NatUtility.UnhandledException += NatUtility_UnhandledException; NatUtility.StartDiscovery(); - _timer = new Timer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); + _timer = new PeriodicTimer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); _ssdp.MessageReceived += _ssdp_MessageReceived; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs index c3b9c0d4d..d8aef909b 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -23,7 +24,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ISessionManager _sessionManager; private readonly IUserManager _userManager; - private Timer _timer; private readonly TimeSpan _frequency = TimeSpan.FromHours(24); private readonly ConcurrentDictionary _apps = new ConcurrentDictionary(); @@ -95,16 +95,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints return info; } - public void Run() + public async void Run() { - _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(5000), _frequency); + await Task.Delay(5000).ConfigureAwait(false); + OnTimerFired(); } /// /// Called when [timer fired]. /// - /// The state. - private async void OnTimerFired(object state) + private async void OnTimerFired() { try { @@ -121,12 +121,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints public void Dispose() { _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } } } } From 352595bc16563b70fa254331c22f821e32432570 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 22:42:03 -0500 Subject: [PATCH 151/214] add null check to PeriodicTimer --- MediaBrowser.Common/Threading/PeriodicTimer.cs | 5 +++++ .../Connect/ConnectEntryPoint.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Common/Threading/PeriodicTimer.cs b/MediaBrowser.Common/Threading/PeriodicTimer.cs index cb562a80d..75ccada4e 100644 --- a/MediaBrowser.Common/Threading/PeriodicTimer.cs +++ b/MediaBrowser.Common/Threading/PeriodicTimer.cs @@ -14,6 +14,11 @@ namespace MediaBrowser.Common.Threading public PeriodicTimer(Action callback, object state, TimeSpan dueTime, TimeSpan period) { + if (callback == null) + { + throw new ArgumentNullException("callback"); + } + Callback = callback; _period = period; _state = state; diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 0d6b8ac26..12de5f6ef 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Connect { Task.Run(() => LoadCachedAddress()); - _timer = new PeriodicTimer(null, new TimerCallback(TimerCallback), TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); + _timer = new PeriodicTimer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" }; From 22bfa9ca82943795215c8f2e5735d31d58391f82 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 00:18:05 -0500 Subject: [PATCH 152/214] merge from dev --- .../Networking/BaseNetworkManager.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index 527a5fb3e..ff11c889a 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -20,14 +20,6 @@ namespace MediaBrowser.Common.Implementations.Networking Logger = logger; } - private void ClearCacheTimerCallback(object state) - { - lock (_localIpAddressSyncLock) - { - _localIpAddresses = null; - } - } - private volatile List _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); @@ -37,13 +29,14 @@ namespace MediaBrowser.Common.Implementations.Networking /// IPAddress. public IEnumerable GetLocalIpAddresses() { - var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1; + const int cacheMinutes = 3; + var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; if (_localIpAddresses == null || forceRefresh) { lock (_localIpAddressSyncLock) { - forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1; + forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; if (_localIpAddresses == null || forceRefresh) { From 933a1664242674d45c5b449fef01ebf555685df5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 00:18:23 -0500 Subject: [PATCH 153/214] 3.0.5852 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 50a0ae7e9..4620e926e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5851")] +[assembly: AssemblyVersion("3.0.5852")] From 0361b8b0e8023c400df3eaac04718cf9b8ff01d0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 13:29:09 -0500 Subject: [PATCH 154/214] don't organize with unknown episode name --- .../FileOrganization/EpisodeFileOrganizer.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index ae40ed6b5..e15ce27e0 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -189,15 +189,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - if (!series.ProviderIds.Any()) - { - var msg = string.Format("Series has not yet been identified: {0}. If you just added the series, please run a library scan or use the identify feature to identify it.", seriesName); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - return Task.FromResult(true); - } - return OrganizeEpisode(sourcePath, series, seasonNumber, @@ -471,7 +462,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The season number. /// The episode number. /// The ending episode number. + /// The premiere date. /// The options. + /// The cancellation token. /// System.String. private async Task GetNewPath(string sourcePath, Series series, @@ -501,17 +494,20 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var episode = searchResults.FirstOrDefault(); - string episodeName = string.Empty; - if (episode == null) { var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); _logger.Warn(msg); - //throw new Exception(msg); + return null; } - else + + var episodeName = episode.Name; + + if (string.IsNullOrWhiteSpace(episodeName)) { - episodeName = episode.Name; + var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + _logger.Warn(msg); + return null; } seasonNumber = seasonNumber ?? episode.ParentIndexNumber; From 00de5b1ca7c921bf84b9ba2a51bcf40e4bdafe15 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 14:20:09 -0500 Subject: [PATCH 155/214] update use of timers --- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 24 ++++++------------- .../News/NewsEntryPoint.cs | 6 ++--- .../EntryPoints/KeepServerAwake.cs | 6 ++--- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 6c79007c4..94f8104be 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IMediaSourceManager _mediaSourceManager; private readonly List _nonRendererUrls = new List(); - private Timer _clearNonRenderersTimer; + private DateTime _lastRendererClear; public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager) { @@ -57,19 +57,9 @@ namespace MediaBrowser.Dlna.PlayTo public void Start() { - _clearNonRenderersTimer = new Timer(OnClearUrlTimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); - _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; } - private void OnClearUrlTimerCallback(object state) - { - lock (_nonRendererUrls) - { - _nonRendererUrls.Clear(); - } - } - async void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e) { string usn; @@ -99,6 +89,12 @@ namespace MediaBrowser.Dlna.PlayTo lock (_nonRendererUrls) { + if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10) + { + _nonRendererUrls.Clear(); + _lastRendererClear = DateTime.UtcNow; + } + if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase)) { return; @@ -181,12 +177,6 @@ namespace MediaBrowser.Dlna.PlayTo public void Dispose() { _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; - - if (_clearNonRenderersTimer != null) - { - _clearNonRenderersTimer.Dispose(); - _clearNonRenderersTimer = null; - } } } } diff --git a/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs b/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs index e8f910f81..969541fbc 100644 --- a/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; @@ -17,12 +16,13 @@ using System.Threading; using System.Threading.Tasks; using System.Xml; using CommonIO; +using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.News { public class NewsEntryPoint : IServerEntryPoint { - private Timer _timer; + private PeriodicTimer _timer; private readonly IHttpClient _httpClient; private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; @@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.News public void Run() { - _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); + _timer = new PeriodicTimer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); } /// diff --git a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs b/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs index ba335868d..20d4c6b2a 100644 --- a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs +++ b/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs @@ -4,7 +4,7 @@ using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; using System; using System.Linq; -using System.Threading; +using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Startup.Common.EntryPoints { @@ -12,7 +12,7 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints { private readonly ISessionManager _sessionManager; private readonly ILogger _logger; - private Timer _timer; + private PeriodicTimer _timer; private readonly IServerApplicationHost _appHost; public KeepServerAwake(ISessionManager sessionManager, ILogger logger, IServerApplicationHost appHost) @@ -24,7 +24,7 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints public void Run() { - _timer = new Timer(obj => + _timer = new PeriodicTimer(obj => { var now = DateTime.UtcNow; if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15)) From 24b925cb56c171a6d88159344f25bc910af5cd29 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 14:37:20 -0500 Subject: [PATCH 156/214] remove timer from PlayToController --- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 49 +++++++------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index cb3629678..7e021b877 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -37,11 +37,28 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IDeviceDiscovery _deviceDiscovery; private readonly string _serverAddress; private readonly string _accessToken; + private readonly DateTime _creationTime; public bool IsSessionActive { get { + var lastDateKnownActivity = new[] { _creationTime, _device.DateLastActivity }.Max(); + + if (DateTime.UtcNow >= lastDateKnownActivity.AddSeconds(120)) + { + try + { + // Session is inactive, mark it for Disposal and don't start the elapsed timer. + _sessionManager.ReportSessionEnded(_session.Id); + } + catch (Exception ex) + { + _logger.ErrorException("Error in ReportSessionEnded", ex); + } + return false; + } + return _device != null; } } @@ -55,8 +72,6 @@ namespace MediaBrowser.Dlna.PlayTo get { return IsSessionActive; } } - private Timer _updateTimer; - public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager) { _session = session; @@ -72,6 +87,7 @@ namespace MediaBrowser.Dlna.PlayTo _mediaSourceManager = mediaSourceManager; _accessToken = accessToken; _logger = logger; + _creationTime = DateTime.UtcNow; } public void Init(Device device) @@ -84,8 +100,6 @@ namespace MediaBrowser.Dlna.PlayTo _device.Start(); _deviceDiscovery.DeviceLeft += _deviceDiscovery_DeviceLeft; - - _updateTimer = new Timer(updateTimer_Elapsed, null, 60000, 60000); } void _deviceDiscovery_DeviceLeft(object sender, SsdpMessageEventArgs e) @@ -117,22 +131,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - private void updateTimer_Elapsed(object state) - { - if (DateTime.UtcNow >= _device.DateLastActivity.AddSeconds(120)) - { - try - { - // Session is inactive, mark it for Disposal and don't start the elapsed timer. - _sessionManager.ReportSessionEnded(_session.Id); - } - catch (Exception ex) - { - _logger.ErrorException("Error in ReportSessionEnded", ex); - } - } - } - async void _device_MediaChanged(object sender, MediaChangedEventArgs e) { try @@ -634,21 +632,10 @@ namespace MediaBrowser.Dlna.PlayTo _device.MediaChanged -= _device_MediaChanged; _deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft; - DisposeUpdateTimer(); - _device.Dispose(); } } - private void DisposeUpdateTimer() - { - if (_updateTimer != null) - { - _updateTimer.Dispose(); - _updateTimer = null; - } - } - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) From de30a0e10bdc05a1ac44ec84e4a2be154a647236 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 14:52:39 -0500 Subject: [PATCH 157/214] remove volume timer from device --- MediaBrowser.Dlna/PlayTo/Device.cs | 79 ++++++++++++++++-------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 222a52736..1ec7a4ce0 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -22,14 +22,26 @@ namespace MediaBrowser.Dlna.PlayTo #region Fields & Properties private Timer _timer; - private Timer _volumeTimer; public DeviceInfo Properties { get; set; } private int _muteVol; public bool IsMuted { get; set; } - public int Volume { get; set; } + private int _volume; + + public int Volume + { + get + { + RefreshVolumeIfNeeded(); + return _volume; + } + set + { + _volume = value; + } + } public TimeSpan? Duration { get; set; } @@ -93,11 +105,6 @@ namespace MediaBrowser.Dlna.PlayTo return 1000; } - private int GetVolumeTimerIntervalMs() - { - return 5000; - } - private int GetInactiveTimerIntervalMs() { return 20000; @@ -107,11 +114,37 @@ namespace MediaBrowser.Dlna.PlayTo { _timer = new Timer(TimerCallback, null, GetPlaybackTimerIntervalMs(), GetInactiveTimerIntervalMs()); - _volumeTimer = new Timer(VolumeTimerCallback, null, Timeout.Infinite, Timeout.Infinite); - _timerActive = false; } + private DateTime _lastVolumeRefresh; + private void RefreshVolumeIfNeeded() + { + if (!_timerActive) + { + return; + } + + if (DateTime.UtcNow >= _lastVolumeRefresh.AddSeconds(5)) + { + _lastVolumeRefresh = DateTime.UtcNow; + RefreshVolume(); + } + } + + private async void RefreshVolume() + { + try + { + await GetVolume().ConfigureAwait(false); + await GetMute().ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error updating device volume info for {0}", ex, Properties.Name); + } + } + private readonly object _timerLock = new object(); private bool _timerActive; private void RestartTimer() @@ -124,7 +157,6 @@ namespace MediaBrowser.Dlna.PlayTo { _logger.Debug("RestartTimer"); _timer.Change(10, GetPlaybackTimerIntervalMs()); - _volumeTimer.Change(100, GetVolumeTimerIntervalMs()); } _timerActive = true; @@ -150,10 +182,6 @@ namespace MediaBrowser.Dlna.PlayTo { _timer.Change(interval, interval); } - if (_volumeTimer != null) - { - _volumeTimer.Change(Timeout.Infinite, Timeout.Infinite); - } } _timerActive = false; @@ -440,19 +468,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - private async void VolumeTimerCallback(object sender) - { - try - { - await GetVolume().ConfigureAwait(false); - await GetMute().ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error updating device volume info for {0}", ex, Properties.Name); - } - } - private async Task GetVolume() { var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume"); @@ -1012,7 +1027,6 @@ namespace MediaBrowser.Dlna.PlayTo _disposed = true; DisposeTimer(); - DisposeVolumeTimer(); } } @@ -1025,15 +1039,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - private void DisposeVolumeTimer() - { - if (_volumeTimer != null) - { - _volumeTimer.Dispose(); - _volumeTimer = null; - } - } - #endregion public override string ToString() From b82b6fc97554009c045f2f2f0ffa10cf806bc71b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 14:52:50 -0500 Subject: [PATCH 158/214] remove no_accurate seek --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 9e2e399d7..bb7f6bb1e 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -2192,7 +2192,7 @@ namespace MediaBrowser.Api.Playback { if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase)) { - inputModifier += " -noaccurate_seek"; + //inputModifier += " -noaccurate_seek"; } } From b1c9984498db115bae5e32e3e1c018fb7cb340a9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 21:42:53 -0500 Subject: [PATCH 159/214] update timer --- .../EntryPoints/LoadRegistrations.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs index 701cf21fb..efda36821 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs @@ -4,6 +4,7 @@ using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -22,7 +23,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// private readonly ILogger _logger; - private Timer _timer; + private PeriodicTimer _timer; /// /// Initializes a new instance of the class. @@ -41,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// public void Run() { - _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12)); + _timer = new PeriodicTimer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12)); } private async Task LoadAllRegistrations() From 0a43522d15641c677fb73485cce2f7451c292736 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 23:54:42 -0500 Subject: [PATCH 160/214] default to include hidden --- MediaBrowser.Api/EnvironmentService.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 8fdfea6b4..4e88e946f 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; @@ -46,6 +45,11 @@ namespace MediaBrowser.Api /// true if [include hidden]; otherwise, false. [ApiMember(Name = "IncludeHidden", Description = "An optional filter to include or exclude hidden files and folders. true/false", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool IncludeHidden { get; set; } + + public GetDirectoryContents() + { + IncludeHidden = true; + } } [Route("/Environment/NetworkShares", "GET", Summary = "Gets shares from a network device")] From fae9b184810ec81de92e6d14b8043b37c085de9e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 23:54:55 -0500 Subject: [PATCH 161/214] update episode organizer --- .../FileOrganization/EpisodeFileOrganizer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index e15ce27e0..73cc5ab01 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -503,12 +503,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var episodeName = episode.Name; - if (string.IsNullOrWhiteSpace(episodeName)) - { - var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); - _logger.Warn(msg); - return null; - } + //if (string.IsNullOrWhiteSpace(episodeName)) + //{ + // var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + // _logger.Warn(msg); + // return null; + //} seasonNumber = seasonNumber ?? episode.ParentIndexNumber; episodeNumber = episodeNumber ?? episode.IndexNumber; @@ -584,7 +584,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - if (string.IsNullOrEmpty(episodeTitle)) + if (string.IsNullOrWhiteSpace(episodeTitle)) { episodeTitle = string.Empty; } From c957ca936f76f6a25af8398feca9f9d1d18e2685 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jan 2016 13:31:31 -0500 Subject: [PATCH 162/214] update components Conflicts: MediaBrowser.WebDashboard/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js --- MediaBrowser.Api/Playback/MediaInfoService.cs | 6 +++--- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 3b577ac01..2bf61f90b 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -141,10 +141,10 @@ namespace MediaBrowser.Api.Playback var profile = request.DeviceProfile; - var caps = _deviceManager.GetCapabilities(authInfo.DeviceId); - if (caps != null) + if (profile == null) { - if (profile == null) + var caps = _deviceManager.GetCapabilities(authInfo.DeviceId); + if (caps != null) { profile = caps.DeviceProfile; } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index cc153a010..a3788ef6c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -311,9 +311,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 6ba51ef49508f8ae00c8f31521819a08c8f28b2f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jan 2016 13:55:26 -0500 Subject: [PATCH 163/214] 3.0.5853 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 4620e926e..1caaf8542 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5852")] +[assembly: AssemblyVersion("3.0.5853")] From dc43c1077d28fa1f4b04bc06d6956e83dabedfd6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jan 2016 13:31:31 -0500 Subject: [PATCH 164/214] merge from dev --- .../LiveTv/EmbyTV/EmbyTV.cs | 70 ++++++++++++++----- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 250b5655f..ea64950ab 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { epgData = GetEpgDataForChannel(timer.ChannelId); } - await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false); + await UpdateTimersForSeriesTimer(epgData, timer, false).ConfigureAwait(false); } var timers = await GetTimersAsync(cancellationToken).ConfigureAwait(false); @@ -348,25 +348,44 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } _seriesTimerProvider.Add(info); - await UpdateTimersForSeriesTimer(epgData, info).ConfigureAwait(false); + await UpdateTimersForSeriesTimer(epgData, info, false).ConfigureAwait(false); } public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) { - _seriesTimerProvider.Update(info); - List epgData; - if (info.RecordAnyChannel) - { - var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); - var channelIds = channels.Select(i => i.Id).ToList(); - epgData = GetEpgDataForChannels(channelIds); - } - else - { - epgData = GetEpgDataForChannel(info.ChannelId); - } + var instance = _seriesTimerProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); - await UpdateTimersForSeriesTimer(epgData, info).ConfigureAwait(false); + if (instance != null) + { + instance.ChannelId = info.ChannelId; + instance.Days = info.Days; + instance.EndDate = info.EndDate; + instance.IsPostPaddingRequired = info.IsPostPaddingRequired; + instance.IsPrePaddingRequired = info.IsPrePaddingRequired; + instance.PostPaddingSeconds = info.PostPaddingSeconds; + instance.PrePaddingSeconds = info.PrePaddingSeconds; + instance.Priority = info.Priority; + instance.RecordAnyChannel = info.RecordAnyChannel; + instance.RecordAnyTime = info.RecordAnyTime; + instance.RecordNewOnly = info.RecordNewOnly; + instance.StartDate = info.StartDate; + + _seriesTimerProvider.Update(instance); + + List epgData; + if (instance.RecordAnyChannel) + { + var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); + var channelIds = channels.Select(i => i.Id).ToList(); + epgData = GetEpgDataForChannels(channelIds); + } + else + { + epgData = GetEpgDataForChannel(instance.ChannelId); + } + + await UpdateTimersForSeriesTimer(epgData, instance, true).ConfigureAwait(false); + } } public Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken) @@ -856,7 +875,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return _config.GetConfiguration("livetv"); } - private async Task UpdateTimersForSeriesTimer(List epgData, SeriesTimerInfo seriesTimer) + private async Task UpdateTimersForSeriesTimer(List epgData, SeriesTimerInfo seriesTimer, bool deleteInvalidTimers) { var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); @@ -869,12 +888,29 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _timerProvider.AddOrUpdate(timer); } } + + if (deleteInvalidTimers) + { + var allTimers = GetTimersForSeries(seriesTimer, epgData, new List()) + .Select(i => i.Id) + .ToList(); + + var deletes = _timerProvider.GetAll() + .Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase)) + .Where(i => !allTimers.Contains(i.Id, StringComparer.OrdinalIgnoreCase) && i.StartDate > DateTime.UtcNow) + .ToList(); + + foreach (var timer in deletes) + { + await CancelTimerAsync(timer.Id, CancellationToken.None).ConfigureAwait(false); + } + } } private IEnumerable GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable allPrograms, IReadOnlyList currentRecordings) { // Exclude programs that have already ended - allPrograms = allPrograms.Where(i => i.EndDate > DateTime.UtcNow); + allPrograms = allPrograms.Where(i => i.EndDate > DateTime.UtcNow && i.StartDate > DateTime.UtcNow); allPrograms = GetProgramsForSeries(seriesTimer, allPrograms); From 77a4c6af94e3f8ce02926b445ffff791b8ccd7d7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jan 2016 15:59:09 -0500 Subject: [PATCH 165/214] switch to shared paperdialoghelper --- 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 a3788ef6c..165792291 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -158,9 +158,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From a789f1d425fc74d6f83318b54ae4d8b377a706df Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Jan 2016 16:34:28 -0500 Subject: [PATCH 166/214] 3.0.5854 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 1caaf8542..f230a0b64 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5853")] +[assembly: AssemblyVersion("3.0.5854")] From 7ac682f06cf45b11967ce51974a3f26da5612b0d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jan 2016 01:03:40 -0500 Subject: [PATCH 167/214] use shared slideshow --- MediaBrowser.WebDashboard/Api/DashboardService.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 5ad40e4c7..12cd5c385 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -354,8 +354,7 @@ namespace MediaBrowser.WebDashboard.Api DeleteFoldersByName(Path.Combine(bowerPath, "jstree"), "src"); DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "meteor"); DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "st"); - DeleteFoldersByName(Path.Combine(bowerPath, "swipebox"), "lib"); - DeleteFoldersByName(Path.Combine(bowerPath, "swipebox"), "scss"); + DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src"); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { From 0297d8f7d3bbb774749d627508849fc00d9a4c71 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jan 2016 19:57:40 -0500 Subject: [PATCH 168/214] update locking --- .../ScheduledTasks/ScheduledTaskWorker.cs | 8 ++++---- MediaBrowser.Controller/Entities/User.cs | 4 ++-- .../Library/LibraryManager.cs | 4 ++-- .../LiveTv/EmbyTV/EmbyTV.cs | 6 +++++- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 95f29915d..a4ccbb6f8 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -233,7 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// /// The _triggers /// - private IEnumerable _triggers; + private volatile List _triggers; /// /// The _triggers sync lock /// @@ -532,7 +532,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// Loads the triggers. /// /// IEnumerable{BaseTaskTrigger}. - private IEnumerable LoadTriggers() + private List LoadTriggers() { try { @@ -543,12 +543,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks catch (FileNotFoundException) { // File doesn't exist. No biggie. Return defaults. - return ScheduledTask.GetDefaultTriggers(); + return ScheduledTask.GetDefaultTriggers().ToList(); } catch (DirectoryNotFoundException) { // File doesn't exist. No biggie. Return defaults. - return ScheduledTask.GetDefaultTriggers(); + return ScheduledTask.GetDefaultTriggers().ToList(); } } diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index a9e314ede..be8521a5c 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -109,7 +109,7 @@ namespace MediaBrowser.Controller.Entities /// The last activity date. public DateTime? LastActivityDate { get; set; } - private UserConfiguration _config; + private volatile UserConfiguration _config; private readonly object _configSyncLock = new object(); [IgnoreDataMember] public UserConfiguration Configuration @@ -132,7 +132,7 @@ namespace MediaBrowser.Controller.Entities set { _config = value; } } - private UserPolicy _policy; + private volatile UserPolicy _policy; private readonly object _policySyncLock = new object(); [IgnoreDataMember] public UserPolicy Policy diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 0cb5174c9..b0b2680ca 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -222,7 +222,7 @@ namespace MediaBrowser.Server.Implementations.Library /// /// The _root folder /// - private AggregateFolder _rootFolder; + private volatile AggregateFolder _rootFolder; /// /// The _root folder sync lock /// @@ -743,7 +743,7 @@ namespace MediaBrowser.Server.Implementations.Library return rootFolder; } - private UserRootFolder _userRootFolder; + private volatile UserRootFolder _userRootFolder; private readonly object _syncLock = new object(); public Folder GetUserRootFolder() { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index ea64950ab..cd91684ce 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -239,7 +239,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) { - var timers = _timerProvider.GetAll().Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase)); + var timers = _timerProvider + .GetAll() + .Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase)) + .ToList(); + foreach (var timer in timers) { CancelTimerInternal(timer.Id); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index f46daa6d5..b29a7562c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV where T : class { private readonly object _fileDataLock = new object(); - private List _items; + private volatile List _items; private readonly IJsonSerializer _jsonSerializer; protected readonly ILogger Logger; private readonly string _dataPath; From 552694bb383e956eaa2ce75c208a70c75cfb2a41 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 Jan 2016 20:02:23 -0500 Subject: [PATCH 169/214] 3.0.5855 --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index f230a0b64..74dd1c2b1 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5854")] +[assembly: AssemblyVersion("3.0.5855")] From 025958a22d84d4d98876d8ba349f82087d585b7b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Feb 2016 12:02:58 -0500 Subject: [PATCH 170/214] update interlaced detection --- .../Encoder/MediaEncoder.cs | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index ba0790bf3..2a3a416ad 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -292,16 +292,25 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } - // If the video codec is not some form of mpeg, then take a shortcut and limit this to containers that are likely to have interlaced content - if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) == -1) + var formats = (video.Container ?? string.Empty).Split(',').ToList(); + var enableInterlacedDection = formats.Contains("vob", StringComparer.OrdinalIgnoreCase) && + formats.Contains("m2ts", StringComparer.OrdinalIgnoreCase) && + formats.Contains("ts", StringComparer.OrdinalIgnoreCase) && + formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) && + formats.Contains("wtv", StringComparer.OrdinalIgnoreCase); + + // If it's mpeg based, assume true + if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1) { - var formats = (video.Container ?? string.Empty).Split(',').ToList(); - - if (!formats.Contains("vob", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("m2ts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("ts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) && - !formats.Contains("wtv", StringComparer.OrdinalIgnoreCase)) + if (enableInterlacedDection) + { + return true; + } + } + else + { + // If the video codec is not some form of mpeg, then take a shortcut and limit this to containers that are likely to have interlaced content + if (!enableInterlacedDection) { return false; } From 865e2babfa70809a165ddc7070ffd80b5ee3d87e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Feb 2016 12:22:02 -0500 Subject: [PATCH 171/214] album refresh fixes --- .../Entities/Audio/MusicAlbum.cs | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 98d1eb4ce..654c9abd3 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -1,17 +1,21 @@ -using MediaBrowser.Controller.Providers; +using System; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Library; namespace MediaBrowser.Controller.Entities.Audio { /// /// Class MusicAlbum /// - public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo + public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo, IMetadataContainer { public MusicAlbum() { @@ -139,5 +143,58 @@ namespace MediaBrowser.Controller.Entities.Audio return id; } + + public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) + { + var items = GetRecursiveChildren().ToList(); + + var songs = items.OfType