From 4b15d1849cc5ec42239098214c984e5e7b056bcc Mon Sep 17 00:00:00 2001 From: Andrew Schurman Date: Mon, 17 Aug 2015 22:20:02 -0700 Subject: [PATCH 001/212] Ensure that all ssa tags are wiped out of srt subtitles --- MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs | 2 +- .../MediaEncoding/Subtitles/TestSubtitles/unit.srt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index d40d4afa71..2a6aa993c1 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -69,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } subEvent.Text = string.Join(ParserValues.NewLine, multiline); subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase); - subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase); + subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\\d?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, "<", "<", RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, ">", ">", RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, "<(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)>", "<$1$3$7>", RegexOptions.IgnoreCase); diff --git a/MediaBrowser.Tests/MediaEncoding/Subtitles/TestSubtitles/unit.srt b/MediaBrowser.Tests/MediaEncoding/Subtitles/TestSubtitles/unit.srt index 5f6e5636ec..1ce811bcb6 100644 --- a/MediaBrowser.Tests/MediaEncoding/Subtitles/TestSubtitles/unit.srt +++ b/MediaBrowser.Tests/MediaEncoding/Subtitles/TestSubtitles/unit.srt @@ -35,7 +35,7 @@ Unclosed but supported HTML tags are left in, {\i1} SSA italics aren't 9 00:00:36,000 --> 00:00:36,999 -Multiple {\pos(142,120)\b1}SSA tags are stripped +Multiple {\bord-3.7\clip(1,m 50 0 b 100 0 100 100 50 100 b 0 100 0 0 50 0)\pos(142,120)\t(0,500,\fscx100\fscy100)\b1\c&H000000&}SSA tags are stripped 10 00:00:37,000 --> 00:00:37,999 From f91bfe0dab08996acc034dc44ee57854a9ea4138 Mon Sep 17 00:00:00 2001 From: RoliePolieOlie Date: Wed, 2 Sep 2015 16:46:00 +0200 Subject: [PATCH 002/212] Probe for MB-ids as generated by MB Picard --- .../Probing/ProbeResultNormalizer.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 481ba0ddac..e4128cf945 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -509,12 +509,25 @@ namespace MediaBrowser.MediaEncoding.Probing FetchStudios(audio, tags, "label"); // These support mulitple values, but for now we only store the first. - audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzArtist, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"))); + var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id")); + if(mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); + audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id")); + if(mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); + audio.SetProviderId(MetadataProviders.MusicBrainzArtist, mb); - audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzTrack, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id"))); + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id")); + if(mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); + audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id")); + if(mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); + audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id")); + if(mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); + audio.SetProviderId(MetadataProviders.MusicBrainzTrack, mb); } private string GetMultipleMusicBrainzId(string value) From ffb9a86cec63681ef5504d8448ae76e83672526e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Sep 2015 12:14:32 -0400 Subject: [PATCH 003/212] fixes #1142 --- MediaBrowser.Controller/Entities/BaseItem.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 594b5ca93c..570d566540 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -484,7 +484,6 @@ namespace MediaBrowser.Controller.Entities public Guid ParentId { get; set; } - private Folder _parent; /// /// Gets or sets the parent. /// @@ -494,11 +493,6 @@ namespace MediaBrowser.Controller.Entities { get { - if (_parent != null) - { - return _parent; - } - if (ParentId != Guid.Empty) { return LibraryManager.GetItemById(ParentId) as Folder; @@ -506,12 +500,10 @@ namespace MediaBrowser.Controller.Entities return null; } - set { _parent = value; } } public void SetParent(Folder parent) { - Parent = parent; ParentId = parent == null ? Guid.Empty : parent.Id; } From b49d523fdbd22608a652504e4e68e0bd01defe0c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Sep 2015 16:20:26 -0400 Subject: [PATCH 004/212] update rev --- SharedVersion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 485a57854a..6bf7a6de10 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; //[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5724.2")] +[assembly: AssemblyVersion("3.0.5724.3")] From 7038c7848c870cb368d1074f8947d7815474b12c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Sep 2015 16:21:31 -0400 Subject: [PATCH 005/212] version bump --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 6bf7a6de10..3bb674230b 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5724.3")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5724.3")] From d482c6efc7c87a200802db44b152a379eee83418 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Sep 2015 21:40:47 -0400 Subject: [PATCH 006/212] fix recordings --- .../LiveTv/EmbyTV/EmbyTV.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 4e0d6e8d49..66ef209280 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -500,14 +500,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV catch (Exception ex) { _logger.ErrorException("Error recording stream", ex); - - if (DateTime.UtcNow < timer.EndDate) - { - const int retryIntervalSeconds = 60; - _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); - - _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); - } } } @@ -597,7 +589,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _recordingProvider.Update(recording); _logger.Info("Beginning recording."); - + try { httpRequestOptions.BufferContent = false; @@ -629,12 +621,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.Update(recording); - _timerProvider.Delete(timer); - _logger.Info("Recording was a success"); if (recording.Status == RecordingStatus.Completed) { OnSuccessfulRecording(recording); + _timerProvider.Delete(timer); + } + else + { + if (DateTime.UtcNow < timer.EndDate) + { + const int retryIntervalSeconds = 60; + _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); + + _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); + } } } From 46aa31b3992f695a49908f022d1383d4eeb1196b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Sep 2015 00:16:31 -0400 Subject: [PATCH 007/212] fix shortcut setting --- MediaBrowser.Controller/Entities/Folder.cs | 4 ++-- .../Library/UserViewManager.cs | 3 ++- .../Persistence/CleanDatabaseScheduledTask.cs | 8 +++++++- .../MediaBrowser.WebDashboard.csproj | 6 ------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index c3ac77328d..84e5e985be 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public virtual bool IsPreSorted { - get { return ConfigurationManager.Configuration.EnableWindowsShortcuts; } + get { return false; } } /// @@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] protected virtual bool SupportsShortcutChildren { - get { return false; } + get { return ConfigurationManager.Configuration.EnableWindowsShortcuts; } } /// diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 43f77ec490..990799e71d 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -136,7 +136,8 @@ namespace MediaBrowser.Server.Implementations.Library if (parents.Count > 0) { - list.Add(await GetUserView(parents, list, CollectionType.Playlists, string.Empty, user, cancellationToken).ConfigureAwait(false)); + var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Playlists); + list.Add(await _libraryManager.GetNamedView(name, CollectionType.Playlists, string.Empty, cancellationToken).ConfigureAwait(false)); } if (user.Configuration.DisplayFoldersView) diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 9f87483baa..0b45c468a5 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Server.Implementations.Persistence innerProgress = new ActionableProgress(); innerProgress.RegisterAction(p => progress.Report(95 + (.05 * p))); - //await CleanDeadItems(cancellationToken, innerProgress).ConfigureAwait(false); + await CleanDeadItems(cancellationToken, innerProgress).ConfigureAwait(false); progress.Report(100); } @@ -77,6 +77,12 @@ namespace MediaBrowser.Server.Implementations.Persistence { cancellationToken.ThrowIfCancellationRequested(); + if (itemId == Guid.Empty) + { + // Somehow some invalid data got into the db. It probably predates the boundary checking + continue; + } + var item = _libraryManager.GetItemById(itemId); if (item != null) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 8abd591e5a..5d713e5a02 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1852,9 +1852,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1873,9 +1870,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From fa3290a5d3990b907bed94328481e8bbf5a7dd06 Mon Sep 17 00:00:00 2001 From: Eric Reed Date: Thu, 3 Sep 2015 08:43:46 -0400 Subject: [PATCH 008/212] Handle unrecognized ratings properly --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 570d566540..d9d334ff27 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1106,7 +1106,7 @@ namespace MediaBrowser.Controller.Entities // Could not determine the integer value if (!value.HasValue) { - return true; + return !GetBlockUnratedValue(user.Policy); } return value.Value <= maxAllowedRating.Value; From 37958b7835a04f029aa80233a258d5aeb82ba30d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Sep 2015 12:39:24 -0400 Subject: [PATCH 009/212] start to rework music tabs --- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 5d377366a0..bfaa1f289c 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -109,7 +109,7 @@ namespace MediaBrowser.Api.Playback.Hls throw; } - await WaitForMinimumSegmentCount(playlist, 3, cancellationTokenSource.Token).ConfigureAwait(false); + await WaitForMinimumSegmentCount(playlist, 1, cancellationTokenSource.Token).ConfigureAwait(false); } } finally diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5d713e5a02..a1c08e481c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1846,9 +1846,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1882,9 +1879,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From c0245d332dd66f13057a25ac56204e885602ab77 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Sep 2015 14:07:33 -0400 Subject: [PATCH 010/212] update web project --- 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 a1c08e481c..563e3e7901 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1840,9 +1840,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From cfd3248af7b51e308e9d3600cf2cfb8a460bf786 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Sep 2015 15:04:29 -0400 Subject: [PATCH 011/212] update music tabs --- .../MediaBrowser.WebDashboard.csproj | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 563e3e7901..0bb11bbf8e 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -784,9 +784,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1840,10 +1837,7 @@ PreserveNewest - - PreserveNewest - - + PreserveNewest From 0b2c5fe6f44259af0b573073a26c5eb1c6b821d1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Sep 2015 21:34:57 -0400 Subject: [PATCH 012/212] fix scheduled task crash --- .../ScheduledTasks/TaskManager.cs | 22 +++++++++++++++---- MediaBrowser.Controller/Entities/BaseItem.cs | 4 ++++ .../LiveTv/EmbyTV/EmbyTV.cs | 21 ++++++++++++------ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs index de7987bd22..7034113d7c 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -106,9 +106,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void QueueScheduledTask(TaskExecutionOptions options) where T : IScheduledTask { - var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T)); - QueueScheduledTask(scheduledTask, options); + if (scheduledTask == null) + { + Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name); + } + else + { + QueueScheduledTask(scheduledTask, options); + } } public void QueueScheduledTask() @@ -124,9 +131,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The task options. public void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options) { - var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == task.GetType()); + var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == task.GetType()); - QueueScheduledTask(scheduledTask, options); + if (scheduledTask == null) + { + Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name); + } + else + { + QueueScheduledTask(scheduledTask, options); + } } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d9d334ff27..f74a8bda7d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -500,6 +500,10 @@ namespace MediaBrowser.Controller.Entities return null; } + set + { + + } } public void SetParent(Folder parent) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 66ef209280..1786d14e47 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -618,6 +618,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger.ErrorException("Error recording", ex); recording.Status = RecordingStatus.Error; } + finally + { + CancellationTokenSource removed; + _activeRecordings.TryRemove(timer.Id, out removed); + } recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.Update(recording); @@ -627,15 +632,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV OnSuccessfulRecording(recording); _timerProvider.Delete(timer); } + else if (DateTime.UtcNow < timer.EndDate) + { + const int retryIntervalSeconds = 60; + _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); + + _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); + } else { - if (DateTime.UtcNow < timer.EndDate) - { - const int retryIntervalSeconds = 60; - _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); - - _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); - } + _timerProvider.Delete(timer); + _recordingProvider.Delete(recording); } } From 3d04b2566a1a60d1bb4130854816b3829d46c176 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 4 Sep 2015 12:20:54 -0400 Subject: [PATCH 013/212] fix now playing background --- MediaBrowser.Server.Implementations/Sync/MediaSync.cs | 9 ++++++++- .../MediaBrowser.WebDashboard.csproj | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs index 86ef58e425..83dd13c05d 100644 --- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs +++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs @@ -147,7 +147,14 @@ namespace MediaBrowser.Server.Implementations.Sync progress.Report(totalProgress); }); - await GetItem(provider, dataProvider, target, serverId, serverName, jobItem, innerProgress, cancellationToken).ConfigureAwait(false); + try + { + await GetItem(provider, dataProvider, target, serverId, serverName, jobItem, innerProgress, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error syncing item", ex); + } numComplete++; startingPercent = numComplete; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 0bb11bbf8e..b42b8fde18 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -330,6 +330,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest From 5cf3d3744ff53b53cfa2054f3a2c417498628834 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Sep 2015 12:58:27 -0400 Subject: [PATCH 014/212] update jqm --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index b42b8fde18..ff7457effe 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -330,6 +330,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest From f559c1fd50b9ef28ecd893fdb7eb520e7242290f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Sep 2015 13:25:22 -0400 Subject: [PATCH 015/212] 3.0.5724.4 --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 3bb674230b..36853f5e27 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5724.3")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5724.4")] From 462bec451f5ef8977d6c61f14843ef49ef616cce Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Sep 2015 13:43:53 -0400 Subject: [PATCH 016/212] update version --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index 36853f5e27..3bb5b51cd4 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5724.4")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5724.4")] From 27431b888cbf9dc0c554f44cfa6b56398083157e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Sep 2015 14:05:29 -0400 Subject: [PATCH 017/212] strip out jqm panel --- .../MediaBrowser.WebDashboard.csproj | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index ff7457effe..f6811724f8 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -342,6 +342,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -360,21 +366,12 @@ PreserveNewest - - PreserveNewest - PreserveNewest - - PreserveNewest - PreserveNewest - - PreserveNewest - PreserveNewest @@ -1765,9 +1762,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 74c1e8e12afa3b163dd1c936d8b3145817d25a6d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 5 Sep 2015 17:15:36 -0400 Subject: [PATCH 018/212] update bitrate detection --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 9f95953cf9..15770c3289 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -274,7 +274,7 @@ namespace MediaBrowser.Model.Configuration PeopleMetadataOptions = new PeopleMetadataOptions(); EnableVideoFrameAnalysis = true; - VideoFrameAnalysisLimitBytes = 600000000; + VideoFrameAnalysisLimitBytes = 800000000; InsecureApps9 = new[] { From 04aa4965c6eaa9f4068a964058cbb1fac460256c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 6 Sep 2015 00:53:37 -0400 Subject: [PATCH 019/212] update path fields --- .../Playback/Hls/BaseHlsService.cs | 25 ------ .../Playback/Hls/DynamicHlsService.cs | 25 ++++++ .../LiveTv/EmbyTV/EmbyTV.cs | 86 ++++++++++++++++++- .../LiveTv/Listings/SchedulesDirect.cs | 10 +-- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 4 +- 5 files changed, 113 insertions(+), 37 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index bfaa1f289c..d7af675aa0 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -312,31 +312,6 @@ namespace MediaBrowser.Api.Playback.Hls return 0; } - protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) - { - if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) - { - Logger.Debug("Cannot stream copy video due to missing keyframe info"); - return false; - } - - var previousSegment = 0; - foreach (var frame in videoStream.KeyFrames) - { - var length = frame - previousSegment; - - // Don't allow really long segments because this could result in long download times - if (length > 10000) - { - Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); - return false; - } - previousSegment = frame; - } - - return base.CanStreamCopyVideo(request, videoStream); - } - protected override bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List supportedAudioCodecs) { return false; diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index cbea1ca0ca..0353508f10 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -960,5 +960,30 @@ namespace MediaBrowser.Api.Playback.Hls { return isOutputVideo ? ".ts" : ".ts"; } + + protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + { + if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) + { + Logger.Debug("Cannot stream copy video due to missing keyframe info"); + return false; + } + + var previousSegment = 0; + foreach (var frame in videoStream.KeyFrames) + { + var length = frame - previousSegment; + + // Don't allow really long segments because this could result in long download times + if (length > 10000) + { + Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); + return false; + } + previousSegment = frame; + } + + return base.CanStreamCopyVideo(request, videoStream); + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1786d14e47..c5edb212b4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -8,7 +8,9 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; @@ -47,10 +49,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly IFileOrganizationService _organizationService; + private readonly IMediaEncoder _mediaEncoder; 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) + 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) { Current = this; @@ -64,6 +67,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _libraryMonitor = libraryMonitor; _providerManager = providerManager; _organizationService = organizationService; + _mediaEncoder = mediaEncoder; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; @@ -428,6 +432,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (mediaSourceInfo != null) { + await AddMediaInfo(mediaSourceInfo, false, cancellationToken).ConfigureAwait(false); + mediaSourceInfo.Id = Guid.NewGuid().ToString("N"); return mediaSourceInfo; } @@ -458,6 +464,84 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV throw new NotImplementedException(); } + private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) + { + var originalRuntime = mediaSource.RunTimeTicks; + + var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest + { + InputPath = mediaSource.Path, + Protocol = mediaSource.Protocol, + MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, + ExtractChapters = false + + }, cancellationToken).ConfigureAwait(false); + + mediaSource.Bitrate = info.Bitrate; + mediaSource.Container = info.Container; + mediaSource.Formats = info.Formats; + mediaSource.MediaStreams = info.MediaStreams; + mediaSource.RunTimeTicks = info.RunTimeTicks; + mediaSource.Size = info.Size; + mediaSource.Timestamp = info.Timestamp; + mediaSource.Video3DFormat = info.Video3DFormat; + mediaSource.VideoType = info.VideoType; + + mediaSource.DefaultSubtitleStreamIndex = null; + + // Null this out so that it will be treated like a live stream + if (!originalRuntime.HasValue) + { + mediaSource.RunTimeTicks = null; + } + + var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio); + + if (audioStream == null || audioStream.Index == -1) + { + mediaSource.DefaultAudioStreamIndex = null; + } + else + { + mediaSource.DefaultAudioStreamIndex = audioStream.Index; + } + + var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video); + if (videoStream != null) + { + if (!videoStream.BitRate.HasValue) + { + var width = videoStream.Width ?? 1920; + + if (width >= 1900) + { + videoStream.BitRate = 8000000; + } + + else if (width >= 1260) + { + videoStream.BitRate = 3000000; + } + + else if (width >= 700) + { + videoStream.BitRate = 1000000; + } + } + } + + // Try to estimate this + if (!mediaSource.Bitrate.HasValue) + { + var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); + + if (total > 0) + { + mediaSource.Bitrate = total; + } + } + } + public Task> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) { throw new NotImplementedException(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index d53c081500..b96aa52264 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -216,20 +216,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings // Helper.logger.Info("Modifyin channel " + channel.Number); if (_channelPair.ContainsKey(channel.Number)) { - string channelName; if (_channelPair[channel.Number].logo != null) { channel.ImageUrl = _channelPair[channel.Number].logo.URL; channel.HasImage = true; } - if (_channelPair[channel.Number].affiliate != null) - { - channelName = _channelPair[channel.Number].affiliate; - } - else - { - channelName = _channelPair[channel.Number].name; - } + string channelName = _channelPair[channel.Number].name; channel.Name = channelName; } else diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index bccb0db0a0..02b3080e47 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -325,8 +325,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun BitRate = 128000 } }, - RequiresOpening = false, - RequiresClosing = false, + RequiresOpening = true, + RequiresClosing = true, BufferMs = 1000, Container = "ts", Id = profile From b7af1213a48ab3203a247295b3b055bbb30c90e4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 6 Sep 2015 12:02:41 -0400 Subject: [PATCH 020/212] fix auto organize --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- .../Manager/ProviderManager.cs | 20 ++++++++++--------- .../MediaBrowser.WebDashboard.csproj | 6 ++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f74a8bda7d..5d054c3b9d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -183,7 +183,7 @@ namespace MediaBrowser.Controller.Entities { // Local trailer, special feature, theme video, etc. // An item that belongs to another item but is not part of the Parent-Child tree - return !IsFolder && Parent == null && LocationType == LocationType.FileSystem; + return !IsFolder && ParentId == Guid.Empty && LocationType == LocationType.FileSystem; } } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index fe0e4890c2..4a846b4cee 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -283,17 +283,17 @@ namespace MediaBrowser.Providers.Manager { var options = GetMetadataOptions(item); - return GetMetadataProvidersInternal(item, options, false); + return GetMetadataProvidersInternal(item, options, false, true); } - private IEnumerable> GetMetadataProvidersInternal(IHasMetadata item, MetadataOptions options, bool includeDisabled) + private IEnumerable> GetMetadataProvidersInternal(IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem) where T : IHasMetadata { // Avoid implicitly captured closure var currentOptions = options; return _metadataProviders.OfType>() - .Where(i => CanRefresh(i, item, currentOptions, includeDisabled)) + .Where(i => CanRefresh(i, item, currentOptions, includeDisabled, checkIsOwnedItem)) .OrderBy(i => GetConfiguredOrder(i, options)) .ThenBy(GetDefaultOrder); } @@ -318,7 +318,7 @@ namespace MediaBrowser.Providers.Manager return GetImageProviders(item, options, includeDisabled).OfType(); } - private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled) + private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem) { if (!includeDisabled) { @@ -348,7 +348,7 @@ namespace MediaBrowser.Providers.Manager } // If this restriction is ever lifted, movie xml providers will have to be updated to prevent owned items like trailers from reading those files - if (item.IsOwnedItem) + if (checkIsOwnedItem && item.IsOwnedItem) { if (provider is ILocalMetadataProvider || provider is IRemoteMetadataProvider) { @@ -491,7 +491,8 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new T() { - Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy") + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), + ParentId = Guid.NewGuid() }; dummy.SetParent(new Folder()); @@ -523,7 +524,7 @@ namespace MediaBrowser.Providers.Manager private void AddMetadataPlugins(List list, T item, MetadataOptions options) where T : IHasMetadata { - var providers = GetMetadataProvidersInternal(item, options, true).ToList(); + var providers = GetMetadataProvidersInternal(item, options, true, false).ToList(); // Locals list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin @@ -732,14 +733,15 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new TItemType { - Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy") + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), + ParentId = Guid.NewGuid() }; dummy.SetParent(new Folder()); var options = GetMetadataOptions(dummy); - var providers = GetMetadataProvidersInternal(dummy, options, searchInfo.IncludeDisabledProviders) + var providers = GetMetadataProvidersInternal(dummy, options, searchInfo.IncludeDisabledProviders, false) .OfType>(); if (!string.IsNullOrEmpty(searchInfo.SearchProviderName)) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index f6811724f8..24450b1707 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -336,6 +336,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest From ff33ebbe73f778fa18d5077370b2280acb2c0d50 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 6 Sep 2015 12:11:41 -0400 Subject: [PATCH 021/212] isolate jqm checkbox --- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 24450b1707..552edf97ea 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -330,6 +330,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -366,6 +369,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 046eaa76716f5167a56d25dd354038541fba5845 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 7 Sep 2015 11:54:57 -0400 Subject: [PATCH 022/212] update translations --- .../Playback/Hls/DynamicHlsService.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 0353508f10..7b2844cd4b 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -285,20 +285,23 @@ namespace MediaBrowser.Api.Playback.Hls private double[] GetSegmentLengths(StreamState state) { var result = new List(); - var encoder = GetVideoEncoder(state); - - if (string.Equals(encoder, "copy", StringComparison.OrdinalIgnoreCase)) + if (state.VideoRequest != null) { - var videoStream = state.VideoStream; - if (videoStream.KeyFrames != null && videoStream.KeyFrames.Count > 0) + var encoder = GetVideoEncoder(state); + + if (string.Equals(encoder, "copy", StringComparison.OrdinalIgnoreCase)) { - foreach (var frame in videoStream.KeyFrames) + var videoStream = state.VideoStream; + if (videoStream.KeyFrames != null && videoStream.KeyFrames.Count > 0) { - var seconds = TimeSpan.FromMilliseconds(frame).TotalSeconds; - seconds -= result.Sum(); - result.Add(seconds); + foreach (var frame in videoStream.KeyFrames) + { + var seconds = TimeSpan.FromMilliseconds(frame).TotalSeconds; + seconds -= result.Sum(); + result.Add(seconds); + } + return result.ToArray(); } - return result.ToArray(); } } From 976a4c22da626677c8961fe30ee3ff3b1841bff7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 7 Sep 2015 21:00:46 -0400 Subject: [PATCH 023/212] update live tv segments --- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index d7af675aa0..eb5c6c95eb 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -109,7 +109,7 @@ namespace MediaBrowser.Api.Playback.Hls throw; } - await WaitForMinimumSegmentCount(playlist, 1, cancellationTokenSource.Token).ConfigureAwait(false); + await WaitForMinimumSegmentCount(playlist, 2, cancellationTokenSource.Token).ConfigureAwait(false); } } finally From 29caf70fee5222393df8c6e1afb7d8f6e6f5d6f6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 8 Sep 2015 16:40:48 -0400 Subject: [PATCH 024/212] limit videos for keyframe extraction --- .../Encoder/MediaEncoder.cs | 29 +++++++++++++++---- .../MediaBrowser.WebDashboard.csproj | 3 ++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 503399f8db..8eaf0a78eb 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Session; using MediaBrowser.MediaEncoding.Probing; using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; @@ -247,10 +248,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { foreach (var stream in mediaInfo.MediaStreams) { - if (stream.Type == MediaStreamType.Video && - string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && - !stream.IsInterlaced && - !(stream.IsAnamorphic ?? false)) + if (EnableKeyframeExtraction(mediaInfo, stream)) { try { @@ -287,6 +285,25 @@ namespace MediaBrowser.MediaEncoding.Encoder throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); } + private bool EnableKeyframeExtraction(MediaSourceInfo mediaSource, MediaStream videoStream) + { + if (videoStream.Type == MediaStreamType.Video && string.Equals(videoStream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && + !videoStream.IsInterlaced && + !(videoStream.IsAnamorphic ?? false)) + { + var audioStreams = mediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio).ToList(); + + // If it has aac audio then it will probably direct stream anyway, so don't bother with this + if (audioStreams.Count == 1 && string.Equals(audioStreams[0].Codec, "aac", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return true; + } + return false; + } + private async Task> GetKeyFrames(string inputPath, int videoStreamIndex, CancellationToken cancellationToken) { inputPath = inputPath.Split(new[] { ':' }, 2).Last().Trim('"'); @@ -313,7 +330,7 @@ namespace MediaBrowser.MediaEncoding.Encoder EnableRaisingEvents = true }; - _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); using (process) { @@ -339,7 +356,7 @@ namespace MediaBrowser.MediaEncoding.Encoder process.WaitForExit(); - _logger.Debug("Keyframe extraction took {0} seconds", (DateTime.UtcNow - start).TotalSeconds); + _logger.Info("Keyframe extraction took {0} seconds", (DateTime.UtcNow - start).TotalSeconds); //_logger.Debug("Found keyframes {0}", string.Join(",", lines.ToArray())); return lines; } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 552edf97ea..ac3437892c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -2649,6 +2649,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 0d45ab8d647aebd929b638c43712cba4fa18db30 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 8 Sep 2015 17:03:31 -0400 Subject: [PATCH 025/212] adjust default settings --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 +- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 8eaf0a78eb..f8836ada99 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) { - if (ConfigurationManager.Configuration.EnableVideoFrameAnalysis && mediaInfo.Size.HasValue && mediaInfo.Size.Value <= ConfigurationManager.Configuration.VideoFrameAnalysisLimitBytes) + if (ConfigurationManager.Configuration.EnableVideoFrameByFrameAnalysis && mediaInfo.Size.HasValue) { foreach (var stream in mediaInfo.MediaStreams) { diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 15770c3289..0bf73eba12 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -222,8 +222,7 @@ namespace MediaBrowser.Model.Configuration public bool DisableXmlSavers { get; set; } public bool EnableWindowsShortcuts { get; set; } - public bool EnableVideoFrameAnalysis { get; set; } - public long VideoFrameAnalysisLimitBytes { get; set; } + public bool EnableVideoFrameByFrameAnalysis { get; set; } /// /// Initializes a new instance of the class. @@ -273,8 +272,7 @@ namespace MediaBrowser.Model.Configuration PeopleMetadataOptions = new PeopleMetadataOptions(); - EnableVideoFrameAnalysis = true; - VideoFrameAnalysisLimitBytes = 800000000; + EnableVideoFrameByFrameAnalysis = false; InsecureApps9 = new[] { From 38ff6565c68f7bec245ab84a324c6ea2e690abb1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 9 Sep 2015 13:49:44 -0400 Subject: [PATCH 026/212] update sync processes --- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- MediaBrowser.Api/Playback/StreamState.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 - .../MediaBrowser.WebDashboard.csproj | 15 ++++++++++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index eb5c6c95eb..e4f00e2a08 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -109,7 +109,7 @@ namespace MediaBrowser.Api.Playback.Hls throw; } - await WaitForMinimumSegmentCount(playlist, 2, cancellationTokenSource.Token).ConfigureAwait(false); + await WaitForMinimumSegmentCount(playlist, 3, cancellationTokenSource.Token).ConfigureAwait(false); } } finally diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 34dc5ea12f..fdbe5835ef 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Api.Playback { get { - return ReadInputAtNativeFramerate ? 1000 : 0; + return 0; } } diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 48ad62bd49..6dac90c1f2 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -521,7 +521,6 @@ namespace MediaBrowser.WebDashboard.Api "thirdparty/jquery.unveil-custom.js", "apiclient/logger.js", "apiclient/md5.js", - "apiclient/sha1.js", "apiclient/store.js", "apiclient/device.js", "apiclient/credentials.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index ac3437892c..7de14dac17 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -87,6 +87,15 @@ + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -150,6 +159,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -527,9 +539,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From ce0435a66d98be8519a0c6e438674caf3badc076 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 9 Sep 2015 23:22:52 -0400 Subject: [PATCH 027/212] add movie resolver fix --- .../Playback/Progressive/VideoService.cs | 1 + .../Reports/Stat/ReportStatBuilder.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 8 +--- .../LiveTv/LiveTvAudioRecording.cs | 3 ++ .../LiveTv/LiveTvProgram.cs | 3 ++ .../LiveTv/LiveTvVideoRecording.cs | 3 ++ .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/Movies/MovieResolver.cs | 26 +++++++----- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 5 ++- .../Persistence/SqliteItemRepository.cs | 40 +++++++++++++++++-- .../MediaBrowser.WebDashboard.csproj | 9 +++++ 11 files changed, 80 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 84ae26248f..1dfb433879 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -17,6 +17,7 @@ namespace MediaBrowser.Api.Playback.Progressive /// /// Class GetVideoStream /// + [Route("/Videos/{Id}/stream.mpegts", "GET")] [Route("/Videos/{Id}/stream.ts", "GET")] [Route("/Videos/{Id}/stream.webm", "GET")] [Route("/Videos/{Id}/stream.asf", "GET")] diff --git a/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs index c9ee6337ff..fb694d6e13 100644 --- a/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs +++ b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs @@ -213,7 +213,7 @@ namespace MediaBrowser.Api.Reports }; foreach (var item in t) { - var ps = items.Where(x => x.People != null && x.SupportsPeople).SelectMany(x => x.People) + var ps = items.SelectMany(x => _libraryManager.GetPeople(x)) .Where(n => n.Type == item.ToString()) .GroupBy(x => x.Name) .OrderByDescending(x => x.Count()) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 5d054c3b9d..6d0a270da6 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -62,6 +62,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the channel identifier. /// /// The channel identifier. + [IgnoreDataMember] public string ChannelId { get; set; } [IgnoreDataMember] @@ -554,6 +555,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the end date. /// /// The end date. + [IgnoreDataMember] public DateTime? EndDate { get; set; } /// @@ -586,12 +588,6 @@ namespace MediaBrowser.Controller.Entities /// The overview. public string Overview { get; set; } - /// - /// Gets or sets the people. - /// - /// The people. - public List People { get; set; } - /// /// Gets or sets the studios. /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 2179c5ecd7..28f6deafaf 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -22,10 +22,13 @@ namespace MediaBrowser.Controller.LiveTv public string SeriesTimerId { get; set; } public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } + [IgnoreDataMember] public bool IsSports { get; set; } public bool IsNews { get; set; } + [IgnoreDataMember] public bool IsKids { get; set; } public bool IsRepeat { get; set; } + [IgnoreDataMember] public bool IsMovie { get; set; } public bool? IsHD { get; set; } public bool IsLive { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 12052905f2..937234b177 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -110,12 +110,14 @@ namespace MediaBrowser.Controller.LiveTv /// Gets or sets a value indicating whether this instance is movie. /// /// true if this instance is movie; otherwise, false. + [IgnoreDataMember] public bool IsMovie { get; set; } /// /// Gets or sets a value indicating whether this instance is sports. /// /// true if this instance is sports; otherwise, false. + [IgnoreDataMember] public bool IsSports { get; set; } /// @@ -140,6 +142,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets or sets a value indicating whether this instance is kids. /// /// true if this instance is kids; otherwise, false. + [IgnoreDataMember] public bool IsKids { get; set; } /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 960f8054a1..7688691090 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -22,10 +22,13 @@ namespace MediaBrowser.Controller.LiveTv public string SeriesTimerId { get; set; } public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } + [IgnoreDataMember] public bool IsSports { get; set; } public bool IsNews { get; set; } + [IgnoreDataMember] public bool IsKids { get; set; } public bool IsRepeat { get; set; } + [IgnoreDataMember] public bool IsMovie { get; set; } public bool? IsHD { get; set; } public bool IsLive { get; set; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index cc9d9551c2..c8f4725368 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2181,7 +2181,7 @@ namespace MediaBrowser.Server.Implementations.Library } } - return item.People ?? new List(); + return new List(); } public List GetPeopleItems(InternalPeopleQuery query) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 0d1e4202ca..d9f23977cf 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -309,20 +309,26 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies //we need to only look at the name of this actual item (not parents) var justName = item.IsInMixedFolder ? Path.GetFileName(item.Path) : Path.GetFileName(item.ContainingFolderPath); - // check for tmdb id - var tmdbid = justName.GetAttributeValue("tmdbid"); - - if (!string.IsNullOrEmpty(tmdbid)) + if (!string.IsNullOrWhiteSpace(justName)) { - item.SetProviderId(MetadataProviders.Tmdb, tmdbid); + // check for tmdb id + var tmdbid = justName.GetAttributeValue("tmdbid"); + + if (!string.IsNullOrWhiteSpace(tmdbid)) + { + item.SetProviderId(MetadataProviders.Tmdb, tmdbid); + } } - // check for imdb id - we use full media path, as we can assume, that this will match in any use case (wither id in parent dir or in file name) - var imdbid = item.Path.GetAttributeValue("imdbid"); - - if (!string.IsNullOrEmpty(imdbid)) + if (!string.IsNullOrWhiteSpace(item.Path)) { - item.SetProviderId(MetadataProviders.Imdb, imdbid); + // check for imdb id - we use full media path, as we can assume, that this will match in any use case (wither id in parent dir or in file name) + var imdbid = item.Path.GetAttributeValue("imdbid"); + + if (!string.IsNullOrWhiteSpace(imdbid)) + { + item.SetProviderId(MetadataProviders.Imdb, imdbid); + } } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 02b3080e47..bc6ed47ad6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -329,7 +329,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun RequiresClosing = true, BufferMs = 1000, Container = "ts", - Id = profile + Id = profile, + SupportsDirectPlay = true, + SupportsDirectStream = false, + SupportsTranscoding = true }; return mediaSource; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 00ebf7ea6e..86b4e7d1cb 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -187,11 +187,16 @@ namespace MediaBrowser.Server.Implementations.Persistence /// private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1); - private string[] _retriveItemColumns = + private readonly string[] _retriveItemColumns = { "type", "data", - "IsOffline" + "EndDate", + "IsOffline", + "ChannelId", + "IsMovie", + "IsSports", + "IsKids" }; /// @@ -511,7 +516,36 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(2)) { - item.IsOffline = reader.GetBoolean(2); + item.EndDate = reader.GetDateTime(2).ToUniversalTime(); + } + + if (!reader.IsDBNull(3)) + { + item.IsOffline = reader.GetBoolean(3); + } + + if (!reader.IsDBNull(4)) + { + item.ChannelId = reader.GetString(4); + } + + var hasProgramAttributes = item as IHasProgramAttributes; + if (hasProgramAttributes != null) + { + if (!reader.IsDBNull(5)) + { + hasProgramAttributes.IsMovie = reader.GetBoolean(5); + } + + if (!reader.IsDBNull(6)) + { + hasProgramAttributes.IsSports = reader.GetBoolean(6); + } + + if (!reader.IsDBNull(7)) + { + hasProgramAttributes.IsKids = reader.GetBoolean(7); + } } return item; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 7de14dac17..91a438ff75 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,9 +90,15 @@ PreserveNewest + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest @@ -159,6 +165,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From baf2f801549a284501ee836053aa113adf5b1503 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 10 Sep 2015 14:28:22 -0400 Subject: [PATCH 028/212] update camera upload --- MediaBrowser.Api/Devices/DeviceService.cs | 35 ++++++++++++++----- .../ScheduledTasks/IntervalTrigger.cs | 2 +- .../LiveTv/LiveTvAudioRecording.cs | 1 + .../LiveTv/LiveTvProgram.cs | 1 + .../LiveTv/LiveTvVideoRecording.cs | 1 + .../Providers/MetadataStatus.cs | 8 ++--- MediaBrowser.Model/Net/MimeTypes.cs | 2 +- .../Manager/MetadataService.cs | 20 +++++++++-- .../Devices/DeviceManager.cs | 6 ++-- .../LiveTv/EmbyTV/EmbyTV.cs | 14 ++++++++ .../TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 30 ++++++++++------ .../MediaBrowser.WebDashboard.csproj | 6 ++++ 13 files changed, 98 insertions(+), 30 deletions(-) diff --git a/MediaBrowser.Api/Devices/DeviceService.cs b/MediaBrowser.Api/Devices/DeviceService.cs index ab0a4a4b2a..759eea3537 100644 --- a/MediaBrowser.Api/Devices/DeviceService.cs +++ b/MediaBrowser.Api/Devices/DeviceService.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Devices; +using System; +using System.Linq; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Devices; using MediaBrowser.Model.Querying; @@ -128,15 +130,32 @@ namespace MediaBrowser.Api.Devices var id = Request.QueryString["Id"]; var name = Request.QueryString["Name"]; - var task = _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo + if (Request.ContentType.IndexOf("multi", StringComparison.OrdinalIgnoreCase) == -1) { - MimeType = Request.ContentType, - Album = album, - Name = name, - Id = id - }); + var task = _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo + { + MimeType = Request.ContentType, + Album = album, + Name = name, + Id = id + }); - Task.WaitAll(task); + Task.WaitAll(task); + } + else + { + var file = Request.Files.First(); + + var task = _deviceManager.AcceptCameraUpload(deviceId, file.InputStream, new LocalFileInfo + { + MimeType = file.ContentType, + Album = album, + Name = name, + Id = id + }); + + Task.WaitAll(task); + } } } } diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index b615adf816..42871866df 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Common.ScheduledTasks { if (isApplicationStartup) { - triggerDate = DateTime.UtcNow.AddMinutes(5); + triggerDate = DateTime.UtcNow.AddMinutes(2); } else { diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 28f6deafaf..1be04bb7cb 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.LiveTv public string EpisodeTitle { get; set; } public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 937234b177..0f7d0a6cee 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -56,6 +56,7 @@ namespace MediaBrowser.Controller.LiveTv /// /// The start date of the program, in UTC. /// + [IgnoreDataMember] public DateTime StartDate { get; set; } /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 7688691090..a26d8b402b 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.LiveTv public string EpisodeTitle { get; set; } public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Providers/MetadataStatus.cs b/MediaBrowser.Controller/Providers/MetadataStatus.cs index 283b9edbc2..f395dabf19 100644 --- a/MediaBrowser.Controller/Providers/MetadataStatus.cs +++ b/MediaBrowser.Controller/Providers/MetadataStatus.cs @@ -78,9 +78,9 @@ namespace MediaBrowser.Controller.Providers public bool IsDirty { get; private set; } - public void SetDateLastMetadataRefresh(DateTime date) + public void SetDateLastMetadataRefresh(DateTime? date) { - if (date != (DateLastMetadataRefresh ?? DateTime.MinValue)) + if (date != DateLastMetadataRefresh) { IsDirty = true; } @@ -88,9 +88,9 @@ namespace MediaBrowser.Controller.Providers DateLastMetadataRefresh = date; } - public void SetDateLastImagesRefresh(DateTime date) + public void SetDateLastImagesRefresh(DateTime? date) { - if (date != (DateLastImagesRefresh ?? DateTime.MinValue)) + if (date != DateLastImagesRefresh) { IsDirty = true; } diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index efa5a5217a..e905af58da 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -318,7 +318,7 @@ namespace MediaBrowser.Model.Net { return result; } - throw new ArgumentNullException("Unable to determine extension for mimeType: " + mimeType); + return null; } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index cddc6f8942..8a60ea78f9 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -147,7 +147,14 @@ namespace MediaBrowser.Providers.Manager updateType = updateType | result.UpdateType; refreshResult.AddStatus(result.Status, result.ErrorMessage); - refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow); + if (result.Failures == 0) + { + refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow); + } + else + { + refreshResult.SetDateLastMetadataRefresh(null); + } MergeIdentities(itemOfType, id); } @@ -164,7 +171,14 @@ namespace MediaBrowser.Providers.Manager updateType = updateType | result.UpdateType; refreshResult.AddStatus(result.Status, result.ErrorMessage); - refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow); + if (result.Failures == 0) + { + refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow); + } + else + { + refreshResult.SetDateLastImagesRefresh(null); + } } } @@ -503,7 +517,7 @@ namespace MediaBrowser.Providers.Manager { return false; } - + return true; } diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index 04337dda6a..0173f27847 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Devices; using MediaBrowser.Model.Events; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Session; using MediaBrowser.Model.Users; @@ -151,12 +152,13 @@ namespace MediaBrowser.Server.Implementations.Devices path = Path.Combine(path, _fileSystem.GetValidFilename(file.Album)); } - Directory.CreateDirectory(path); - path = Path.Combine(path, file.Name); + path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg"); _libraryMonitor.ReportFileSystemChangeBeginning(path); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + try { using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c5edb212b4..fb58248057 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -369,6 +369,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } public async Task> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + try + { + return await GetProgramsAsyncInternal(channelId, startDateUtc, endDateUtc, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting programs", ex); + return GetEpgDataForChannel(channelId).Where(i => i.StartDate <= endDateUtc && i.EndDate >= startDateUtc); + } + } + + private async Task> GetProgramsAsyncInternal(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false); var channel = channels.First(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase)); @@ -377,6 +390,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, startDateUtc, endDateUtc, cancellationToken) .ConfigureAwait(false); + var list = programs.ToList(); // Replace the value that came from the provider with a normalized value diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index bc6ed47ad6..c16d044b74 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -331,7 +331,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun Container = "ts", Id = profile, SupportsDirectPlay = true, - SupportsDirectStream = false, + SupportsDirectStream = true, SupportsTranscoding = true }; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 86b4e7d1cb..9fa650bdf6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -191,6 +191,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { "type", "data", + "StartDate", "EndDate", "IsOffline", "ChannelId", @@ -516,35 +517,44 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(2)) { - item.EndDate = reader.GetDateTime(2).ToUniversalTime(); + var hasStartDate = item as IHasStartDate; + if (hasStartDate != null) + { + hasStartDate.StartDate = reader.GetDateTime(2).ToUniversalTime(); + } } if (!reader.IsDBNull(3)) { - item.IsOffline = reader.GetBoolean(3); + item.EndDate = reader.GetDateTime(3).ToUniversalTime(); } if (!reader.IsDBNull(4)) { - item.ChannelId = reader.GetString(4); + item.IsOffline = reader.GetBoolean(4); + } + + if (!reader.IsDBNull(5)) + { + item.ChannelId = reader.GetString(5); } var hasProgramAttributes = item as IHasProgramAttributes; if (hasProgramAttributes != null) { - if (!reader.IsDBNull(5)) - { - hasProgramAttributes.IsMovie = reader.GetBoolean(5); - } - if (!reader.IsDBNull(6)) { - hasProgramAttributes.IsSports = reader.GetBoolean(6); + hasProgramAttributes.IsMovie = reader.GetBoolean(6); } if (!reader.IsDBNull(7)) { - hasProgramAttributes.IsKids = reader.GetBoolean(7); + hasProgramAttributes.IsSports = reader.GetBoolean(7); + } + + if (!reader.IsDBNull(8)) + { + hasProgramAttributes.IsKids = reader.GetBoolean(8); } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 91a438ff75..2ba831c3f2 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,6 +90,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -165,6 +168,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From cd5615c6ce4c4de44f7c9118d2ca0454fadd0868 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 11 Sep 2015 12:26:06 -0400 Subject: [PATCH 029/212] update client sync --- MediaBrowser.Controller/Entities/BaseItem.cs | 22 +++------------- .../Persistence/SqliteItemRepository.cs | 26 ++++++++++++++++++- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 6d0a270da6..54267490df 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -332,25 +332,8 @@ namespace MediaBrowser.Controller.Entities return Name; } - /// - /// Returns true if this item should not attempt to fetch metadata - /// - /// true if [dont fetch meta]; otherwise, false. - [Obsolete("Please use IsLocked instead of DontFetchMeta")] - public bool DontFetchMeta { get; set; } - [IgnoreDataMember] - public bool IsLocked - { - get - { - return DontFetchMeta; - } - set - { - DontFetchMeta = value; - } - } + public bool IsLocked { get; set; } public bool IsUnidentified { get; set; } @@ -580,6 +563,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the custom rating. /// /// The custom rating. + [IgnoreDataMember] public string CustomRating { get; set; } /// @@ -610,6 +594,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the community rating. /// /// The community rating. + [IgnoreDataMember] public float? CommunityRating { get; set; } /// @@ -635,6 +620,7 @@ namespace MediaBrowser.Controller.Entities /// This could be episode number, album track number, etc. /// /// The index number. + [IgnoreDataMember] public int? IndexNumber { get; set; } /// diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9fa650bdf6..5ad6449b3d 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -197,7 +197,11 @@ namespace MediaBrowser.Server.Implementations.Persistence "ChannelId", "IsMovie", "IsSports", - "IsKids" + "IsKids", + "CommunityRating", + "CustomRating", + "IndexNumber", + "IsLocked" }; /// @@ -558,6 +562,26 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (!reader.IsDBNull(9)) + { + item.CommunityRating = reader.GetFloat(9); + } + + if (!reader.IsDBNull(10)) + { + item.CustomRating = reader.GetString(10); + } + + if (!reader.IsDBNull(11)) + { + item.IndexNumber = reader.GetInt32(11); + } + + if (!reader.IsDBNull(12)) + { + item.IsLocked = reader.GetBoolean(12); + } + return item; } From dd17096b5d60e24f88f8f0c21227961d54587f6f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 11 Sep 2015 22:18:09 -0400 Subject: [PATCH 030/212] update libs --- MediaBrowser.Api/MediaBrowser.Api.csproj | 4 ++-- MediaBrowser.Api/packages.config | 2 +- .../BaseApplicationHost.cs | 4 ++-- .../Logging/NlogManager.cs | 2 +- .../MediaBrowser.Common.Implementations.csproj | 9 ++++----- MediaBrowser.Common.Implementations/packages.config | 4 ++-- .../MediaBrowser.Controller.csproj | 4 ++-- MediaBrowser.Controller/packages.config | 2 +- MediaBrowser.Providers/MediaBrowser.Providers.csproj | 4 ++-- MediaBrowser.Providers/packages.config | 2 +- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- .../MediaBrowser.WebDashboard.csproj | 11 +++++------ MediaBrowser.WebDashboard/packages.config | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 2 +- 15 files changed, 28 insertions(+), 30 deletions(-) diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 295cc78e93..7fa631e218 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -49,9 +49,9 @@ Always - + False - ..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll + ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index 6df1662040..0cdb26bd59 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 70ed5c3191..bfd8c1f823 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -581,7 +581,7 @@ namespace MediaBrowser.Common.Implementations protected void RegisterSingleInstance(T obj, bool manageLifetime = true) where T : class { - Container.RegisterSingle(obj); + Container.RegisterSingleton(obj); if (manageLifetime) { @@ -607,7 +607,7 @@ namespace MediaBrowser.Common.Implementations protected void RegisterSingleInstance(Func func) where T : class { - Container.RegisterSingle(func); + Container.RegisterSingleton(func); } void IDependencyContainer.Register(Type typeInterface, Type typeImplementation) diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs index 6987928026..6d4cd06cb4 100644 --- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs +++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs @@ -170,7 +170,7 @@ namespace MediaBrowser.Common.Implementations.Logging /// /// The name. /// ILogger. - public ILogger GetLogger(string name) + public Model.Logging.ILogger GetLogger(string name) { return new NLogger(name, this); } diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index e603ea3738..e765b1ca37 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -48,18 +48,17 @@ Always - + False - ..\packages\NLog.3.2.1\lib\net45\NLog.dll + ..\packages\NLog.4.1.0\lib\net45\NLog.dll False ..\ThirdParty\SharpCompress\SharpCompress.dll - + False - ..\packages\SimpleInjector.2.8.0\lib\net45\SimpleInjector.dll - True + ..\packages\SimpleInjector.3.0.5\lib\net45\SimpleInjector.dll diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index e57c874f2c..151a3a36d2 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,5 +1,5 @@  - - + + diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 24309734f8..f898f80156 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -51,9 +51,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll + ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config index 8846b5a064..c320ed9d9a 100644 --- a/MediaBrowser.Controller/packages.config +++ b/MediaBrowser.Controller/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 1d323e567b..1d12426b98 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -53,9 +53,9 @@ False ..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll - + False - ..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll + ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll ..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config index be21e92dcf..fe2b571a4f 100644 --- a/MediaBrowser.Providers/packages.config +++ b/MediaBrowser.Providers/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index f0312cef61..11dd7c28d5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -56,9 +56,9 @@ False ..\packages\Mono.Nat.1.2.24.0\lib\net40\Mono.Nat.dll - + False - ..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll + ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 92388c99e3..7587918685 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 2ba831c3f2..caed0f5e68 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -57,9 +57,8 @@ ..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll - - False - ..\packages\WebMarkupMin.Core.0.9.12\lib\net40\WebMarkupMin.Core.dll + + ..\packages\WebMarkupMin.Core.1.0.0\lib\net40\WebMarkupMin.Core.dll @@ -300,6 +299,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -1153,9 +1155,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 48f68789ba..cb5a323478 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index f92e054925..558f7f5ca3 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -14,7 +14,7 @@ - + From 0f743205c4835d828de9f28f6ab7d325209e83b2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 12 Sep 2015 12:39:24 -0400 Subject: [PATCH 031/212] update external subs --- Emby.Drawing/ImageProcessor.cs | 3 +++ MediaBrowser.Model/Dlna/StreamBuilder.cs | 12 +++++------- .../Library/MediaSourceManager.cs | 7 +++++-- .../Sync/SyncManager.cs | 5 ----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 970b463cd1..231bfa2b47 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -227,6 +227,9 @@ namespace Emby.Drawing imageProcessingLockTaken = true; _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options); + + // ImageMagick doesn't seem to always release it right away + await Task.Delay(100).ConfigureAwait(false); } } finally diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index e0cc1b705c..810d42a095 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -759,14 +759,12 @@ namespace MediaBrowser.Model.Dlna if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) { - if (!requiresConversion) + if (subtitleStream.IsTextSubtitleStream || !requiresConversion) { - return profile; - } - - if (subtitleStream.SupportsExternalStream) - { - return profile; + if (subtitleStream.SupportsExternalStream) + { + return profile; + } } // For sync we can handle the longer extraction times diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index e3ec99392f..63067bf5a5 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -127,9 +127,12 @@ namespace MediaBrowser.Server.Implementations.Library { var supportsExternalStream = StreamSupportsExternalStream(subStream); - if (supportsExternalStream && videoBitrate >= maxAllowedBitrateForExternalSubtitleStream) + if (!subStream.IsExternal) { - supportsExternalStream = false; + if (supportsExternalStream && videoBitrate >= maxAllowedBitrateForExternalSubtitleStream) + { + supportsExternalStream = false; + } } subStream.SupportsExternalStream = supportsExternalStream; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 18fcb4e794..f7a87dad5e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -539,11 +539,6 @@ namespace MediaBrowser.Server.Implementations.Sync return false; } - if (video.IsStacked) - { - return false; - } - if (video.IsShortcut) { return false; From 14de062681026157c6917779a51af6fb7046cec2 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 13 Sep 2015 17:32:02 -0400 Subject: [PATCH 032/212] update file system methods --- Emby.Drawing/Common/ImageHeader.cs | 2 +- Emby.Drawing/GDI/GDIImageEncoder.cs | 4 +- .../ImageMagick/ImageMagickEncoder.cs | 11 +- .../ImageMagick/PlayedIndicatorDrawer.cs | 27 +-- .../ImageMagick/StripCollageBuilder.cs | 7 +- .../ImageMagick/UnplayedCountIndicator.cs | 2 +- Emby.Drawing/ImageProcessor.cs | 16 +- MediaBrowser.Api/AppThemeService.cs | 100 ----------- MediaBrowser.Api/EnvironmentService.cs | 8 +- MediaBrowser.Api/Images/ImageByNameService.cs | 21 ++- MediaBrowser.Api/Images/RemoteImageService.cs | 6 +- MediaBrowser.Api/ItemLookupService.cs | 8 +- MediaBrowser.Api/ItemRefreshService.cs | 2 +- MediaBrowser.Api/Library/LibraryHelpers.cs | 6 +- MediaBrowser.Api/Library/LibraryService.cs | 2 +- .../Library/LibraryStructureService.cs | 16 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 15 +- .../Playback/BaseStreamingService.cs | 6 +- .../Playback/Dash/MpegDashService.cs | 11 +- .../Playback/Hls/BaseHlsService.cs | 4 +- .../Playback/Hls/DynamicHlsService.cs | 11 +- .../BaseProgressiveStreamingService.cs | 4 +- MediaBrowser.Api/Subtitles/SubtitleService.cs | 2 +- MediaBrowser.Api/System/SystemService.cs | 6 +- .../Archiving/ZipClient.cs | 18 +- .../BaseApplicationHost.cs | 9 +- .../BaseApplicationPaths.cs | 4 +- .../Configuration/BaseConfigurationManager.cs | 4 +- .../Configuration/ConfigurationHelper.cs | 9 +- .../Devices/DeviceId.cs | 17 +- .../HttpClientManager/HttpClientManager.cs | 4 +- .../IO/CommonFileSystem.cs | 60 ++++--- .../Logging/NlogManager.cs | 2 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 4 +- .../Tasks/DeleteCacheFileTask.cs | 6 +- .../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 2 +- .../Security/MBLicenseFile.cs | 10 +- .../Serialization/JsonSerializer.cs | 2 +- .../Serialization/XmlSerializer.cs | 10 +- .../Updates/InstallationManager.cs | 8 +- MediaBrowser.Common/IO/IFileSystem.cs | 57 ++++-- MediaBrowser.Controller/Entities/BaseItem.cs | 10 +- MediaBrowser.Controller/Entities/Folder.cs | 6 +- MediaBrowser.Controller/Entities/User.cs | 10 +- .../MediaBrowser.Controller.csproj | 16 +- .../Providers/DirectoryService.cs | 12 +- .../Providers/MetadataRefreshOptions.cs | 5 +- .../Themes/IAppThemeManager.cs | 38 ---- .../Themes/InternalThemeImage.cs | 31 ---- MediaBrowser.Dlna/DlnaManager.cs | 10 +- .../Savers/XmlSaverHelpers.cs | 7 +- .../EncodingConfigurationFactory.cs | 2 +- .../Encoder/BaseEncoder.cs | 6 +- .../Encoder/MediaEncoder.cs | 2 +- .../Subtitles/SubtitleEncoder.cs | 20 +-- MediaBrowser.Model/Dlna/StreamBuilder.cs | 15 +- MediaBrowser.Model/MediaBrowser.Model.csproj | 15 +- MediaBrowser.Model/Themes/AppTheme.cs | 22 --- MediaBrowser.Model/Themes/AppThemeInfo.cs | 9 - MediaBrowser.Model/Themes/ThemeImage.cs | 18 -- .../BoxSets/MovieDbBoxSetProvider.cs | 2 +- .../ImagesByName/ImageUtils.cs | 4 +- MediaBrowser.Providers/Manager/ImageSaver.cs | 2 +- .../Manager/ItemImageProvider.cs | 4 +- .../Manager/ProviderManager.cs | 2 +- .../MediaInfo/AudioImageProvider.cs | 6 +- .../MediaInfo/FFProbeProvider.cs | 2 +- .../MediaInfo/FFProbeVideoInfo.cs | 2 +- .../Movies/FanArtMovieUpdatesPostScanTask.cs | 6 +- .../Movies/FanartMovieImageProvider.cs | 2 +- .../Movies/GenericMovieDbInfo.cs | 7 +- .../Movies/MovieDbProvider.cs | 4 +- .../Movies/MovieUpdatesPrescanTask.cs | 6 +- .../Music/AudioDbAlbumProvider.cs | 2 +- .../Music/AudioDbArtistProvider.cs | 2 +- .../Music/FanArtArtistProvider.cs | 2 +- .../Music/FanArtUpdatesPostScanTask.cs | 6 +- .../People/MovieDbPersonProvider.cs | 2 +- .../Subtitles/SubtitleManager.cs | 2 +- .../TV/DummySeasonProvider.cs | 4 +- .../TV/FanArtTvUpdatesPostScanTask.cs | 6 +- .../TV/FanartSeriesProvider.cs | 2 +- .../TV/MissingEpisodeProvider.cs | 4 +- .../TV/MovieDbEpisodeImageProvider.cs | 2 +- .../TV/MovieDbSeasonProvider.cs | 2 +- .../TV/MovieDbSeriesProvider.cs | 4 +- MediaBrowser.Providers/TV/TvdbPrescanTask.cs | 8 +- .../TV/TvdbSeriesProvider.cs | 13 +- .../Channels/ChannelManager.cs | 10 +- .../Collections/CollectionManager.cs | 2 +- .../Collections/CollectionsDynamicFolder.cs | 2 +- .../ServerConfigurationManager.cs | 4 +- .../Connect/ConnectEntryPoint.cs | 6 +- .../Connect/ConnectManager.cs | 6 +- .../Devices/CameraUploadsFolder.cs | 2 +- .../Devices/DeviceManager.cs | 2 +- .../Devices/DeviceRepository.cs | 4 +- .../Notifications/RemoteNotifications.cs | 4 +- .../FileOrganization/EpisodeFileOrganizer.cs | 12 +- .../FileOrganization/TvFolderOrganizer.cs | 8 +- .../IO/LibraryMonitor.cs | 2 +- .../Library/LibraryManager.cs | 16 +- .../Library/MediaSourceManager.cs | 2 +- .../Library/UserManager.cs | 6 +- .../LiveTv/EmbyTV/EmbyTV.cs | 8 +- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 +- .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- .../Localization/LocalizationManager.cs | 4 +- ...MediaBrowser.Server.Implementations.csproj | 37 ++-- .../MediaEncoder/EncodingManager.cs | 2 +- .../News/NewsEntryPoint.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 2 +- .../Photos/BaseDynamicImageProvider.cs | 4 +- .../Playlists/ManualPlaylistsFolder.cs | 2 +- .../Playlists/PlaylistManager.cs | 4 +- .../ScheduledTasks/ChapterImagesTask.cs | 6 +- .../Sync/SyncJobProcessor.cs | 2 +- .../Sync/SyncManager.cs | 30 ---- .../Themes/AppThemeManager.cs | 168 ------------------ MediaBrowser.Server.Mac.userprefs | 21 +-- .../ApplicationHost.cs | 4 +- .../FFMpeg/FFMpegDownloader.cs | 16 +- .../FFMpeg/FFmpegValidator.cs | 6 +- .../Migrations/MigrateUserFolders.cs | 3 +- .../UnhandledExceptionWriter.cs | 4 +- .../Api/DashboardService.cs | 34 ++-- .../Savers/SeasonNfoSaver.cs | 2 +- OpenSubtitlesHandler/MovieHasher.cs | 12 +- OpenSubtitlesHandler/Utilities.cs | 2 +- 129 files changed, 482 insertions(+), 872 deletions(-) delete mode 100644 MediaBrowser.Api/AppThemeService.cs delete mode 100644 MediaBrowser.Controller/Themes/IAppThemeManager.cs delete mode 100644 MediaBrowser.Controller/Themes/InternalThemeImage.cs delete mode 100644 MediaBrowser.Model/Themes/AppTheme.cs delete mode 100644 MediaBrowser.Model/Themes/AppThemeInfo.cs delete mode 100644 MediaBrowser.Model/Themes/ThemeImage.cs delete mode 100644 MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs diff --git a/Emby.Drawing/Common/ImageHeader.cs b/Emby.Drawing/Common/ImageHeader.cs index b66bd71ea5..1c70b3bb6c 100644 --- a/Emby.Drawing/Common/ImageHeader.cs +++ b/Emby.Drawing/Common/ImageHeader.cs @@ -46,7 +46,7 @@ namespace Emby.Drawing.Common /// The image was of an unrecognised format. public static ImageSize GetDimensions(string path, ILogger logger, IFileSystem fileSystem) { - using (var fs = File.OpenRead(path)) + using (var fs = fileSystem.OpenRead(path)) { using (var binaryReader = new BinaryReader(fs)) { diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 7e3ca530b5..1eabce74e0 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -66,7 +66,7 @@ namespace Emby.Drawing.GDI { using (var croppedImage = image.CropWhitespace()) { - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var outputStream = _fileSystem.GetFileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.Read, false)) { @@ -120,7 +120,7 @@ namespace Emby.Drawing.GDI var outputFormat = GetOutputFormat(originalImage, selectedOutputFormat); - Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); // Save to the cache location using (var cacheFileStream = _fileSystem.GetFileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, false)) diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 6ff40d1cf2..1fa93d5fbf 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Logging; using System; using System.IO; using System.Linq; +using MediaBrowser.Common.IO; namespace Emby.Drawing.ImageMagick { @@ -15,13 +16,15 @@ namespace Emby.Drawing.ImageMagick { private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; - private readonly IHttpClient _httpClient; + private readonly IHttpClient _httpClient; + private readonly IFileSystem _fileSystem; - public ImageMagickEncoder(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient) + public ImageMagickEncoder(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IFileSystem fileSystem) { _logger = logger; _appPaths = appPaths; _httpClient = httpClient; + _fileSystem = fileSystem; LogImageMagickVersion(); } @@ -77,7 +80,7 @@ namespace Emby.Drawing.ImageMagick try { var tmpPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".webp"); - Directory.CreateDirectory(Path.GetDirectoryName(tmpPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(tmpPath)); using (var wand = new MagickWand(1, 1, new PixelWand("none", 1))) { @@ -181,7 +184,7 @@ namespace Emby.Drawing.ImageMagick { var currentImageSize = new ImageSize(imageWidth, imageHeight); - var task = new PlayedIndicatorDrawer(_appPaths, _httpClient).DrawPlayedIndicator(wand, currentImageSize); + var task = new PlayedIndicatorDrawer(_appPaths, _httpClient, _fileSystem).DrawPlayedIndicator(wand, currentImageSize); Task.WaitAll(task); } else if (options.UnplayedCount.HasValue) diff --git a/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs b/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs index 1c751de1fd..b5912788fa 100644 --- a/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs +++ b/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Drawing; using System; using System.IO; using System.Threading.Tasks; +using MediaBrowser.Common.IO; namespace Emby.Drawing.ImageMagick { @@ -14,12 +15,14 @@ namespace Emby.Drawing.ImageMagick private const int OffsetFromTopRightCorner = 38; private readonly IApplicationPaths _appPaths; - private readonly IHttpClient _iHttpClient; + private readonly IHttpClient _iHttpClient; + private readonly IFileSystem _fileSystem; - public PlayedIndicatorDrawer(IApplicationPaths appPaths, IHttpClient iHttpClient) + public PlayedIndicatorDrawer(IApplicationPaths appPaths, IHttpClient iHttpClient, IFileSystem fileSystem) { _appPaths = appPaths; _iHttpClient = iHttpClient; + _fileSystem = fileSystem; } public async Task DrawPlayedIndicator(MagickWand wand, ImageSize imageSize) @@ -38,7 +41,7 @@ namespace Emby.Drawing.ImageMagick pixel.Opacity = 0; pixel.Color = "white"; draw.FillColor = pixel; - draw.Font = await DownloadFont("webdings.ttf", "https://github.com/MediaBrowser/Emby.Resources/raw/master/fonts/webdings.ttf", _appPaths, _iHttpClient).ConfigureAwait(false); + draw.Font = await DownloadFont("webdings.ttf", "https://github.com/MediaBrowser/Emby.Resources/raw/master/fonts/webdings.ttf", _appPaths, _iHttpClient, _fileSystem).ConfigureAwait(false); draw.FontSize = FontSize; draw.FontStyle = FontStyleType.NormalStyle; draw.TextAlignment = TextAlignType.CenterAlign; @@ -52,18 +55,18 @@ namespace Emby.Drawing.ImageMagick } } - internal static string ExtractFont(string name, IApplicationPaths paths) + internal static string ExtractFont(string name, IApplicationPaths paths, IFileSystem fileSystem) { var filePath = Path.Combine(paths.ProgramDataPath, "fonts", name); - if (File.Exists(filePath)) + if (fileSystem.FileExists(filePath)) { return filePath; } var namespacePath = typeof(PlayedIndicatorDrawer).Namespace + ".fonts." + name; var tempPath = Path.Combine(paths.TempDirectory, Guid.NewGuid().ToString("N") + ".ttf"); - Directory.CreateDirectory(Path.GetDirectoryName(tempPath)); + fileSystem.CreateDirectory(Path.GetDirectoryName(tempPath)); using (var stream = typeof(PlayedIndicatorDrawer).Assembly.GetManifestResourceStream(namespacePath)) { @@ -73,11 +76,11 @@ namespace Emby.Drawing.ImageMagick } } - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + fileSystem.CreateDirectory(Path.GetDirectoryName(filePath)); try { - File.Copy(tempPath, filePath, false); + fileSystem.CopyFile(tempPath, filePath, false); } catch (IOException) { @@ -87,11 +90,11 @@ namespace Emby.Drawing.ImageMagick return tempPath; } - internal static async Task DownloadFont(string name, string url, IApplicationPaths paths, IHttpClient httpClient) + internal static async Task DownloadFont(string name, string url, IApplicationPaths paths, IHttpClient httpClient, IFileSystem fileSystem) { var filePath = Path.Combine(paths.ProgramDataPath, "fonts", name); - if (File.Exists(filePath)) + if (fileSystem.FileExists(filePath)) { return filePath; } @@ -103,11 +106,11 @@ namespace Emby.Drawing.ImageMagick }).ConfigureAwait(false); - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + fileSystem.CreateDirectory(Path.GetDirectoryName(filePath)); try { - File.Copy(tempPath, filePath, false); + fileSystem.CopyFile(tempPath, filePath, false); } catch (IOException) { diff --git a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs index 7ed0f36e2c..92eb1cd597 100644 --- a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs +++ b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs @@ -2,16 +2,19 @@ using MediaBrowser.Common.Configuration; using System; using System.Collections.Generic; +using MediaBrowser.Common.IO; namespace Emby.Drawing.ImageMagick { public class StripCollageBuilder { private readonly IApplicationPaths _appPaths; + private readonly IFileSystem _fileSystem; - public StripCollageBuilder(IApplicationPaths appPaths) + public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem) { _appPaths = appPaths; + _fileSystem = fileSystem; } public void BuildPosterCollage(List paths, string outputPath, int width, int height, string text) @@ -490,7 +493,7 @@ namespace Emby.Drawing.ImageMagick private string MontserratLightFont { - get { return PlayedIndicatorDrawer.ExtractFont("MontserratLight.otf", _appPaths); } + get { return PlayedIndicatorDrawer.ExtractFont("MontserratLight.otf", _appPaths, _fileSystem); } } } } diff --git a/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs b/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs index dd25004d66..d63abd2a5a 100644 --- a/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs +++ b/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs @@ -33,7 +33,7 @@ namespace Emby.Drawing.ImageMagick pixel.Opacity = 0; pixel.Color = "white"; draw.FillColor = pixel; - draw.Font = PlayedIndicatorDrawer.ExtractFont("robotoregular.ttf", _appPaths); + draw.Font = PlayedIndicatorDrawer.ExtractFont("robotoregular.ttf", _appPaths, _fileSystem); draw.FontStyle = FontStyleType.NormalStyle; draw.TextAlignment = TextAlignType.CenterAlign; draw.FontWeight = FontWeightType.RegularStyle; diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 231bfa2b47..d4fce76d02 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -215,12 +215,12 @@ namespace Emby.Drawing { CheckDisposed(); - if (!File.Exists(cacheFilePath)) + if (!_fileSystem.FileExists(cacheFilePath)) { var newWidth = Convert.ToInt32(newSize.Width); var newHeight = Convert.ToInt32(newSize.Height); - Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); @@ -270,7 +270,7 @@ namespace Emby.Drawing await semaphore.WaitAsync().ConfigureAwait(false); // Check again in case of contention - if (File.Exists(croppedImagePath)) + if (_fileSystem.FileExists(croppedImagePath)) { semaphore.Release(); return GetResult(croppedImagePath); @@ -280,7 +280,7 @@ namespace Emby.Drawing try { - Directory.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); imageProcessingLockTaken = true; @@ -366,7 +366,7 @@ namespace Emby.Drawing /// ImageSize. public ImageSize GetImageSize(string path) { - return GetImageSize(path, File.GetLastWriteTimeUtc(path), false); + return GetImageSize(path, _fileSystem.GetLastWriteTimeUtc(path), false); } public ImageSize GetImageSize(ItemImageInfo info) @@ -452,7 +452,7 @@ namespace Emby.Drawing try { var path = ImageSizeFile; - Directory.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); _jsonSerializer.SerializeToFile(_cachedImagedSizes, path); } catch (Exception ex) @@ -624,7 +624,7 @@ namespace Emby.Drawing await semaphore.WaitAsync().ConfigureAwait(false); // Check again in case of contention - if (File.Exists(enhancedImagePath)) + if (_fileSystem.FileExists(enhancedImagePath)) { semaphore.Release(); return enhancedImagePath; @@ -634,7 +634,7 @@ namespace Emby.Drawing try { - Directory.CreateDirectory(Path.GetDirectoryName(enhancedImagePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(enhancedImagePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); diff --git a/MediaBrowser.Api/AppThemeService.cs b/MediaBrowser.Api/AppThemeService.cs deleted file mode 100644 index 87084e415a..0000000000 --- a/MediaBrowser.Api/AppThemeService.cs +++ /dev/null @@ -1,100 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Themes; -using MediaBrowser.Model.Themes; -using ServiceStack; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace MediaBrowser.Api -{ - [Route("/Themes", "GET", Summary = "Gets a list of available themes for an app")] - public class GetAppThemes : IReturn> - { - [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string App { get; set; } - } - - [Route("/Themes/Info", "GET", Summary = "Gets an app theme")] - public class GetAppTheme : IReturn - { - [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string App { get; set; } - - [ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string Name { get; set; } - } - - [Route("/Themes/Images", "GET", Summary = "Gets an app theme")] - public class GetAppThemeImage - { - [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string App { get; set; } - - [ApiMember(Name = "Theme", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string Theme { get; set; } - - [ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string Name { get; set; } - - [ApiMember(Name = "CacheTag", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public string CacheTag { get; set; } - } - - [Route("/Themes", "POST", Summary = "Saves a theme")] - public class SaveTheme : AppTheme, IReturnVoid - { - } - - [Authenticated] - public class AppThemeService : BaseApiService - { - private readonly IAppThemeManager _themeManager; - private readonly IFileSystem _fileSystem; - - public AppThemeService(IAppThemeManager themeManager, IFileSystem fileSystem) - { - _themeManager = themeManager; - _fileSystem = fileSystem; - } - - public object Get(GetAppThemes request) - { - var result = _themeManager.GetThemes(request.App).ToList(); - - return ToOptimizedResult(result); - } - - public object Get(GetAppTheme request) - { - var result = _themeManager.GetTheme(request.App, request.Name); - - return ToOptimizedResult(result); - } - - public void Post(SaveTheme request) - { - _themeManager.SaveTheme(request); - } - - public object Get(GetAppThemeImage request) - { - var info = _themeManager.GetImageImageInfo(request.App, request.Theme, request.Name); - - var cacheGuid = new Guid(info.CacheTag); - - TimeSpan? cacheDuration = null; - - if (!string.IsNullOrEmpty(request.CacheTag) && cacheGuid == new Guid(request.CacheTag)) - { - cacheDuration = TimeSpan.FromDays(365); - } - - var contentType = MimeTypes.GetMimeType(info.Path); - - return ResultFactory.GetCachedResult(Request, cacheGuid, null, cacheDuration, () => _fileSystem.GetFileStream(info.Path, FileMode.Open, FileAccess.Read, FileShare.Read), contentType); - } - } -} diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 457b4709bf..8160c6a167 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using MediaBrowser.Common.IO; namespace MediaBrowser.Api { @@ -96,13 +97,14 @@ namespace MediaBrowser.Api /// The _network manager /// private readonly INetworkManager _networkManager; + private IFileSystem _fileSystem; /// /// Initializes a new instance of the class. /// /// The network manager. /// networkManager - public EnvironmentService(INetworkManager networkManager) + public EnvironmentService(INetworkManager networkManager, IFileSystem fileSystem) { if (networkManager == null) { @@ -110,6 +112,7 @@ namespace MediaBrowser.Api } _networkManager = networkManager; + _fileSystem = fileSystem; } /// @@ -222,8 +225,7 @@ namespace MediaBrowser.Api private IEnumerable GetFileSystemEntries(GetDirectoryContents request) { // using EnumerateFileSystemInfos doesn't handle reparse points (symlinks) - var entries = new DirectoryInfo(request.Path).EnumerateDirectories("*", SearchOption.TopDirectoryOnly) - .Concat(new DirectoryInfo(request.Path).EnumerateFiles("*", SearchOption.TopDirectoryOnly)).Where(i => + var entries = _fileSystem.GetFileSystemEntries(request.Path).Where(i => { if (!request.IncludeHidden && i.Attributes.HasFlag(FileAttributes.Hidden)) { diff --git a/MediaBrowser.Api/Images/ImageByNameService.cs b/MediaBrowser.Api/Images/ImageByNameService.cs index b4d5a99497..a6e1af516c 100644 --- a/MediaBrowser.Api/Images/ImageByNameService.cs +++ b/MediaBrowser.Api/Images/ImageByNameService.cs @@ -130,8 +130,7 @@ namespace MediaBrowser.Api.Images { try { - return new DirectoryInfo(path) - .GetFiles("*", SearchOption.AllDirectories) + return _fileSystem.GetFiles(path) .Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.Ordinal)) .Select(i => new ImageByNameInfo { @@ -184,7 +183,7 @@ namespace MediaBrowser.Api.Images var paths = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(_appPaths.GeneralPath, request.Name, filename + i)).ToList(); - var path = paths.FirstOrDefault(File.Exists) ?? paths.FirstOrDefault(); + var path = paths.FirstOrDefault(_fileSystem.FileExists) ?? paths.FirstOrDefault(); return ToStaticFileResult(path); } @@ -198,11 +197,11 @@ namespace MediaBrowser.Api.Images { var themeFolder = Path.Combine(_appPaths.RatingsPath, request.Theme); - if (Directory.Exists(themeFolder)) + if (_fileSystem.DirectoryExists(themeFolder)) { var path = BaseItem.SupportedImageExtensions .Select(i => Path.Combine(themeFolder, request.Name + i)) - .FirstOrDefault(File.Exists); + .FirstOrDefault(_fileSystem.FileExists); if (!string.IsNullOrEmpty(path)) { @@ -212,14 +211,14 @@ namespace MediaBrowser.Api.Images var allFolder = Path.Combine(_appPaths.RatingsPath, "all"); - if (Directory.Exists(allFolder)) + if (_fileSystem.DirectoryExists(allFolder)) { // Avoid implicitly captured closure var currentRequest = request; var path = BaseItem.SupportedImageExtensions .Select(i => Path.Combine(allFolder, currentRequest.Name + i)) - .FirstOrDefault(File.Exists); + .FirstOrDefault(_fileSystem.FileExists); if (!string.IsNullOrEmpty(path)) { @@ -239,10 +238,10 @@ namespace MediaBrowser.Api.Images { var themeFolder = Path.Combine(_appPaths.MediaInfoImagesPath, request.Theme); - if (Directory.Exists(themeFolder)) + if (_fileSystem.DirectoryExists(themeFolder)) { var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(themeFolder, request.Name + i)) - .FirstOrDefault(File.Exists); + .FirstOrDefault(_fileSystem.FileExists); if (!string.IsNullOrEmpty(path)) { @@ -252,13 +251,13 @@ namespace MediaBrowser.Api.Images var allFolder = Path.Combine(_appPaths.MediaInfoImagesPath, "all"); - if (Directory.Exists(allFolder)) + if (_fileSystem.DirectoryExists(allFolder)) { // Avoid implicitly captured closure var currentRequest = request; var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(allFolder, currentRequest.Name + i)) - .FirstOrDefault(File.Exists); + .FirstOrDefault(_fileSystem.FileExists); if (!string.IsNullOrEmpty(path)) { diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 6d2579ea9f..c67ef96c96 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -237,7 +237,7 @@ namespace MediaBrowser.Api.Images contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - if (File.Exists(contentPath)) + if (_fileSystem.FileExists(contentPath)) { return ToStaticFileResult(contentPath); } @@ -281,7 +281,7 @@ namespace MediaBrowser.Api.Images var fullCachePath = GetFullCachePath(urlHash + "." + ext); - Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(fullCachePath)); using (var stream = result.Content) { using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true)) @@ -290,7 +290,7 @@ namespace MediaBrowser.Api.Images } } - Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); using (var writer = new StreamWriter(pointerCachePath)) { await writer.WriteAsync(fullCachePath).ConfigureAwait(false); diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index a0ba6e61f8..9f7f57155b 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -200,7 +200,7 @@ namespace MediaBrowser.Api //} item.ProviderIds = request.ProviderIds; - var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions + var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem) { MetadataRefreshMode = MetadataRefreshMode.FullRefresh, ImageRefreshMode = ImageRefreshMode.FullRefresh, @@ -230,7 +230,7 @@ namespace MediaBrowser.Api contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - if (File.Exists(contentPath)) + if (_fileSystem.FileExists(contentPath)) { return ToStaticFileResult(contentPath); } @@ -271,7 +271,7 @@ namespace MediaBrowser.Api var fullCachePath = GetFullCachePath(urlHash + "." + ext); - Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(fullCachePath)); using (var stream = result.Content) { using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true)) @@ -280,7 +280,7 @@ namespace MediaBrowser.Api } } - Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); using (var writer = new StreamWriter(pointerCachePath)) { await writer.WriteAsync(fullCachePath).ConfigureAwait(false); diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index f56fd32828..7eb0b87dda 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Api private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request) { - return new MetadataRefreshOptions(new DirectoryService()) + return new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { MetadataRefreshMode = request.MetadataRefreshMode, ImageRefreshMode = request.ImageRefreshMode, diff --git a/MediaBrowser.Api/Library/LibraryHelpers.cs b/MediaBrowser.Api/Library/LibraryHelpers.cs index 0ee28d6fef..5e40ac635f 100644 --- a/MediaBrowser.Api/Library/LibraryHelpers.cs +++ b/MediaBrowser.Api/Library/LibraryHelpers.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Library var rootFolderPath = appPaths.DefaultUserViewsPath; var path = Path.Combine(rootFolderPath, virtualFolderName); - if (!Directory.Exists(path)) + if (!fileSystem.DirectoryExists(path)) { throw new DirectoryNotFoundException(string.Format("The media collection {0} does not exist", virtualFolderName)); } @@ -57,7 +57,7 @@ namespace MediaBrowser.Api.Library /// The path is not valid. public static void AddMediaPath(IFileSystem fileSystem, string virtualFolderName, string path, IServerApplicationPaths appPaths) { - if (!Directory.Exists(path)) + if (!fileSystem.DirectoryExists(path)) { throw new DirectoryNotFoundException("The path does not exist."); } @@ -69,7 +69,7 @@ namespace MediaBrowser.Api.Library var lnk = Path.Combine(virtualFolderPath, shortcutFilename + ShortcutFileExtension); - while (File.Exists(lnk)) + while (fileSystem.FileExists(lnk)) { shortcutFilename += "1"; lnk = Path.Combine(virtualFolderPath, shortcutFilename + ShortcutFileExtension); diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 49dd121baa..9106d86ff5 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -557,7 +557,7 @@ namespace MediaBrowser.Api.Library { throw new ArgumentException("This command cannot be used for remote or virtual items."); } - if (Directory.Exists(item.Path)) + if (_fileSystem.DirectoryExists(item.Path)) { throw new ArgumentException("This command cannot be used for directories."); } diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index f5fe921cec..c9baf5c376 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -195,7 +195,7 @@ namespace MediaBrowser.Api.Library var virtualFolderPath = Path.Combine(rootFolderPath, name); - if (Directory.Exists(virtualFolderPath)) + if (_fileSystem.DirectoryExists(virtualFolderPath)) { throw new ArgumentException("There is already a media collection with the name " + name + "."); } @@ -204,13 +204,13 @@ namespace MediaBrowser.Api.Library try { - Directory.CreateDirectory(virtualFolderPath); + _fileSystem.CreateDirectory(virtualFolderPath); if (!string.IsNullOrEmpty(request.CollectionType)) { var path = Path.Combine(virtualFolderPath, request.CollectionType + ".collection"); - File.Create(path); + _fileSystem.CreateFile(path); } } finally @@ -256,12 +256,12 @@ namespace MediaBrowser.Api.Library var currentPath = Path.Combine(rootFolderPath, request.Name); var newPath = Path.Combine(rootFolderPath, request.NewName); - if (!Directory.Exists(currentPath)) + if (!_fileSystem.DirectoryExists(currentPath)) { throw new DirectoryNotFoundException("The media collection does not exist"); } - if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && Directory.Exists(newPath)) + if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && _fileSystem.DirectoryExists(newPath)) { throw new ArgumentException("There is already a media collection with the name " + newPath + "."); } @@ -276,11 +276,11 @@ namespace MediaBrowser.Api.Library //Create an unique name var temporaryName = Guid.NewGuid().ToString(); var temporaryPath = Path.Combine(rootFolderPath, temporaryName); - Directory.Move(currentPath, temporaryPath); + _fileSystem.MoveDirectory(currentPath, temporaryPath); currentPath = temporaryPath; } - Directory.Move(currentPath, newPath); + _fileSystem.MoveDirectory(currentPath, newPath); } finally { @@ -319,7 +319,7 @@ namespace MediaBrowser.Api.Library var path = Path.Combine(rootFolderPath, request.Name); - if (!Directory.Exists(path)) + if (!_fileSystem.DirectoryExists(path)) { throw new DirectoryNotFoundException("The media folder does not exist"); } diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 7fa631e218..901dd11e2a 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -11,10 +11,10 @@ MediaBrowser.Api 512 ..\ - 10.0.0 - 2.0 v4.5 true + + true @@ -25,7 +25,6 @@ prompt 4 AnyCPU - v4.5 none @@ -34,7 +33,6 @@ TRACE prompt 4 - v4.5 none @@ -43,16 +41,11 @@ TRACE prompt 4 - v4.5 Always - - False - ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll - @@ -64,12 +57,14 @@ ..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll + + ..\packages\morelinq.1.1.1\lib\net35\MoreLinq.dll + Properties\SharedVersion.cs - diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 531d67eedd..a524490783 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -889,7 +889,7 @@ namespace MediaBrowser.Api.Playback CancellationTokenSource cancellationTokenSource, string workingDirectory = null) { - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + FileSystem.CreateDirectory(Path.GetDirectoryName(outputPath)); await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false); @@ -942,7 +942,7 @@ namespace MediaBrowser.Api.Playback Logger.Info(commandLineLogMessage); var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, "transcode-" + Guid.NewGuid() + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(logFilePath)); + FileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath)); // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory. state.LogFileStream = FileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); @@ -972,7 +972,7 @@ namespace MediaBrowser.Api.Playback StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream); // Wait for the file to exist before proceeeding - while (!File.Exists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited) + while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited) { await Task.Delay(100, cancellationTokenSource.Token).ConfigureAwait(false); } diff --git a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs index c201ffd587..8864848011 100644 --- a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs @@ -174,7 +174,7 @@ namespace MediaBrowser.Api.Playback.Dash var workingDirectory = Path.Combine(Path.GetDirectoryName(playlistPath), (startNumber == -1 ? 0 : startNumber).ToString(CultureInfo.InvariantCulture)); state.WaitForPath = Path.Combine(workingDirectory, Path.GetFileName(playlistPath)); - Directory.CreateDirectory(workingDirectory); + FileSystem.CreateDirectory(workingDirectory); job = await StartFfMpeg(state, playlistPath, cancellationTokenSource, workingDirectory).ConfigureAwait(false); await WaitForMinimumDashSegmentCount(Path.Combine(workingDirectory, Path.GetFileName(playlistPath)), 1, cancellationTokenSource.Token).ConfigureAwait(false); } @@ -328,8 +328,7 @@ namespace MediaBrowser.Api.Playback.Dash try { - return new DirectoryInfo(folder) - .EnumerateFiles("*", SearchOption.AllDirectories) + return fileSystem.GetFiles(folder) .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase)) .OrderByDescending(fileSystem.GetLastWriteTimeUtc) .Take(count) @@ -348,12 +347,12 @@ namespace MediaBrowser.Api.Playback.Dash if (requestedIndex == -1) { var path = Path.Combine(folder, "0", "stream" + representationId + "-" + "init" + segmentExtension); - return File.Exists(path) ? path : null; + return FileSystem.FileExists(path) ? path : null; } try { - foreach (var subfolder in new DirectoryInfo(folder).EnumerateDirectories().ToList()) + foreach (var subfolder in FileSystem.GetDirectories(folder).ToList()) { var subfolderName = Path.GetFileNameWithoutExtension(subfolder.FullName); int startNumber; @@ -361,7 +360,7 @@ namespace MediaBrowser.Api.Playback.Dash { var segmentIndex = requestedIndex - startNumber + 1; var path = Path.Combine(folder, subfolderName, "stream" + representationId + "-" + segmentIndex.ToString("00000", CultureInfo.InvariantCulture) + segmentExtension); - if (File.Exists(path)) + if (FileSystem.FileExists(path)) { return path; } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index e4f00e2a08..036397b4f5 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -90,12 +90,12 @@ namespace MediaBrowser.Api.Playback.Hls TranscodingJob job = null; var playlist = state.OutputFilePath; - if (!File.Exists(playlist)) + if (!FileSystem.FileExists(playlist)) { await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); try { - if (!File.Exists(playlist)) + if (!FileSystem.FileExists(playlist)) { // If the playlist doesn't already exist, startup ffmpeg try diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 7b2844cd4b..9359c65f26 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -165,7 +165,7 @@ namespace MediaBrowser.Api.Playback.Hls TranscodingJob job = null; - if (File.Exists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); @@ -174,7 +174,7 @@ namespace MediaBrowser.Api.Playback.Hls await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); try { - if (File.Exists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); @@ -386,8 +386,7 @@ namespace MediaBrowser.Api.Playback.Hls try { - return new DirectoryInfo(folder) - .EnumerateFiles("*", SearchOption.TopDirectoryOnly) + return fileSystem.GetFiles(folder) .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase) && Path.GetFileNameWithoutExtension(i.Name).StartsWith(filePrefix, StringComparison.OrdinalIgnoreCase)) .OrderByDescending(fileSystem.GetLastWriteTimeUtc) .FirstOrDefault(); @@ -432,7 +431,7 @@ namespace MediaBrowser.Api.Playback.Hls CancellationToken cancellationToken) { // If all transcoding has completed, just return immediately - if (transcodingJob != null && transcodingJob.HasExited && File.Exists(segmentPath)) + if (transcodingJob != null && transcodingJob.HasExited && FileSystem.FileExists(segmentPath)) { return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } @@ -452,7 +451,7 @@ namespace MediaBrowser.Api.Playback.Hls // If it appears in the playlist, it's done if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) { - if (File.Exists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 910ac18e7b..aa0cda133b 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -139,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Progressive } var outputPath = state.OutputFilePath; - var outputPathExists = File.Exists(outputPath); + var outputPathExists = FileSystem.FileExists(outputPath); var isTranscodeCached = outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive); @@ -325,7 +325,7 @@ namespace MediaBrowser.Api.Playback.Progressive { TranscodingJob job; - if (!File.Exists(outputPath)) + if (!FileSystem.FileExists(outputPath)) { job = await StartFfMpeg(state, outputPath, cancellationTokenSource).ConfigureAwait(false); } diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index c9280b6f63..6cfd07caca 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -259,7 +259,7 @@ namespace MediaBrowser.Api.Subtitles await _subtitleManager.DownloadSubtitles(video, request.SubtitleId, CancellationToken.None) .ConfigureAwait(false); - _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions()); + _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions(_fileSystem)); } catch (Exception ex) { diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index aa12269019..00935dd1e1 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -122,8 +122,7 @@ namespace MediaBrowser.Api.System try { - files = new DirectoryInfo(_appPaths.LogDirectoryPath) - .EnumerateFiles("*", SearchOption.AllDirectories) + files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .Where(i => string.Equals(i.Extension, ".txt", StringComparison.OrdinalIgnoreCase)) .ToList(); } @@ -149,8 +148,7 @@ namespace MediaBrowser.Api.System public object Get(GetLogFile request) { - var file = new DirectoryInfo(_appPaths.LogDirectoryPath) - .EnumerateFiles("*", SearchOption.AllDirectories) + var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase)); return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite); diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs index cdcbc311a1..1377e9d552 100644 --- a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs +++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs @@ -7,6 +7,7 @@ using SharpCompress.Reader; using SharpCompress.Reader.Zip; using System; using System.IO; +using MediaBrowser.Common.IO; namespace MediaBrowser.Common.Implementations.Archiving { @@ -15,7 +16,14 @@ namespace MediaBrowser.Common.Implementations.Archiving /// public class ZipClient : IZipClient { - /// + private IFileSystem _fileSystem; + + public ZipClient(IFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + + /// /// Extracts all. /// /// The source file. @@ -23,7 +31,7 @@ namespace MediaBrowser.Common.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) + using (var fileStream = _fileSystem.OpenRead(sourceFile)) { ExtractAll(fileStream, targetPath, overwriteExistingFiles); } @@ -73,7 +81,7 @@ namespace MediaBrowser.Common.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) + using (var fileStream = _fileSystem.OpenRead(sourceFile)) { ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles); } @@ -112,7 +120,7 @@ namespace MediaBrowser.Common.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) + using (var fileStream = _fileSystem.OpenRead(sourceFile)) { ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles); } @@ -150,7 +158,7 @@ namespace MediaBrowser.Common.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) + using (var fileStream = _fileSystem.OpenRead(sourceFile)) { ExtractAllFromRar(fileStream, targetPath, overwriteExistingFiles); } diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index bfd8c1f823..181f8e43d3 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -93,7 +93,7 @@ namespace MediaBrowser.Common.Implementations /// /// The _XML serializer /// - protected readonly IXmlSerializer XmlSerializer = new XmlSerializer(); + protected readonly IXmlSerializer XmlSerializer; /// /// Gets assemblies that failed to load @@ -180,7 +180,7 @@ namespace MediaBrowser.Common.Implementations { if (_deviceId == null) { - _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId")); + _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); } return _deviceId.Value; @@ -199,6 +199,7 @@ namespace MediaBrowser.Common.Implementations ILogManager logManager, IFileSystem fileSystem) { + XmlSerializer = new MediaBrowser.Common.Implementations.Serialization.XmlSerializer (fileSystem); FailedAssemblies = new List(); ApplicationPaths = applicationPaths; @@ -473,7 +474,7 @@ namespace MediaBrowser.Common.Implementations InstallationManager = new InstallationManager(Logger, this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager); RegisterSingleInstance(InstallationManager); - ZipClient = new ZipClient(); + ZipClient = new ZipClient(FileSystemManager); RegisterSingleInstance(ZipClient); IsoManager = new IsoManager(); @@ -650,7 +651,7 @@ namespace MediaBrowser.Common.Implementations { try { - return Assembly.Load(File.ReadAllBytes((file))); + return Assembly.Load(FileSystemManager.ReadAllBytes((file))); } catch (Exception ex) { diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs index 9ba2effd3a..f76359d30b 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.Common.Implementations { _dataDirectory = Path.Combine(ProgramDataPath, "data"); - Directory.CreateDirectory(_dataDirectory); + FileSystem.CreateDirectory(_dataDirectory); } return _dataDirectory; @@ -152,7 +152,7 @@ namespace MediaBrowser.Common.Implementations { _cachePath = Path.Combine(ProgramDataPath, "cache"); - Directory.CreateDirectory(_cachePath); + FileSystem.CreateDirectory(_cachePath); } return _cachePath; diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 1b9146644a..1e9d4c97ce 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -121,7 +121,7 @@ namespace MediaBrowser.Common.Implementations.Configuration { var path = CommonApplicationPaths.SystemConfigurationFilePath; - Directory.CreateDirectory(Path.GetDirectoryName(path)); + FileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_configurationSyncLock) { @@ -276,7 +276,7 @@ namespace MediaBrowser.Common.Implementations.Configuration _configurations.AddOrUpdate(key, configuration, (k, v) => configuration); var path = GetConfigurationFile(key); - Directory.CreateDirectory(Path.GetDirectoryName(path)); + FileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_configurationSyncLock) { diff --git a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs index ff5b8bd599..6af59bb6b0 100644 --- a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs +++ b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Linq; +using MediaBrowser.Common.IO; namespace MediaBrowser.Common.Implementations.Configuration { @@ -18,7 +19,7 @@ namespace MediaBrowser.Common.Implementations.Configuration /// The path. /// The XML serializer. /// System.Object. - public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer) + public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer, IFileSystem fileSystem) { object configuration; @@ -27,7 +28,7 @@ namespace MediaBrowser.Common.Implementations.Configuration // Use try/catch to avoid the extra file system lookup using File.Exists try { - buffer = File.ReadAllBytes(path); + buffer = fileSystem.ReadAllBytes(path); configuration = xmlSerializer.DeserializeFromBytes(type, buffer); } @@ -46,10 +47,10 @@ namespace MediaBrowser.Common.Implementations.Configuration // If the file didn't exist before, or if something has changed, re-save if (buffer == null || !buffer.SequenceEqual(newBytes)) { - Directory.CreateDirectory(Path.GetDirectoryName(path)); + fileSystem.CreateDirectory(Path.GetDirectoryName(path)); // Save it after load in case we got new items - File.WriteAllBytes(path, newBytes); + fileSystem.WriteAllBytes(path, newBytes); } return configuration; diff --git a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs index 2a1c8877d7..02edc493a5 100644 --- a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs +++ b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs @@ -3,13 +3,15 @@ using MediaBrowser.Model.Logging; using System; using System.IO; using System.Text; +using MediaBrowser.Common.IO; namespace MediaBrowser.Common.Implementations.Devices { public class DeviceId { private readonly IApplicationPaths _appPaths; - private readonly ILogger _logger; + private readonly ILogger _logger; + private readonly IFileSystem _fileSystem; private readonly object _syncLock = new object(); @@ -24,7 +26,7 @@ namespace MediaBrowser.Common.Implementations.Devices { lock (_syncLock) { - var value = File.ReadAllText(CachePath, Encoding.UTF8); + var value = _fileSystem.ReadAllText(CachePath, Encoding.UTF8); Guid guid; if (Guid.TryParse(value, out guid)) @@ -55,11 +57,11 @@ namespace MediaBrowser.Common.Implementations.Devices { var path = CachePath; - Directory.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_syncLock) { - File.WriteAllText(path, id, Encoding.UTF8); + _fileSystem.WriteAllText(path, id, Encoding.UTF8); } } catch (Exception ex) @@ -88,10 +90,15 @@ namespace MediaBrowser.Common.Implementations.Devices private string _id; - public DeviceId(IApplicationPaths appPaths, ILogger logger) + public DeviceId(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem) { + if (fileSystem == null) { + throw new ArgumentNullException ("fileSystem"); + } + _appPaths = appPaths; _logger = logger; + _fileSystem = fileSystem; } public string Value diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 89f405e8a0..5dd1ab8080 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -355,7 +355,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager private async Task CacheResponse(HttpResponseInfo response, string responseCachePath) { - Directory.CreateDirectory(Path.GetDirectoryName(responseCachePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(responseCachePath)); using (var responseStream = response.Content) { @@ -599,7 +599,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager { ValidateParams(options); - Directory.CreateDirectory(_appPaths.TempDirectory); + _fileSystem.CreateDirectory(_appPaths.TempDirectory); var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); diff --git a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs index e9ef846634..5951dbb316 100644 --- a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs +++ b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs @@ -4,6 +4,8 @@ using MediaBrowser.Model.Logging; using System; using System.IO; using System.Text; +using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Common.Implementations.IO { @@ -75,7 +77,7 @@ namespace MediaBrowser.Common.Implementations.IO if (string.Equals(Path.GetExtension(filename), ".mblink", StringComparison.OrdinalIgnoreCase)) { - var path = File.ReadAllText(filename); + var path = ReadAllText(filename); return NormalizePath(path); } @@ -105,7 +107,7 @@ namespace MediaBrowser.Common.Implementations.IO throw new ArgumentNullException("target"); } - File.WriteAllText(shortcutPath, target); + _fileSystem.WriteAllText(shortcutPath, target); } /// @@ -230,7 +232,7 @@ namespace MediaBrowser.Common.Implementations.IO /// The share. /// if set to true [is asynchronous]. /// FileStream. - public FileStream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false) + public Stream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false) { if (_supportsAsyncFileStreams && isAsync) { @@ -264,11 +266,11 @@ namespace MediaBrowser.Common.Implementations.IO RemoveHiddenAttribute(file1); RemoveHiddenAttribute(file2); - File.Copy(file1, temp1, true); - File.Copy(file2, temp2, true); + CopyFile(file1, temp1, true); + CopyFile(file2, temp2, true); - File.Copy(temp1, file2, true); - File.Copy(temp2, file1, true); + CopyFile(temp1, file2, true); + CopyFile(temp2, file1, true); DeleteFile(temp1); DeleteFile(temp2); @@ -410,24 +412,42 @@ namespace MediaBrowser.Common.Implementations.IO //return Path.IsPathRooted(path); } - public void DeleteFile(string path, bool sendToRecycleBin) + public void DeleteFile(string path) { File.Delete(path); } - public void DeleteDirectory(string path, bool recursive, bool sendToRecycleBin) - { - Directory.Delete(path, recursive); - } - - public void DeleteFile(string path) - { - DeleteFile(path, false); - } - public void DeleteDirectory(string path, bool recursive) { - DeleteDirectory(path, recursive, false); - } + Directory.Delete(path, recursive); + } + + public void CreateDirectory(string path) + { + Directory.CreateDirectory(path); + } + + public IEnumerable GetDirectories(string path, bool recursive = false) + { + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + return new DirectoryInfo (path).EnumerateDirectories("*", searchOption); + } + + public IEnumerable GetFiles(string path, bool recursive = false) + { + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + return new DirectoryInfo (path).EnumerateFiles("*", searchOption); + } + + public IEnumerable GetFileSystemEntries(string path, bool recursive = false) + { + var directoryInfo = new DirectoryInfo (path); + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + return directoryInfo.EnumerateDirectories("*", searchOption) + .Concat(directoryInfo.EnumerateFiles("*", searchOption)); + } } } diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs index 6d4cd06cb4..239ea03cda 100644 --- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs +++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs @@ -208,7 +208,7 @@ namespace MediaBrowser.Common.Implementations.Logging { LogFilePath = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Round(DateTime.Now.Ticks / 10000000) + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(LogFilePath)); AddFileTarget(LogFilePath, level); diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index cbd1c1ac55..08c117220e 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -154,7 +154,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks _lastExecutionResult = value; var path = GetHistoryFilePath(); - Directory.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_lastExecutionResultSyncLock) { @@ -552,7 +552,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { var path = GetConfigurationFilePath(); - Directory.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); JsonSerializer.SerializeToFile(triggers.Select(ScheduledTaskHelpers.GetTriggerInfo), path); } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index d9c178d8b5..6d5516ebd0 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The progress. private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress progress) { - var filesToDelete = new DirectoryInfo(directory).EnumerateFiles("*", SearchOption.AllDirectories) + var filesToDelete = _fileSystem.GetFiles(directory, true) .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified) .ToList(); @@ -120,14 +120,14 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks progress.Report(100); } - private static void DeleteEmptyFolders(string parent) + private void DeleteEmptyFolders(string parent) { foreach (var directory in Directory.GetDirectories(parent)) { DeleteEmptyFolders(directory); if (!Directory.EnumerateFileSystemEntries(directory).Any()) { - Directory.Delete(directory, false); + _fileSystem.DeleteDirectory(directory, false); } } } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs index b2759c52a6..ffba3d9dae 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Delete log files more than n days old var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays)); - var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories) + var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, true) .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified) .ToList(); diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs index 63381efcdf..e5cf5856e7 100644 --- a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs +++ b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs @@ -99,15 +99,15 @@ namespace MediaBrowser.Common.Implementations.Security { try { - contents = File.ReadAllLines(licenseFile); + contents = _fileSystem.ReadAllLines(licenseFile); } catch (DirectoryNotFoundException) { - (File.Create(licenseFile)).Close(); + (_fileSystem.CreateFile(licenseFile)).Close(); } catch (FileNotFoundException) { - (File.Create(licenseFile)).Close(); + (_fileSystem.CreateFile(licenseFile)).Close(); } } if (contents != null && contents.Length > 0) @@ -150,8 +150,8 @@ namespace MediaBrowser.Common.Implementations.Security } var licenseFile = Filename; - Directory.CreateDirectory(Path.GetDirectoryName(licenseFile)); - lock (_fileLock) File.WriteAllLines(licenseFile, lines); + _fileSystem.CreateDirectory(Path.GetDirectoryName(licenseFile)); + lock (_fileLock) _fileSystem.WriteAllLines(licenseFile, lines); } } } diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs index f194b334a8..80ccd72f77 100644 --- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.Common.Implementations.Serialization throw new ArgumentNullException("file"); } - using (Stream stream = File.Open(file, FileMode.Create)) + using (Stream stream = _fileSystem.GetFileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read)) { SerializeToStream(obj, stream); } diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs index 04030522f3..41a59fb2b4 100644 --- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.IO; using System.Xml; +using MediaBrowser.Common.IO; namespace MediaBrowser.Common.Implementations.Serialization { @@ -11,6 +12,13 @@ namespace MediaBrowser.Common.Implementations.Serialization /// public class XmlSerializer : IXmlSerializer { + private IFileSystem _fileSystem; + + public XmlSerializer(IFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + // Need to cache these // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html private readonly ConcurrentDictionary _serializers = @@ -83,7 +91,7 @@ namespace MediaBrowser.Common.Implementations.Serialization /// System.Object. public object DeserializeFromFile(Type type, string file) { - using (var stream = File.OpenRead(file)) + using (var stream = _fileSystem.OpenRead(file)) { return DeserializeFromStream(type, stream); } diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index 5f205d69e7..fee23fd2e1 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -553,7 +553,7 @@ namespace MediaBrowser.Common.Implementations.Updates if (packageChecksum != Guid.Empty) // support for legacy uploads for now { using (var crypto = new MD5CryptoServiceProvider()) - using (var stream = new BufferedStream(File.OpenRead(tempFile), 100000)) + using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000)) { var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty)); if (check != packageChecksum) @@ -568,12 +568,12 @@ namespace MediaBrowser.Common.Implementations.Updates // Success - move it to the real target try { - Directory.CreateDirectory(Path.GetDirectoryName(target)); - File.Copy(tempFile, target, true); + _fileSystem.CreateDirectory(Path.GetDirectoryName(target)); + _fileSystem.CopyFile(tempFile, target, true); //If it is an archive - write out a version file so we know what it is if (isArchive) { - File.WriteAllText(target + ".ver", package.versionStr); + _fileSystem.WriteAllText(target + ".ver", package.versionStr); } } catch (IOException e) diff --git a/MediaBrowser.Common/IO/IFileSystem.cs b/MediaBrowser.Common/IO/IFileSystem.cs index 5ce84f4360..60ba4c8aef 100644 --- a/MediaBrowser.Common/IO/IFileSystem.cs +++ b/MediaBrowser.Common/IO/IFileSystem.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Collections.Generic; +using System.Text; namespace MediaBrowser.Common.IO { @@ -73,7 +75,9 @@ namespace MediaBrowser.Common.IO /// The share. /// if set to true [is asynchronous]. /// FileStream. - FileStream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false); + Stream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false); + + Stream OpenRead(String path); /// /// Swaps the files. @@ -134,21 +138,6 @@ namespace MediaBrowser.Common.IO /// true if [is path file] [the specified path]; otherwise, false. bool IsPathFile(string path); - /// - /// Deletes the file. - /// - /// The path. - /// if set to true [send to recycle bin]. - void DeleteFile(string path, bool sendToRecycleBin); - - /// - /// Deletes the directory. - /// - /// The path. - /// if set to true [recursive]. - /// if set to true [send to recycle bin]. - void DeleteDirectory(string path, bool recursive, bool sendToRecycleBin); - /// /// Deletes the file. /// @@ -161,5 +150,41 @@ namespace MediaBrowser.Common.IO /// The path. /// if set to true [recursive]. void DeleteDirectory(string path, bool recursive); + + IEnumerable GetDirectories(string path, bool recursive = false); + + IEnumerable GetFiles(string path, bool recursive = false); + + IEnumerable GetFileSystemEntries(string path, bool recursive = false); + + void CreateDirectory(string path); + + void CopyFile(string source, string target, bool overwrite); + + void MoveFile(string source, string target); + + void MoveDirectory(string source, string target); + + bool DirectoryExists(string path); + + bool FileExists(string path); + + string ReadAllText(string path, Encoding encoding); + + string ReadAllText(string path); + + byte[] ReadAllBytes(string path); + + void WriteAllBytes(string path, byte[] bytes); + + void WriteAllText(string path, string text, Encoding encoding); + + void WriteAllText(string path, string text); + + void CreateFile(string path); + + void WriteAllLines(string path, string[] lines); + + string[] ReadAllLines(string path); } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 54267490df..25e742e7cc 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -683,7 +683,7 @@ namespace MediaBrowser.Controller.Entities { var files = fileSystemChildren.OfType() .Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase)) - .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly)) + .SelectMany(i => directoryService.GetFiles(i.FullName)) .ToList(); // Support plex/xbmc convention @@ -719,7 +719,7 @@ namespace MediaBrowser.Controller.Entities { var files = fileSystemChildren.OfType() .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase)) - .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly)); + .SelectMany(i => directoryService.GetFiles(i.FullName)); return LibraryManager.ResolvePaths(files, directoryService, null) .OfType