From 42542e10bf3a780f7f03cd94415aab51b3aa05c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 18 Jul 2015 15:32:59 -0400 Subject: add live tv to search --- .../Persistence/SqliteItemRepository.cs | 72 ++++++++++++++++++---- 1 file changed, 61 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 852fbd76c..788d12cbb 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1,5 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; @@ -867,7 +869,7 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("type=@type"); cmd.Parameters.Add(cmd, "@type", DbType.String).Value = includeTypes[0]; } - if (includeTypes.Length > 1) + else if (includeTypes.Length > 1) { var inClause = string.Join(",", includeTypes.Select(i => "'" + i + "'").ToArray()); whereClauses.Add(string.Format("type in ({0})", inClause)); @@ -930,6 +932,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@PersonName", DbType.String).Value = query.Person; } + if (!string.IsNullOrWhiteSpace(query.NameContains)) + { + whereClauses.Add("Name like @NameContains"); + cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%"; + } + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -947,16 +955,58 @@ namespace MediaBrowser.Server.Implementations.Persistence return whereClauses; } + private static readonly Type[] KnownTypes = + { + typeof(LiveTvProgram), + typeof(LiveTvChannel), + typeof(LiveTvVideoRecording), + typeof(LiveTvAudioRecording), + typeof(Series), + typeof(LiveTvAudioRecording), + typeof(LiveTvVideoRecording), + typeof(Audio), + typeof(MusicAlbum), + typeof(MusicArtist), + typeof(MusicGenre), + typeof(MusicVideo), + typeof(Movie), + typeof(BoxSet), + typeof(Episode), + typeof(Season), + typeof(Series), + typeof(Book), + typeof(CollectionFolder), + typeof(Folder), + typeof(Game), + typeof(GameGenre), + typeof(GameSystem), + typeof(Genre), + typeof(Person), + typeof(Photo), + typeof(PhotoAlbum), + typeof(Studio), + typeof(UserRootFolder), + typeof(UserView), + typeof(Video), + typeof(Year) + }; + + private static Dictionary GetTypeMapDictionary() + { + var dict = new Dictionary(); + + foreach (var t in KnownTypes) + { + dict[t.Name] = new[] { t.FullName }; + } + + dict["Recording"] = new[] { typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName }; + + return dict; + } + // Not crazy about having this all the way down here, but at least it's in one place - readonly Dictionary _types = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - {typeof(LiveTvProgram).Name, new []{typeof(LiveTvProgram).FullName}}, - {typeof(LiveTvChannel).Name, new []{typeof(LiveTvChannel).FullName}}, - {typeof(LiveTvVideoRecording).Name, new []{typeof(LiveTvVideoRecording).FullName}}, - {typeof(LiveTvAudioRecording).Name, new []{typeof(LiveTvAudioRecording).FullName}}, - {typeof(Series).Name, new []{typeof(Series).FullName}}, - {"Recording", new []{typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName}} - }; + readonly Dictionary _types = GetTypeMapDictionary(); private IEnumerable MapIncludeItemTypes(string value) { @@ -1260,7 +1310,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!string.IsNullOrWhiteSpace(query.NameContains)) { whereClauses.Add("Name like @NameContains"); - cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%"+query.NameContains+"%"; + cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%"; } return whereClauses; -- cgit v1.2.3 From 3178896004540c4a5884b9235a67ffbe3f58af0b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 19 Jul 2015 23:43:13 -0400 Subject: update subtitle methods --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 4 ++-- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 4 ++-- .../MediaBrowser.MediaEncoding.csproj | 1 - MediaBrowser.MediaEncoding/Subtitles/AssParser.cs | 1 + .../Subtitles/ISubtitleParser.cs | 1 + .../Subtitles/ISubtitleWriter.cs | 1 + MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs | 3 ++- MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs | 1 + MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs | 1 + MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs | 1 + .../Subtitles/SubtitleTrackInfo.cs | 22 ---------------------- MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs | 1 + MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs | 1 + .../MediaBrowser.Model.Portable.csproj | 6 ++++++ .../MediaBrowser.Model.net35.csproj | 6 ++++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 2 ++ MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs | 11 +++++++++++ MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs | 14 ++++++++++++++ .../Library/SearchEngine.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 2 ++ .../MediaEncoding/Subtitles/AssParserTests.cs | 1 + .../MediaEncoding/Subtitles/SrtParserTests.cs | 1 + .../MediaEncoding/Subtitles/VttWriterTest.cs | 1 + MediaBrowser.WebDashboard/Api/PackageCreator.cs | 12 ++++++------ 24 files changed, 65 insertions(+), 35 deletions(-) delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/SubtitleTrackInfo.cs create mode 100644 MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs create mode 100644 MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index dc5858e86..e7885a3f8 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -689,7 +689,7 @@ namespace MediaBrowser.Api.Playback // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), + subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), charsetParam, seconds.ToString(UsCulture)); } @@ -697,7 +697,7 @@ namespace MediaBrowser.Api.Playback var mediaPath = state.MediaPath ?? string.Empty; return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - mediaPath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), + mediaPath.Replace('\\', '/').Replace(":/", "\\:/"), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 97c5aecd0..fbfe79272 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -902,13 +902,13 @@ namespace MediaBrowser.MediaEncoding.Encoder // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), + subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), charsetParam, seconds.ToString(UsCulture)); } return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - state.MediaPath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), + state.MediaPath.Replace('\\', '/').Replace(":/", "\\:/"), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index ad561c484..de05d9ffd 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -81,7 +81,6 @@ - diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs index e711c02b6..6d723a087 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs index 5b072a450..75de81f46 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleWriter.cs index eb29e6c17..e28da9185 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleWriter.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs index a4fc5d795..474f712f9 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using System.IO; using System.Text; using System.Threading; diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index 9751176cb..d40d4afa7 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.IO; using System.Text.RegularExpressions; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs index 3e574f931..c05929fde 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs index bfc6c60fc..6c760658d 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -3,6 +3,7 @@ using System; using System.IO; using System.Text; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleTrackInfo.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleTrackInfo.cs deleted file mode 100644 index 67d70ed6e..000000000 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleTrackInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace MediaBrowser.MediaEncoding.Subtitles -{ - public class SubtitleTrackInfo - { - public List TrackEvents { get; set; } - - public SubtitleTrackInfo() - { - TrackEvents = new List(); - } - } - - public class SubtitleTrackEvent - { - public string Id { get; set; } - public string Text { get; set; } - public long StartPositionTicks { get; set; } - public long EndPositionTicks { get; set; } - } -} diff --git a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs index 955b36ecd..c32005f89 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs index fa53e4d13..092add992 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index a1b7ce396..90a185a97 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -821,6 +821,12 @@ MediaInfo\SubtitleFormat.cs + + MediaInfo\SubtitleTrackEvent.cs + + + MediaInfo\SubtitleTrackInfo.cs + MediaInfo\TransportStreamTimestamp.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index d4a373733..e7878fb1b 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -777,6 +777,12 @@ MediaInfo\SubtitleFormat.cs + + MediaInfo\SubtitleTrackEvent.cs + + + MediaInfo\SubtitleTrackInfo.cs + MediaInfo\TransportStreamTimestamp.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index b36fa2362..5c7caf407 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -169,6 +169,8 @@ + + diff --git a/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs b/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs new file mode 100644 index 000000000..b4ab6ed97 --- /dev/null +++ b/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs @@ -0,0 +1,11 @@ + +namespace MediaBrowser.Model.MediaInfo +{ + public class SubtitleTrackEvent + { + public string Id { get; set; } + public string Text { get; set; } + public long StartPositionTicks { get; set; } + public long EndPositionTicks { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs b/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs new file mode 100644 index 000000000..765cfe32f --- /dev/null +++ b/MediaBrowser.Model/MediaInfo/SubtitleTrackInfo.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.MediaInfo +{ + public class SubtitleTrackInfo + { + public List TrackEvents { get; set; } + + public SubtitleTrackInfo() + { + TrackEvents = new List(); + } + } +} diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index db8a2d4fd..abebd26cc 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.Library }).Items; // Add search hints based on item name - hints.AddRange(mediaItems.Where(i => (user == null || i.IsVisibleStandalone(user)) && !(i is CollectionFolder)).Select(item => + hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && (user == null || i.IsVisibleStandalone(user)) && !(i is CollectionFolder)).Select(item => { var index = GetIndex(item.Name, searchTerm, terms); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 788d12cbb..9ce239eb9 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1001,6 +1001,8 @@ namespace MediaBrowser.Server.Implementations.Persistence } dict["Recording"] = new[] { typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName }; + dict["Program"] = new[] { typeof(LiveTvProgram).FullName }; + dict["TvChannel"] = new[] { typeof(LiveTvChannel).FullName }; return dict; } diff --git a/MediaBrowser.Tests/MediaEncoding/Subtitles/AssParserTests.cs b/MediaBrowser.Tests/MediaEncoding/Subtitles/AssParserTests.cs index 02fd66b20..d5a62802d 100644 --- a/MediaBrowser.Tests/MediaEncoding/Subtitles/AssParserTests.cs +++ b/MediaBrowser.Tests/MediaEncoding/Subtitles/AssParserTests.cs @@ -1,5 +1,6 @@ using System.Text; using MediaBrowser.MediaEncoding.Subtitles; +using MediaBrowser.Model.MediaInfo; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using System.IO; diff --git a/MediaBrowser.Tests/MediaEncoding/Subtitles/SrtParserTests.cs b/MediaBrowser.Tests/MediaEncoding/Subtitles/SrtParserTests.cs index 8ea4398e9..07717a328 100644 --- a/MediaBrowser.Tests/MediaEncoding/Subtitles/SrtParserTests.cs +++ b/MediaBrowser.Tests/MediaEncoding/Subtitles/SrtParserTests.cs @@ -4,6 +4,7 @@ using System.IO; using System.Threading; using MediaBrowser.MediaEncoding.Subtitles; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MediaBrowser.Tests.MediaEncoding.Subtitles diff --git a/MediaBrowser.Tests/MediaEncoding/Subtitles/VttWriterTest.cs b/MediaBrowser.Tests/MediaEncoding/Subtitles/VttWriterTest.cs index 7a4823ecf..924a1736f 100644 --- a/MediaBrowser.Tests/MediaEncoding/Subtitles/VttWriterTest.cs +++ b/MediaBrowser.Tests/MediaEncoding/Subtitles/VttWriterTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading; using MediaBrowser.MediaEncoding.Subtitles; +using MediaBrowser.Model.MediaInfo; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MediaBrowser.Tests.MediaEncoding.Subtitles { diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 7f7aa4a2d..3be24ddf1 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -304,11 +304,11 @@ namespace MediaBrowser.WebDashboard.Api } } - var version = GetType().Assembly.GetName().Version; + var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + appVersion : string.Empty; var imports = new[] { - "vulcanize-out.html?v=" + appVersion + "vulcanize-out.html" + versionString }; var importsHtml = string.Join("", imports.Select(i => "").ToArray()); @@ -316,7 +316,7 @@ namespace MediaBrowser.WebDashboard.Api // In chrome it is causing the body to be hidden while loading, which leads to width-check methods to return 0 for everything //imports = ""; - html = html.Replace("", "" + GetMetaTags(mode) + GetCommonCss(mode, version) + GetInitialJavascript(mode, version) + importsHtml + GetCommonJavascript(mode, version)); + html = html.Replace("", "" + GetMetaTags(mode) + GetCommonCss(mode, appVersion) + GetInitialJavascript(mode, appVersion) + importsHtml + GetCommonJavascript(mode, appVersion)); var bytes = Encoding.UTF8.GetBytes(html); @@ -412,7 +412,7 @@ namespace MediaBrowser.WebDashboard.Api /// The mode. /// The version. /// System.String. - private string GetCommonCss(string mode, Version version) + private string GetCommonCss(string mode, string version) { var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + version : string.Empty; @@ -433,7 +433,7 @@ namespace MediaBrowser.WebDashboard.Api /// The mode. /// The version. /// System.String. - private string GetInitialJavascript(string mode, Version version) + private string GetInitialJavascript(string mode, string version) { var builder = new StringBuilder(); @@ -457,7 +457,7 @@ namespace MediaBrowser.WebDashboard.Api /// The mode. /// The version. /// System.String. - private string GetCommonJavascript(string mode, Version version) + private string GetCommonJavascript(string mode, string version) { var builder = new StringBuilder(); -- cgit v1.2.3 From 3799ad594080f6476119e59e8d4631c4354ee598 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 08:33:30 -0400 Subject: update task triggers --- .../ScheduledTasks/ScheduledTaskWorker.cs | 4 +- .../ScheduledTasks/Tasks/DeleteCacheFileTask.cs | 3 - .../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 3 - MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs | 8 ++- MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs | 8 ++- .../ScheduledTasks/IntervalTrigger.cs | 24 ++++++-- .../ScheduledTasks/StartupTrigger.cs | 8 ++- .../ScheduledTasks/SystemEventTrigger.cs | 7 ++- .../ScheduledTasks/WeeklyTrigger.cs | 4 +- MediaBrowser.Controller/Entities/BaseItem.cs | 12 ++++ .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Library/ILibraryManager.cs | 2 +- .../Channels/RefreshChannelsScheduledTask.cs | 4 -- .../LiveTv/LiveTvManager.cs | 44 +++++++------- .../LiveTv/RefreshChannelsScheduledTask.cs | 9 +-- .../Persistence/SqliteItemRepository.cs | 70 +++++++++++++--------- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 3 - .../Sync/SyncConvertScheduledTask.cs | 3 +- .../UserViews/DynamicImageProvider.cs | 4 -- 19 files changed, 127 insertions(+), 94 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index c2551731f..cbd1c1ac5 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -312,7 +312,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks trigger.Triggered -= trigger_Triggered; trigger.Triggered += trigger_Triggered; - trigger.Start(isApplicationStartup); + trigger.Start(LastExecutionResult, isApplicationStartup); } } @@ -340,7 +340,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks await Task.Delay(1000).ConfigureAwait(false); - trigger.Start(false); + trigger.Start(LastExecutionResult, false); } private Task _currentTask; diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index eb2b46c22..d9c178d8b 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -45,9 +45,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Until we can vary these default triggers per server and MBT, we need something that makes sense for both return new ITaskTrigger[] { - // At startup - new StartupTrigger {DelayMs = 60000}, - // Every so often new IntervalTrigger { Interval = TimeSpan.FromHours(24)} }; diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs index 6b9bcbfc1..b2759c52a 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -42,9 +42,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Until we can vary these default triggers per server and MBT, we need something that makes sense for both return new ITaskTrigger[] { - // At startup - new StartupTrigger {DelayMs = 30000}, - // Every so often new IntervalTrigger { Interval = TimeSpan.FromHours(24)} }; diff --git a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs index 2f935607b..382a41255 100644 --- a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -32,8 +33,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs index d30111316..8c87f8f38 100644 --- a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs @@ -1,5 +1,6 @@ -using System; -using MediaBrowser.Model.Events; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; namespace MediaBrowser.Common.ScheduledTasks { @@ -16,8 +17,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - void Start(bool isApplicationStartup); + void Start(TaskResult lastResult, bool isApplicationStartup); /// /// Stops waiting for the trigger action diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 455a70d7e..41073516a 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -32,12 +33,27 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); - Timer = new Timer(state => OnTriggered(), null, Interval, TimeSpan.FromMilliseconds(-1)); + var triggerDate = lastResult != null ? + lastResult.EndTimeUtc.Add(Interval) : + DateTime.UtcNow.Add(Interval); + + if (DateTime.UtcNow > triggerDate) + { + triggerDate = DateTime.UtcNow; + + if (isApplicationStartup) + { + triggerDate = triggerDate.AddMinutes(1); + } + } + + Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.UtcNow, TimeSpan.FromMilliseconds(-1)); } /// diff --git a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs index a58fa22b9..1d82dc76a 100644 --- a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading.Tasks; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -27,8 +28,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public async void Start(bool isApplicationStartup) + public async void Start(TaskResult lastResult, bool isApplicationStartup) { if (isApplicationStartup) { diff --git a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs index a40dc6b5c..eaf4afc75 100644 --- a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; using Microsoft.Win32; using System; using System.Threading.Tasks; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -28,8 +28,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { switch (SystemEvent) { diff --git a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs index a3818f83f..2e38264b2 100644 --- a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Common.ScheduledTasks { @@ -38,8 +39,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d9dbf265f..3062c00e7 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1115,6 +1115,18 @@ namespace MediaBrowser.Controller.Entities return value.Value <= maxAllowedRating.Value; } + public int? GetParentalRatingValue() + { + var rating = CustomRatingForComparison; + + if (string.IsNullOrWhiteSpace(rating)) + { + rating = OfficialRatingForComparison; + } + + return LocalizationManager.GetRatingLevel(rating); + } + private bool IsVisibleViaTags(User user) { var hasTags = this as IHasTags; diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 3702716f9..c9603c7e3 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -94,6 +94,7 @@ namespace MediaBrowser.Controller.Entities public string[] ChannelIds { get; set; } internal List ItemIdsFromPersonFilters { get; set; } + public int? MaxParentalRating { get; set; } public InternalItemsQuery() { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index f0bfaaf66..77c07dfd4 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -5,12 +5,12 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Library { diff --git a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index c6ecfc250..b1491d594 100644 --- a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -42,10 +42,6 @@ namespace MediaBrowser.Server.Implementations.Channels { return new ITaskTrigger[] { - new StartupTrigger{DelayMs = 10000}, - - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - new IntervalTrigger{ Interval = TimeSpan.FromHours(24)} }; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d8e60be5a..d8954724a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -13,6 +13,7 @@ using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; @@ -772,9 +773,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv MaxStartDate = query.MaxStartDate, ChannelIds = query.ChannelIds, IsMovie = query.IsMovie, - IsSports = query.IsSports + IsSports = query.IsSports, + Genres = query.Genres }; + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + if (user != null) + { + internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; + + if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) + { + internalQuery.HasParentalRating = true; + } + } + if (query.HasAired.HasValue) { if (query.HasAired.Value) @@ -789,20 +802,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); - // Apply genre filter - if (query.Genres.Length > 0) - { - programs = programs.Where(p => p.Genres.Any(g => query.Genres.Contains(g, StringComparer.OrdinalIgnoreCase))); - } - - var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); - if (user != null) - { - // Avoid implicitly captured closure - var currentUser = user; - programs = programs.Where(i => i.IsVisible(currentUser)); - } - programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending) .Cast(); @@ -860,13 +859,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); - var user = _userManager.GetUserById(query.UserId); + if (user != null) + { + internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; - // Avoid implicitly captured closure - var currentUser = user; - programs = programs.Where(i => i.IsVisible(currentUser)); + if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) + { + internalQuery.HasParentalRating = true; + } + } + + IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); var programList = programs.ToList(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs index fa1a8b3e7..d8d91c2f9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs @@ -2,7 +2,6 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Linq; @@ -47,11 +46,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { return new ITaskTrigger[] { - new StartupTrigger(), - - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - - new IntervalTrigger{ Interval = TimeSpan.FromHours(4)} + new IntervalTrigger{ Interval = TimeSpan.FromHours(12)} }; } @@ -59,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { return _config.GetConfiguration("livetv"); } - + public bool IsHidden { get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Count(i => i.IsEnabled) == 0; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9ce239eb9..3ec45c4de 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -157,6 +157,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "PremiereDate", "DATETIME"); _connection.AddColumn(_logger, "TypedBaseItems", "ProductionYear", "INT"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentId", "GUID"); + _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); PrepareStatements(); @@ -197,10 +199,12 @@ namespace MediaBrowser.Server.Implementations.Persistence "ParentIndexNumber", "PremiereDate", "ProductionYear", - "ParentId" + "ParentId", + "Genres", + "ParentalRatingValue" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24)"; for (var i = 1; i <= saveColumns.Count; i++) { _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); @@ -343,6 +347,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ParentId; } + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); + _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -937,7 +944,39 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("Name like @NameContains"); cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%"; } - + + if (query.Genres.Length > 0) + { + var genres = new List(); + var index = 0; + foreach (var genre in query.Genres) + { + genres.Add("Genres like @Genres" + index); + cmd.Parameters.Add(cmd, "@Genres" + index, DbType.String).Value = "%" + genre + "%"; + index++; + } + var genreCaluse = "(" + string.Join(" OR ", genres.ToArray()) + ")"; + whereClauses.Add(genreCaluse); + } + + if (query.MaxParentalRating.HasValue) + { + whereClauses.Add("(ParentalRatingValue is NULL OR ParentalRatingValue<=@MaxParentalRating)"); + cmd.Parameters.Add(cmd, "@MaxParentalRating", DbType.Int32).Value = query.MaxParentalRating.Value; + } + + if (query.HasParentalRating.HasValue) + { + if (query.HasParentalRating.Value) + { + whereClauses.Add("ParentalRatingValue NOT NULL"); + } + else + { + whereClauses.Add("ParentalRatingValue IS NULL"); + } + } + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -1021,31 +1060,6 @@ namespace MediaBrowser.Server.Implementations.Persistence return new[] { value }; } - public IEnumerable GetItemIdsOfType(Type type) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - CheckDisposed(); - - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "select guid from TypedBaseItems where type = @type"; - - cmd.Parameters.Add(cmd, "@type", DbType.String).Value = type.FullName; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - yield return reader.GetGuid(0); - } - } - } - } - public async Task DeleteItem(Guid id, CancellationToken cancellationToken) { if (id == Guid.Empty) diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index 0ac53c987..824d859f3 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Tasks; using MediaBrowser.Server.Implementations.Library; using System; using System.Collections.Generic; @@ -38,8 +37,6 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks new StartupTrigger(), - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - new IntervalTrigger{ Interval = TimeSpan.FromHours(6)} }; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs index 913d50e9d..5347e1d83 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs @@ -70,8 +70,7 @@ namespace MediaBrowser.Server.Implementations.Sync { return new ITaskTrigger[] { - new IntervalTrigger { Interval = TimeSpan.FromHours(3) }, - new StartupTrigger{ DelayMs = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalMilliseconds)} + new IntervalTrigger { Interval = TimeSpan.FromHours(3) } }; } diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 3d77f831e..0162b8802 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -143,7 +143,6 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.TvFavoriteEpisodes, SpecialFolder.TvFavoriteSeries, SpecialFolder.TvGenres, - SpecialFolder.TvGenre, SpecialFolder.TvLatest, SpecialFolder.TvNextUp, SpecialFolder.TvResume, @@ -152,14 +151,12 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.MovieCollections, SpecialFolder.MovieFavorites, SpecialFolder.MovieGenres, - SpecialFolder.MovieGenre, SpecialFolder.MovieLatest, SpecialFolder.MovieMovies, SpecialFolder.MovieResume, SpecialFolder.GameFavorites, SpecialFolder.GameGenres, - SpecialFolder.GameGenre, SpecialFolder.GameSystems, SpecialFolder.LatestGames, SpecialFolder.RecentlyPlayedGames, @@ -168,7 +165,6 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.MusicAlbumArtists, SpecialFolder.MusicAlbums, SpecialFolder.MusicGenres, - SpecialFolder.MusicGenre, SpecialFolder.MusicLatest, SpecialFolder.MusicPlaylists, SpecialFolder.MusicSongs, -- cgit v1.2.3 From 8046a514187f0ef003c2d828dcf31de6e85ecedb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 24 Aug 2015 23:13:04 -0400 Subject: add more live tv buttons --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 11 +++++- MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs | 6 ++++ .../LiveTv/LiveTvManager.cs | 40 +++++++--------------- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 4 +-- .../Persistence/SqliteItemRepository.cs | 34 +++++++++++++++++- 5 files changed, 64 insertions(+), 31 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index d47a7e2d6..07e64c98d 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -78,6 +78,14 @@ namespace MediaBrowser.Api.LiveTv /// The fields. [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + [ApiMember(Name = "AddCurrentProgram", Description = "Optional. Adds current program info to each channel", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool AddCurrentProgram { get; set; } + + public GetChannels() + { + AddCurrentProgram = true; + } } [Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")] @@ -582,7 +590,8 @@ namespace MediaBrowser.Api.LiveTv IsFavorite = request.IsFavorite, IsLiked = request.IsLiked, IsDisliked = request.IsDisliked, - EnableFavoriteSorting = request.EnableFavoriteSorting + EnableFavoriteSorting = request.EnableFavoriteSorting, + AddCurrentProgram = request.AddCurrentProgram }, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index 900537b7a..3a6ad0444 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -53,5 +53,11 @@ namespace MediaBrowser.Model.LiveTv /// /// The limit. public int? Limit { get; set; } + + /// + /// Gets or sets a value indicating whether [add current program]. + /// + /// true if [add current program]; otherwise, false. + public bool AddCurrentProgram { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 653adb716..9cd4a2334 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -251,13 +251,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv var now = DateTime.UtcNow; - var programs = _libraryManager.QueryItems(new InternalItemsQuery + var programs = query.AddCurrentProgram ? _libraryManager.QueryItems(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, MaxStartDate = now, - MinEndDate = now + MinEndDate = now, + ChannelIds = internalResult.Items.Select(i => i.Id.ToString("N")).ToArray() - }).Items.Cast().OrderBy(i => i.StartDate).ToList(); + }).Items.Cast().OrderBy(i => i.StartDate).ToList() : new List(); foreach (var channel in internalResult.Items) { @@ -776,7 +777,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv IsMovie = query.IsMovie, IsSports = query.IsSports, IsKids = query.IsKids, - Genres = query.Genres + Genres = query.Genres, + StartIndex = query.StartIndex, + Limit = query.Limit, + SortBy = query.SortBy, + SortOrder = query.SortOrder ?? SortOrder.Ascending }; var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -802,29 +807,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable programs = _libraryManager.QueryItems(internalQuery).Items.Cast(); - - programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending) - .Cast(); - - var programList = programs.ToList(); - IEnumerable returnPrograms = programList; - - if (query.StartIndex.HasValue) - { - returnPrograms = returnPrograms.Skip(query.StartIndex.Value); - } + var queryResult = _libraryManager.QueryItems(internalQuery); - if (query.Limit.HasValue) - { - returnPrograms = returnPrograms.Take(query.Limit.Value); - } - - var returnArray = returnPrograms - .Select(i => - { - return _dtoService.GetBaseItemDto(i, options, user); - }) + var returnArray = queryResult.Items + .Select(i => _dtoService.GetBaseItemDto(i, options, user)) .ToArray(); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); @@ -832,7 +818,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var result = new QueryResult { Items = returnArray, - TotalRecordCount = programList.Count + TotalRecordCount = queryResult.TotalRecordCount }; return result; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 4bbbf5a4d..cab21bc3a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) { - string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); + var model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); using (var stream = await _httpClient.Get(new HttpRequestOptions() { @@ -398,7 +398,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var info = await GetTunerInfos(tuner, cancellationToken).ConfigureAwait(false); - return info.Any(i => i.Status == LiveTvTunerStatus.Available); + return info.Any(i => i.Status == LiveTvTunerStatus.Available || string.Equals(i.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)); } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3ec45c4de..f6a04f303 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -712,6 +712,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -719,6 +721,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; + _logger.Debug(cmd.CommandText); + var list = new List(); var count = 0; @@ -747,6 +751,28 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + private string GetOrderByText(InternalItemsQuery query) + { + if (query.SortBy == null || query.SortBy.Length == 0) + { + return string.Empty; + } + + var sortOrder = query.SortOrder == SortOrder.Descending ? "DESC" : "ASC"; + + return " ORDER BY " + string.Join(",", query.SortBy.Select(i => MapOrderByField(i) + " " + sortOrder).ToArray()); + } + + private string MapOrderByField(string name) + { + if (string.Equals(name, "sortname", StringComparison.OrdinalIgnoreCase)) + { + return "name"; + } + + return name; + } + public List GetItemIdsList(InternalItemsQuery query) { if (query == null) @@ -768,6 +794,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -816,6 +844,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -985,7 +1015,9 @@ namespace MediaBrowser.Server.Implementations.Persistence string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM TypedBaseItems {0} ORDER BY DateCreated DESC LIMIT {1})", + var orderBy = GetOrderByText(query); + + whereClauses.Add(string.Format("guid NOT IN (SELECT guid FROM TypedBaseItems {0}" + orderBy + " LIMIT {1})", pagingWhereText, query.StartIndex.Value.ToString(CultureInfo.InvariantCulture))); } -- cgit v1.2.3 From 3e1bbcdcea8d78fd3845e13a4edf107cbcdf0640 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 26 Aug 2015 01:10:04 -0400 Subject: add clean db task --- .../Entities/InternalItemsQuery.cs | 2 + .../MediaBrowser.Server.Implementations.csproj | 1 + .../Persistence/CleanDatabaseScheduledTask.cs | 89 ++++++++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 23 +++++- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 227a6bd0e..53667c6e1 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -96,6 +96,8 @@ namespace MediaBrowser.Controller.Entities internal List ItemIdsFromPersonFilters { get; set; } public int? MaxParentalRating { get; set; } + public bool? IsCurrentSchema { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 74329b08f..b2da2489d 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -241,6 +241,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs new file mode 100644 index 000000000..c29204702 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Common.Progress; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + class CleanDatabaseScheduledTask : IScheduledTask + { + private readonly ILibraryManager _libraryManager; + private readonly IItemRepository _itemRepo; + private readonly ILogger _logger; + + public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger) + { + _libraryManager = libraryManager; + _itemRepo = itemRepo; + _logger = logger; + } + + public string Name + { + get { return "Clean Database"; } + } + + public string Description + { + get { return "Deletes obsolete content from the database."; } + } + + public string Category + { + get { return "Library"; } + } + + public async Task Execute(CancellationToken cancellationToken, IProgress progress) + { + var innerProgress = new ActionableProgress(); + innerProgress.RegisterAction(progress.Report); + + await UpdateToLatestSchema(cancellationToken, innerProgress).ConfigureAwait(false); + } + + private async Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress progress) + { + var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IsCurrentSchema = false, + Limit = 50000 + }); + + var numComplete = 0; + var numItems = itemIds.Count; + + _logger.Debug("Upgrading schema for {0} items", numItems); + + foreach (var itemId in itemIds) + { + var item = _libraryManager.GetItemById(itemId); + + if (item != null) + { + await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false); + } + + numComplete++; + double percent = numComplete; + percent /= numItems; + progress.Report(percent * 100); + } + + progress.Report(100); + } + + public IEnumerable GetDefaultTriggers() + { + return new ITaskTrigger[] + { + new IntervalTrigger{ Interval = TimeSpan.FromDays(1)} + }; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index f6a04f303..73f292622 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -71,6 +71,9 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; + + private const int LatestSchemaVersion = 2; + /// /// Initializes a new instance of the class. /// @@ -159,6 +162,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "ParentId", "GUID"); _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "SchemaVersion", "INT"); PrepareStatements(); @@ -201,10 +205,11 @@ namespace MediaBrowser.Server.Implementations.Persistence "ProductionYear", "ParentId", "Genres", - "ParentalRatingValue" + "ParentalRatingValue", + "SchemaVersion" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24, @25)"; for (var i = 1; i <= saveColumns.Count; i++) { _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); @@ -350,6 +355,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); + _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -883,6 +890,18 @@ namespace MediaBrowser.Server.Implementations.Persistence { var whereClauses = new List(); + if (query.IsCurrentSchema.HasValue) + { + if (query.IsCurrentSchema.Value) + { + whereClauses.Add("(SchemaVersion not null AND SchemaVersion=@SchemaVersion)"); + } + else + { + whereClauses.Add("(SchemaVersion is null or SchemaVersion<>@SchemaVersion)"); + } + cmd.Parameters.Add(cmd, "@SchemaVersion", DbType.Int32).Value = LatestSchemaVersion; + } if (query.IsMovie.HasValue) { whereClauses.Add("IsMovie=@IsMovie"); -- cgit v1.2.3 From d4050fbf2cbec98306d3f39c2cf7b620147afdee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 26 Aug 2015 14:17:38 -0400 Subject: update photos --- .../LiveTv/Listings/SchedulesDirect.cs | 2 +- .../Persistence/CleanDatabaseScheduledTask.cs | 8 +++- .../Persistence/SqliteItemRepository.cs | 49 +++++++++++++++++----- SharedVersion.cs | 4 +- 4 files changed, 49 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 129f922b3..708891e68 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -317,7 +317,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-").Replace("--", "-"); - var invalid = new[] { "N/A", "Approved", "Not Rated" }; + var invalid = new[] { "N/A", "Approved", "Not Rated", "Passed" }; if (invalid.Contains(info.OfficialRating, StringComparer.OrdinalIgnoreCase)) { info.OfficialRating = null; diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index c29204702..69e04c072 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using System; using System.Collections.Generic; @@ -52,7 +53,10 @@ namespace MediaBrowser.Server.Implementations.Persistence var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery { IsCurrentSchema = false, - Limit = 50000 + Limit = 100000, + + // These are constantly getting regenerated so don't bother with them here + ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name } }); var numComplete = 0; @@ -62,6 +66,8 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var itemId in itemIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(itemId); if (item != null) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 73f292622..71578d1e0 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; - private const int LatestSchemaVersion = 2; + private const int LatestSchemaVersion = 4; /// /// Initializes a new instance of the class. @@ -163,6 +163,15 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); _connection.AddColumn(_logger, "TypedBaseItems", "SchemaVersion", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "SortName", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); + + _connection.AddColumn(_logger, "TypedBaseItems", "OfficialRatingDescription", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "HomePageUrl", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "VoteCount", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "DisplayMediaType", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "DateCreated", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "DateModified", "DATETIME"); PrepareStatements(); @@ -206,14 +215,30 @@ namespace MediaBrowser.Server.Implementations.Persistence "ParentId", "Genres", "ParentalRatingValue", - "SchemaVersion" + "SchemaVersion", + "SortName", + "RunTimeTicks", + "OfficialRatingDescription", + "HomePageUrl", + "VoteCount", + "DisplayMediaType", + "DateCreated", + "DateModified" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24, @25)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; + for (var i = 1; i <= saveColumns.Count; i++) { + if (i > 1) + { + _saveItemCommand.CommandText += ","; + } + _saveItemCommand.CommandText += "@" + i.ToString(CultureInfo.InvariantCulture); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); } + _saveItemCommand.CommandText += ")"; _deleteChildrenCommand = _connection.CreateCommand(); _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; @@ -356,7 +381,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; - + _saveItemCommand.GetParameter(index++).Value = item.SortName; + _saveItemCommand.GetParameter(index++).Value = item.RunTimeTicks; + + _saveItemCommand.GetParameter(index++).Value = item.OfficialRatingDescription; + _saveItemCommand.GetParameter(index++).Value = item.HomePageUrl; + _saveItemCommand.GetParameter(index++).Value = item.VoteCount; + _saveItemCommand.GetParameter(index++).Value = item.DisplayMediaType; + _saveItemCommand.GetParameter(index++).Value = item.DateCreated; + _saveItemCommand.GetParameter(index++).Value = item.DateModified; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -729,7 +763,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; _logger.Debug(cmd.CommandText); - + var list = new List(); var count = 0; @@ -772,11 +806,6 @@ namespace MediaBrowser.Server.Implementations.Persistence private string MapOrderByField(string name) { - if (string.Equals(name, "sortname", StringComparison.OrdinalIgnoreCase)) - { - return "name"; - } - return name; } diff --git a/SharedVersion.cs b/SharedVersion.cs index bef2d6af2..ec5cb5676 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5713.3")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5713.3")] -- cgit v1.2.3 From 5b21ec6747f5c1eef8b44ad8ead4f89ed715a501 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 26 Aug 2015 21:31:54 -0400 Subject: update interval trigger --- MediaBrowser.Api/StartupWizardService.cs | 1 + .../ScheduledTasks/IntervalTrigger.cs | 13 ++- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Dlna/DlnaManager.cs | 3 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 4 +- MediaBrowser.Dlna/Profiles/KodiProfile.cs | 97 ++++++++++++++++++++++ .../Configuration/ServerConfiguration.cs | 6 ++ .../MediaInfo/SubtitleScheduledTask.cs | 2 +- .../IO/LibraryMonitor.cs | 20 +++++ .../LiveTv/Listings/SchedulesDirect.cs | 9 +- .../Persistence/CleanDatabaseScheduledTask.cs | 14 +++- .../Persistence/SqliteItemRepository.cs | 26 +++++- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 22 +++-- 13 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/KodiProfile.cs (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 9eb96873b..e9ac45fa2 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -72,6 +72,7 @@ namespace MediaBrowser.Api _config.Configuration.EnableUserSpecificUserViews = true; _config.Configuration.EnableCustomPathSubFolders = true; _config.Configuration.DisableXmlSavers = true; + _config.Configuration.DisableStartupScan = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 15109be4f..b615adf81 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -30,6 +30,17 @@ namespace MediaBrowser.Common.ScheduledTasks /// public TaskExecutionOptions TaskOptions { get; set; } + /// + /// Gets or sets the first run delay. + /// + /// The first run delay. + public TimeSpan FirstRunDelay { get; set; } + + public IntervalTrigger() + { + FirstRunDelay = TimeSpan.FromHours(1); + } + /// /// Stars waiting for the trigger action /// @@ -41,7 +52,7 @@ namespace MediaBrowser.Common.ScheduledTasks var triggerDate = lastResult != null ? lastResult.EndTimeUtc.Add(Interval) : - DateTime.UtcNow.Add(Interval); + DateTime.UtcNow.Add(FirstRunDelay); if (DateTime.UtcNow > triggerDate) { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cd5c39173..a333fc6e9 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities public virtual string Path { get; set; } [IgnoreDataMember] - protected internal bool IsOffline { get; set; } + public bool IsOffline { get; set; } /// /// Returns the folder containing the item. diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 9ce62034b..124d0e675 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -547,7 +547,8 @@ namespace MediaBrowser.Dlna new DefaultProfile(), new PopcornHourProfile(), new VlcProfile(), - new BubbleUpnpProfile() + new BubbleUpnpProfile(), + new KodiProfile() }; foreach (var item in list) diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 2a495638a..055173a7c 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -166,7 +166,9 @@ - + + Designer + diff --git a/MediaBrowser.Dlna/Profiles/KodiProfile.cs b/MediaBrowser.Dlna/Profiles/KodiProfile.cs new file mode 100644 index 000000000..75c323a1a --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/KodiProfile.cs @@ -0,0 +1,97 @@ +using MediaBrowser.Model.Dlna; +using System.Xml.Serialization; + +namespace MediaBrowser.Dlna.Profiles +{ + [XmlRoot("Profile")] + public class KodiProfile : DefaultProfile + { + public KodiProfile() + { + Name = "Kodi"; + + MaxStreamingBitrate = 100000000; + MaxStaticBitrate = 100000000; + MusicStreamingTranscodingBitrate = 1280000; + MusicSyncBitrate = 1280000; + + TimelineOffsetSeconds = 5; + + Identification = new DeviceIdentification + { + ModelName = "Kodi", + + Headers = new[] + { + new HttpHeaderInfo {Name = "User-Agent", Value = "Kodi", Match = HeaderMatchType.Substring} + } + }; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + + new TranscodingProfile + { + Container = "ts", + Type = DlnaProfileType.Video, + AudioCodec = "aac", + VideoCodec = "h264" + }, + + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Photo, + } + }; + + ResponseProfiles = new ResponseProfile[] { }; + + ContainerProfiles = new ContainerProfile[] { }; + + CodecProfiles = new CodecProfile[] { }; + + SubtitleProfiles = new[] + { + new SubtitleProfile + { + Format = "srt", + Method = SubtitleDeliveryMethod.External, + }, + + new SubtitleProfile + { + Format = "sub", + Method = SubtitleDeliveryMethod.External, + } + }; + } + } +} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 46f9db580..07d5905c6 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -98,6 +98,12 @@ namespace MediaBrowser.Model.Configuration /// true if [enable localized guids]; otherwise, false. public bool EnableLocalizedGuids { get; set; } + /// + /// Gets or sets a value indicating whether [disable startup scan]. + /// + /// true if [disable startup scan]; otherwise, false. + public bool DisableStartupScan { get; set; } + /// /// Gets or sets a value indicating whether [enable library metadata sub folder]. /// diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs index 0f092b554..4953621f5 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs @@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.MediaInfo { return new ITaskTrigger[] { - new DailyTrigger { TimeOfDay = TimeSpan.FromHours(3) }, + new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} }; } } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index e1c529187..5bd26ce18 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.ScheduledTasks; @@ -700,4 +701,23 @@ namespace MediaBrowser.Server.Implementations.IO } } } + + public class LibraryMonitorStartup : IServerEntryPoint + { + private readonly ILibraryMonitor _monitor; + + public LibraryMonitorStartup(ILibraryMonitor monitor) + { + _monitor = monitor; + } + + public void Run() + { + _monitor.Start(); + } + + public void Dispose() + { + } + } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 708891e68..cb5a37401 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -438,8 +438,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return lineups; } - _logger.Info("Headends on account "); - var options = new HttpRequestOptions() { Url = ApiUrl + "/headends?country=" + country + "&postalcode=" + location, @@ -454,16 +452,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings using (Stream responce = await _httpClient.Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream>(responce); - _logger.Info("Lineups on account "); + if (root != null) { foreach (ScheduleDirect.Headends headend in root) { - _logger.Info("Headend: " + headend.headend); foreach (ScheduleDirect.Lineup lineup in headend.lineups) { - _logger.Info("Headend: " + lineup.uri); - lineups.Add(new NameIdPair { Name = string.IsNullOrWhiteSpace(lineup.name) ? lineup.lineup : lineup.name, @@ -474,7 +469,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } else { - _logger.Info("No lineups on account"); + _logger.Info("No lineups available"); } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 69e04c072..7a993b7db 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -1,14 +1,15 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Persistence { @@ -17,12 +18,14 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly ILibraryManager _libraryManager; private readonly IItemRepository _itemRepo; private readonly ILogger _logger; + private readonly IServerConfigurationManager _config; - public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger) + public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config) { _libraryManager = libraryManager; _itemRepo = itemRepo; _logger = logger; + _config = config; } public string Name @@ -53,7 +56,6 @@ namespace MediaBrowser.Server.Implementations.Persistence var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery { IsCurrentSchema = false, - Limit = 100000, // These are constantly getting regenerated so don't bother with them here ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name } @@ -81,6 +83,12 @@ namespace MediaBrowser.Server.Implementations.Persistence progress.Report(percent * 100); } + if (!_config.Configuration.DisableStartupScan) + { + _config.Configuration.DisableStartupScan = true; + _config.SaveConfiguration(); + } + progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 71578d1e0..806e86a5a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; - private const int LatestSchemaVersion = 4; + private const int LatestSchemaVersion = 6; /// /// Initializes a new instance of the class. @@ -173,6 +173,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "DateCreated", "DATETIME"); _connection.AddColumn(_logger, "TypedBaseItems", "DateModified", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "ForcedSortName", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT"); + PrepareStatements(); _mediaStreamsRepository.Initialize(); @@ -223,7 +226,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "VoteCount", "DisplayMediaType", "DateCreated", - "DateModified" + "DateModified", + "ForcedSortName", + "IsOffline" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -391,6 +396,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.DateCreated; _saveItemCommand.GetParameter(index++).Value = item.DateModified; + _saveItemCommand.GetParameter(index++).Value = item.ForcedSortName; + _saveItemCommand.GetParameter(index++).Value = item.IsOffline; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -948,7 +956,6 @@ namespace MediaBrowser.Server.Implementations.Persistence } var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); - if (includeTypes.Length == 1) { whereClauses.Add("type=@type"); @@ -959,6 +966,19 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", includeTypes.Select(i => "'" + i + "'").ToArray()); whereClauses.Add(string.Format("type in ({0})", inClause)); } + + var excludeTypes = query.ExcludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); + if (excludeTypes.Length == 1) + { + whereClauses.Add("type<>@type"); + cmd.Parameters.Add(cmd, "@type", DbType.String).Value = excludeTypes[0]; + } + else if (excludeTypes.Length > 1) + { + var inClause = string.Join(",", excludeTypes.Select(i => "'" + i + "'").ToArray()); + whereClauses.Add(string.Format("type not in ({0})", inClause)); + } + if (query.ChannelIds.Length == 1) { whereClauses.Add("ChannelId=@ChannelId"); diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index ed284a90d..8cb76393e 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Common.ScheduledTasks; +using System.Linq; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Server.Implementations.Library; using System; @@ -17,14 +19,16 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// The _library manager /// private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; /// /// Initializes a new instance of the class. /// /// The library manager. - public RefreshMediaLibraryTask(ILibraryManager libraryManager) + public RefreshMediaLibraryTask(ILibraryManager libraryManager, IServerConfigurationManager config) { _libraryManager = libraryManager; + _config = config; } /// @@ -33,12 +37,18 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// IEnumerable{BaseTaskTrigger}. public IEnumerable GetDefaultTriggers() { - return new ITaskTrigger[] { - - new StartupTrigger(), + var list = new ITaskTrigger[] { new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} - }; + + }.ToList(); + + if (!_config.Configuration.DisableStartupScan) + { + list.Add(new StartupTrigger()); + } + + return list; } /// -- cgit v1.2.3 From 4ca526979ddb665ce905cd5943738a2c5657ab31 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 27 Aug 2015 11:58:07 -0400 Subject: 3.0.5713.4 --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 17 +-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 32 ++++- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 152 +++++++++------------ MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 4 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 26 ++-- MediaBrowser.Model/Entities/MediaStream.cs | 7 +- .../MediaInfo/FFProbeVideoInfo.cs | 16 +-- .../Persistence/SqliteItemRepository.cs | 33 ++++- .../Persistence/SqliteMediaStreamsRepository.cs | 58 +++++++- SharedVersion.cs | 4 +- 10 files changed, 213 insertions(+), 136 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 33f3210a9..45e0e8b8a 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1634,11 +1634,6 @@ namespace MediaBrowser.Api.Playback private void TryStreamCopy(StreamState state, VideoStreamRequest videoRequest) { - if (!EnableStreamCopy) - { - return; - } - if (state.VideoStream != null && CanStreamCopyVideo(videoRequest, state.VideoStream)) { state.OutputVideoCodec = "copy"; @@ -1650,14 +1645,6 @@ namespace MediaBrowser.Api.Playback } } - protected virtual bool EnableStreamCopy - { - get - { - return true; - } - } - private void AttachMediaSourceInfo(StreamState state, MediaSourceInfo mediaSource, VideoStreamRequest videoRequest, @@ -1741,7 +1728,7 @@ namespace MediaBrowser.Api.Playback state.MediaSource = mediaSource; } - private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + protected virtual bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) { if (videoStream.IsInterlaced) { @@ -1889,7 +1876,7 @@ namespace MediaBrowser.Api.Playback return Array.FindIndex(list.ToArray(), t => string.Equals(t, profile, StringComparison.OrdinalIgnoreCase)); } - private bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List supportedAudioCodecs) + protected virtual bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List supportedAudioCodecs) { // Source and target codecs must match if (string.IsNullOrEmpty(audioStream.Codec) || !supportedAudioCodecs.Contains(audioStream.Codec, StringComparer.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index b2ffeca3d..1a152790a 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -1,9 +1,11 @@ -using MediaBrowser.Common.IO; +using System.Linq; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; @@ -310,5 +312,33 @@ namespace MediaBrowser.Api.Playback.Hls { return 0; } + + protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + { + if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) + { + 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) + { + 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 27429b8db..04979fc3a 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -160,7 +160,6 @@ namespace MediaBrowser.Api.Playback.Hls var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".m3u8"); var segmentPath = GetSegmentPath(state, playlistPath, requestedIndex); - var segmentLength = state.SegmentLength; var segmentExtension = GetSegmentFileExtension(state); @@ -169,7 +168,7 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); @@ -178,7 +177,7 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } else { @@ -214,7 +213,7 @@ namespace MediaBrowser.Api.Playback.Hls DeleteLastFile(playlistPath, segmentExtension, 0); } - request.StartTimeTicks = GetSeekPositionTicks(state, playlistPath, requestedIndex); + request.StartTimeTicks = GetStartPositionTicks(state, requestedIndex); job = await StartFfMpeg(state, playlistPath, cancellationTokenSource).ConfigureAwait(false); } @@ -249,37 +248,76 @@ namespace MediaBrowser.Api.Playback.Hls Logger.Info("returning {0}", segmentPath); job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } // 256k private const int BufferSize = 262144; - private long GetSeekPositionTicks(StreamState state, string playlist, int requestedIndex) + private long GetStartPositionTicks(StreamState state, int requestedIndex) { double startSeconds = 0; + var lengths = GetSegmentLengths(state); for (var i = 0; i < requestedIndex; i++) { - var segmentPath = GetSegmentPath(state, playlist, i); + startSeconds += lengths[requestedIndex]; + } + + var position = TimeSpan.FromSeconds(startSeconds).Ticks; + return position; + } - //double length; - //if (SegmentLengths.TryGetValue(Path.GetFileName(segmentPath), out length)) - //{ - // Logger.Debug("Found segment length of {0} for index {1}", length, i); - // startSeconds += length; - //} - //else - //{ - // startSeconds += state.SegmentLength; - //} - startSeconds += state.SegmentLength; + private long GetEndPositionTicks(StreamState state, int requestedIndex) + { + double startSeconds = 0; + var lengths = GetSegmentLengths(state); + + for (var i = 0; i <= requestedIndex; i++) + { + startSeconds += lengths[requestedIndex]; } var position = TimeSpan.FromSeconds(startSeconds).Ticks; return position; } + private double[] GetSegmentLengths(StreamState state) + { + var result = new List(); + var encoder = GetVideoEncoder(state); + + if (string.Equals(encoder, "copy", StringComparison.OrdinalIgnoreCase)) + { + var videoStream = state.VideoStream; + if (videoStream.KeyFrames != null && videoStream.KeyFrames.Count > 0) + { + foreach (var frame in videoStream.KeyFrames) + { + var seconds = TimeSpan.FromMilliseconds(frame).TotalSeconds; + seconds -= result.Sum(); + result.Add(seconds); + } + return result.ToArray(); + } + } + + var ticks = state.RunTimeTicks ?? 0; + + var segmentLengthTicks = TimeSpan.FromSeconds(state.SegmentLength).Ticks; + + while (ticks > 0) + { + var length = ticks >= segmentLengthTicks ? segmentLengthTicks : ticks; + + result.Add(TimeSpan.FromTicks(length).TotalSeconds); + + ticks -= length; + } + + return result.ToArray(); + } + public int? GetCurrentTranscodingIndex(string playlist, string segmentExtension) { var job = ApiEntryPoint.Instance.GetTranscodingJob(playlist, TranscodingJobType); @@ -384,17 +422,16 @@ namespace MediaBrowser.Api.Playback.Hls return Path.Combine(folder, filename + index.ToString(UsCulture) + GetSegmentFileExtension(state)); } - private async Task GetSegmentResult(string playlistPath, + private async Task GetSegmentResult(StreamState state, string playlistPath, string segmentPath, int segmentIndex, - int segmentLength, TranscodingJob transcodingJob, CancellationToken cancellationToken) { // If all transcoding has completed, just return immediately if (transcodingJob != null && transcodingJob.HasExited && File.Exists(segmentPath)) { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } var segmentFilename = Path.GetFileName(segmentPath); @@ -414,7 +451,7 @@ namespace MediaBrowser.Api.Playback.Hls { if (File.Exists(segmentPath)) { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } //break; } @@ -465,13 +502,12 @@ namespace MediaBrowser.Api.Playback.Hls //} cancellationToken.ThrowIfCancellationRequested(); - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } - private object GetSegmentResult(string segmentPath, int index, int segmentLength, TranscodingJob transcodingJob) + private object GetSegmentResult(StreamState state, string segmentPath, int index, TranscodingJob transcodingJob) { - var segmentEndingSeconds = (1 + index) * segmentLength; - var segmentEndingPositionTicks = TimeSpan.FromSeconds(segmentEndingSeconds).Ticks; + var segmentEndingPositionTicks = GetEndPositionTicks(state, index); return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { @@ -698,26 +734,22 @@ namespace MediaBrowser.Api.Playback.Hls { var state = await GetState(request, CancellationToken.None).ConfigureAwait(false); + var segmentLengths = GetSegmentLengths(state); + var builder = new StringBuilder(); builder.AppendLine("#EXTM3U"); builder.AppendLine("#EXT-X-VERSION:3"); - builder.AppendLine("#EXT-X-TARGETDURATION:" + (state.SegmentLength).ToString(UsCulture)); + builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling((segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength)).ToString(UsCulture)); builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); var queryStringIndex = Request.RawUrl.IndexOf('?'); var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex); - var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds; - var index = 0; - double segmentLength = state.SegmentLength; - - while (seconds > 0) + foreach (var length in segmentLengths) { - var length = seconds >= state.SegmentLength ? segmentLength : seconds; - builder.AppendLine("#EXTINF:" + length.ToString("0.000000", UsCulture) + ","); builder.AppendLine(string.Format("hlsdynamic/{0}/{1}{2}{3}", @@ -727,7 +759,6 @@ namespace MediaBrowser.Api.Playback.Hls GetSegmentFileExtension(isOutputVideo), queryString)); - seconds -= length; index++; } @@ -850,11 +881,6 @@ namespace MediaBrowser.Api.Playback.Hls args += " -flags +loop-global_header -sc_threshold 0"; } - if (!EnableSplitTranscoding(state)) - { - //args += " -copyts"; - } - return args; } @@ -870,21 +896,6 @@ namespace MediaBrowser.Api.Playback.Hls var toTimeParam = string.Empty; var timestampOffsetParam = string.Empty; - if (EnableSplitTranscoding(state)) - { - var startTime = state.Request.StartTimeTicks ?? 0; - var durationSeconds = ApiEntryPoint.Instance.GetEncodingOptions().ThrottleThresholdInSeconds; - - var endTime = startTime + TimeSpan.FromSeconds(durationSeconds).Ticks; - endTime = Math.Min(endTime, state.RunTimeTicks.Value); - - if (endTime < state.RunTimeTicks.Value) - { - //toTimeParam = " -to " + MediaEncoder.GetTimeParameter(endTime); - toTimeParam = " -t " + MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(durationSeconds).Ticks); - } - } - if (state.IsOutputVideo && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0) { timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0).ToString(CultureInfo.InvariantCulture); @@ -927,36 +938,7 @@ namespace MediaBrowser.Api.Playback.Hls protected override bool EnableThrottling(StreamState state) { - return !EnableSplitTranscoding(state); - } - - private bool EnableSplitTranscoding(StreamState state) - { - return false; - if (string.Equals(Request.QueryString["EnableSplitTranscoding"], "false", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - return state.RunTimeTicks.HasValue && state.IsOutputVideo; - } - - protected override bool EnableStreamCopy - { - get - { - return false; - } + return true; } /// diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index a8cd3257c..c49cbc654 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -226,7 +226,9 @@ - + + Designer +