From 28ab28768a307d1cac60ebe79163b98291068cde Mon Sep 17 00:00:00 2001 From: Sven Van den brande Date: Thu, 31 Oct 2013 21:45:58 +0100 Subject: [PATCH 1/3] Adding RecordingInfo --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 65 ++++++++++++------ MediaBrowser.Controller/LiveTv/ChannelInfo.cs | 2 + .../LiveTv/ILiveTvManager.cs | 3 +- .../LiveTv/ILiveTvService.cs | 3 + .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/Dto/RecordingInfoDto.cs | 12 ++++ MediaBrowser.Model/LiveTv/ChannelInfoDto.cs | 2 + MediaBrowser.Model/LiveTv/RecordingInfo.cs | 27 ++++++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../LiveTv/LiveTvManager.cs | 3 +- .../NextPvr/LiveTvService.cs | 66 +++++++++++++++++++ MediaBrowser.sln | 3 - 13 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 MediaBrowser.Model/Dto/RecordingInfoDto.cs create mode 100644 MediaBrowser.Model/LiveTv/RecordingInfo.cs create mode 100644 MediaBrowser.ServerApplication/NextPvr/LiveTvService.cs diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 579517aeb0..f8e7b63709 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -20,6 +20,13 @@ namespace MediaBrowser.Api.LiveTv { // Add filter by service if needed, and/or other filters } + + [Route("/LiveTv/Recordings", "GET")] + [Api(Description = "Gets available live tv recordings.")] + public class GetRecordings : IReturn> + { + // Add filter by service if needed, and/or other filters + } public class LiveTvService : BaseApiService { @@ -40,26 +47,6 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result); } - public object Get(GetChannels request) - { - var result = GetChannelsAsync(request).Result; - - return ToOptimizedResult(result); - } - - public async Task> GetChannelsAsync(GetChannels request) - { - var services = _liveTvManager.Services; - - var channelTasks = services.Select(i => i.GetChannelsAsync(CancellationToken.None)); - - var channelLists = await Task.WhenAll(channelTasks).ConfigureAwait(false); - - // Aggregate all channels from all services - return channelLists.SelectMany(i => i) - .Select(_liveTvManager.GetChannelInfoDto); - } - private LiveTvServiceInfo GetServiceInfo(ILiveTvService service) { return new LiveTvServiceInfo @@ -67,5 +54,43 @@ namespace MediaBrowser.Api.LiveTv Name = service.Name }; } + + public object Get(GetChannels request) + { + var result = GetChannelsAsync(request).Result; + + return ToOptimizedResult(result); + } + + private async Task> GetChannelsAsync(GetChannels request) + { + var services = _liveTvManager.Services; + + var tasks = services.Select(i => i.GetChannelsAsync(CancellationToken.None)); + + var channelLists = await Task.WhenAll(tasks).ConfigureAwait(false); + + // Aggregate all channels from all services + return channelLists.SelectMany(i => i) + .Select(_liveTvManager.GetChannelInfoDto); + } + + public object Get(GetRecordings request) + { + var result = GetRecordingsAsync(request).Result; + + return ToOptimizedResult(result); + } + + private async Task> GetRecordingsAsync(GetRecordings request) + { + var services = _liveTvManager.Services; + + var tasks = services.Select(i => i.GetRecordingsAsync(CancellationToken.None)); + + var recordings = await Task.WhenAll(tasks).ConfigureAwait(false); + + return recordings.SelectMany(i => i); + } } } diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs index 7ad1ec6c9b..547fc6287c 100644 --- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -13,6 +13,8 @@ namespace MediaBrowser.Controller.LiveTv /// The name. public string Name { get; set; } + public string Id { get; set; } + /// /// Gets or sets the name of the service. /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index de88d15620..62bfdf3e58 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.LiveTv; +using System.Threading.Tasks; +using MediaBrowser.Model.LiveTv; using System.Collections.Generic; namespace MediaBrowser.Controller.LiveTv diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index 4d9ec85311..a1e002bc82 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Controller.LiveTv { @@ -21,5 +22,7 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// Task{IEnumerable{ChannelInfo}}. Task> GetChannelsAsync(CancellationToken cancellationToken); + + Task> GetRecordingsAsync(CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index e88953b9c1..9027a814e2 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -233,6 +233,9 @@ LiveTv\LiveTvServiceInfo.cs + + LiveTv\RecordingInfo.cs + Logging\ILogger.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 6a14817a60..e13c348e04 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -220,6 +220,9 @@ LiveTv\LiveTvServiceInfo.cs + + LiveTv\RecordingInfo.cs + Logging\ILogger.cs diff --git a/MediaBrowser.Model/Dto/RecordingInfoDto.cs b/MediaBrowser.Model/Dto/RecordingInfoDto.cs new file mode 100644 index 0000000000..4151c5a9c8 --- /dev/null +++ b/MediaBrowser.Model/Dto/RecordingInfoDto.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Model.Dto +{ + public class RecordingInfoDto + { + } +} diff --git a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs index c77d7ed127..15c9055817 100644 --- a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs @@ -12,6 +12,8 @@ namespace MediaBrowser.Model.LiveTv /// The name. public string Name { get; set; } + public string Id { get; set; } + /// /// Gets or sets the name of the service. /// diff --git a/MediaBrowser.Model/LiveTv/RecordingInfo.cs b/MediaBrowser.Model/LiveTv/RecordingInfo.cs new file mode 100644 index 0000000000..dab37a3812 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/RecordingInfo.cs @@ -0,0 +1,27 @@ +using System; + +namespace MediaBrowser.Model.LiveTv +{ + public class RecordingInfo + { + public string ChannelId { get; set; } + + public string ChannelName { get; set; } + + public string Id { get; set; } + + public string Name { get; set; } + + public string Description { get; set; } + + /// + /// The start date of the recording, in UTC + /// + public DateTime StartDate { get; set; } + + /// + /// The end date of the recording, in UTC + /// + public DateTime EndDate { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index caf89346cd..b49368cf73 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -73,6 +73,7 @@ + diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 34be46d726..20beb551d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -39,7 +39,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv { Name = info.Name, ServiceName = info.ServiceName, - ChannelType = info.ChannelType + ChannelType = info.ChannelType, + Id = info.Id }; } } diff --git a/MediaBrowser.ServerApplication/NextPvr/LiveTvService.cs b/MediaBrowser.ServerApplication/NextPvr/LiveTvService.cs new file mode 100644 index 0000000000..ab72b2c8e1 --- /dev/null +++ b/MediaBrowser.ServerApplication/NextPvr/LiveTvService.cs @@ -0,0 +1,66 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Plugins.NextPvr +{ + /// + /// Class LiveTvService + /// + public class LiveTvService : ILiveTvService + { + private readonly ILogger _logger; + + private IApplicationPaths _appPaths; + private IJsonSerializer _json; + private IHttpClient _httpClient; + + public LiveTvService(ILogger logger) + { + _logger = logger; + } + + /// + /// Gets the channels async. + /// + /// The cancellation token. + /// Task{IEnumerable{ChannelInfo}}. + public Task> GetChannelsAsync(CancellationToken cancellationToken) + { + //using (var stream = await _httpClient.Get(new HttpRequestOptions() + // { + // Url = "", + // CancellationToken = cancellationToken + // })) + //{ + + //} + _logger.Info("GetChannelsAsync"); + + var channels = new List + { + new ChannelInfo + { + Name = "NBC", + ServiceName = Name + } + }; + + return Task.FromResult>(channels); + } + + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get { return "Next Pvr"; } + } + } +} diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 0c5360b494..744debbcd2 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -237,7 +237,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal From ed34b67f512b07ea2e97f8708811cc4150906f12 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Nov 2013 15:30:29 -0400 Subject: [PATCH 2/3] fix library scan stopping and restarting itself --- .../Configuration/ServerConfiguration.cs | 5 +++- .../Movies/MovieDbProvider.cs | 2 +- .../Savers/XmlSaverHelpers.cs | 4 +-- .../TV/RemoteSeasonProvider.cs | 2 +- .../IO/DirectoryWatchers.cs | 28 +++++++++++++++++- .../SqliteDisplayPreferencesRepository.cs | 2 +- .../Persistence/SqliteExtensions.cs | 5 +++- .../Persistence/SqliteItemRepository.cs | 4 +-- .../SqliteNotificationsRepository.cs | 2 +- .../Persistence/SqliteUserDataRepository.cs | 2 +- .../Persistence/SqliteUserRepository.cs | 2 +- .../Providers/ImageSaver.cs | 29 +++++++++++++++---- .../Sorting/PremiereDateComparer.cs | 9 +++++- 13 files changed, 77 insertions(+), 19 deletions(-) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 54ab7a5407..0ce3d770ee 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -275,7 +275,10 @@ namespace MediaBrowser.Model.Configuration MetadataCountryCode = "US"; DownloadMovieImages = new ImageDownloadOptions(); DownloadSeriesImages = new ImageDownloadOptions(); - DownloadSeasonImages = new ImageDownloadOptions(); + DownloadSeasonImages = new ImageDownloadOptions + { + Backdrops = false + }; DownloadMusicArtistImages = new ImageDownloadOptions(); DownloadMusicAlbumImages = new ImageDownloadOptions(); MaxBackdrops = 3; diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index baec90c66a..eb9c920d76 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -221,7 +221,7 @@ namespace MediaBrowser.Providers.Movies !imagesFileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(imagesFileInfo) > providerInfo.LastRefreshed; } - return true; + return base.NeedsRefreshBasedOnCompareDate(item, providerInfo); } /// diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index e9389d2db1..d9e0fb6e2f 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -562,8 +562,8 @@ namespace MediaBrowser.Providers.Savers { var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value); - builder.Append("" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + ""); - builder.Append("" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + ""); + builder.Append("" + Convert.ToInt64(timespan.TotalMinutes).ToString(UsCulture) + ""); + builder.Append("" + Convert.ToInt64(timespan.TotalSeconds).ToString(UsCulture) + ""); } if (video != null && video.Video3DFormat.HasValue) diff --git a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs index 1f702a2d21..ca6f699c39 100644 --- a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs @@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.TV try { var fanartData = FetchFanartXmlData(imagesXmlPath, seasonNumber.Value, cancellationToken); - await DownloadImages(item, fanartData, 1, cancellationToken).ConfigureAwait(false); + await DownloadImages(item, fanartData, ConfigurationManager.Configuration.MaxBackdrops, cancellationToken).ConfigureAwait(false); } catch (FileNotFoundException) { diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index 330469877a..748ba0df47 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -361,7 +361,33 @@ namespace MediaBrowser.Server.Implementations.IO if (e.ChangeType == WatcherChangeTypes.Changed) { // If the parent of an ignored path has a change event, ignore that too - if (tempIgnorePaths.Any(i => string.Equals(Path.GetDirectoryName(i), e.FullPath, StringComparison.OrdinalIgnoreCase) || string.Equals(i, e.FullPath, StringComparison.OrdinalIgnoreCase))) + if (tempIgnorePaths.Any(i => + { + if (string.Equals(i, e.FullPath, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Go up a level + var parent = Path.GetDirectoryName(i); + if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Go up another level + if (!string.IsNullOrEmpty(parent)) + { + parent = Path.GetDirectoryName(i); + if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + + })) { return; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index bfbb0e206c..09f438aef9 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile).ConfigureAwait(false); + _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs index b5672c39bf..9836de7350 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -128,15 +128,18 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Connects to db. /// /// The db path. + /// The logger. /// Task{IDbConnection}. /// dbPath - public static async Task ConnectToDb(string dbPath) + public static async Task ConnectToDb(string dbPath, ILogger logger) { if (string.IsNullOrEmpty(dbPath)) { throw new ArgumentNullException("dbPath"); } + logger.Info("Opening {0}", dbPath); + #if __MonoCS__ var connectionstr = new SqliteConnectionStringBuilder { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index d61178d282..fc2a6de248 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.Persistence var chapterDbFile = Path.Combine(_appPaths.DataPath, "chapters.db"); - var chapterConnection = SqliteExtensions.ConnectToDb(chapterDbFile).Result; + var chapterConnection = SqliteExtensions.ConnectToDb(chapterDbFile, _logger).Result; _chapterRepository = new SqliteChapterRepository(chapterConnection, logManager); } @@ -104,7 +104,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "library.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile).ConfigureAwait(false); + _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs index d85b1d8746..c5f391765c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile).ConfigureAwait(false); + _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 7fabe6a903..a9d5d8746e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile).ConfigureAwait(false); + _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index 8749c929ca..222cc94229 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -70,7 +70,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "users.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile).ConfigureAwait(false); + _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index 7b5c0df34d..0653bcebd7 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.IO; +using System.Collections.Generic; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -268,7 +269,7 @@ namespace MediaBrowser.Server.Implementations.Providers { item.ScreenshotImagePaths[imageIndex.Value] = path; } - else + else if (!item.ScreenshotImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) { item.ScreenshotImagePaths.Add(path); } @@ -282,7 +283,7 @@ namespace MediaBrowser.Server.Implementations.Providers { item.BackdropImagePaths[imageIndex.Value] = path; } - else + else if (!item.BackdropImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) { item.BackdropImagePaths.Add(path); } @@ -333,14 +334,14 @@ namespace MediaBrowser.Server.Implementations.Providers { throw new ArgumentNullException("imageIndex"); } - filename = imageIndex.Value == 0 ? "backdrop" : "backdrop" + imageIndex.Value.ToString(UsCulture); + filename = GetBackdropSaveFilename(item.BackdropImagePaths, "backdrop", "backdrop", imageIndex.Value); break; case ImageType.Screenshot: if (!imageIndex.HasValue) { throw new ArgumentNullException("imageIndex"); } - filename = imageIndex.Value == 0 ? "screenshot" : "screenshot" + imageIndex.Value.ToString(UsCulture); + filename = GetBackdropSaveFilename(item.ScreenshotImagePaths, "screenshot", "screenshot", imageIndex.Value); break; default: filename = type.ToString().ToLower(); @@ -380,6 +381,24 @@ namespace MediaBrowser.Server.Implementations.Providers return path; } + private string GetBackdropSaveFilename(List images, string zeroIndexFilename, string numberedIndexPrefix, int index) + { + var filesnames = images.Select(Path.GetFileNameWithoutExtension).ToList(); + + if (index == 0) + { + return zeroIndexFilename; + } + + var current = index; + while (filesnames.Contains(numberedIndexPrefix + current.ToString(UsCulture), StringComparer.OrdinalIgnoreCase)) + { + current++; + } + + return numberedIndexPrefix + current.ToString(UsCulture); + } + /// /// Gets the compatible save paths. /// diff --git a/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs index ef589e1fa6..ffe1fc24a1 100644 --- a/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs @@ -35,7 +35,14 @@ namespace MediaBrowser.Server.Implementations.Sorting if (x.ProductionYear.HasValue) { - return new DateTime(x.ProductionYear.Value, 1, 1, 0, 0, 0, DateTimeKind.Utc); + try + { + return new DateTime(x.ProductionYear.Value, 1, 1, 0, 0, 0, DateTimeKind.Utc); + } + catch (ArgumentOutOfRangeException) + { + // Don't blow up if the item has a bad ProductionYear, just return MinValue + } } return DateTime.MinValue; } From 8f7021eb424a89ba0ee5c1acc52d03d149583a1a Mon Sep 17 00:00:00 2001 From: Sven Van den brande Date: Sat, 2 Nov 2013 22:38:21 +0100 Subject: [PATCH 3/3] Added EpgFullInfo & EpgInfo Modified RecordingInfo & ChannelInfo Changed LiveTvService --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 27 +++++++- MediaBrowser.Controller/LiveTv/ChannelInfo.cs | 4 ++ .../LiveTv/ILiveTvService.cs | 2 + .../MediaBrowser.Model.Portable.csproj | 6 ++ .../MediaBrowser.Model.net35.csproj | 6 ++ MediaBrowser.Model/LiveTv/EpgFullInfo.cs | 17 +++++ MediaBrowser.Model/LiveTv/EpgInfo.cs | 32 +++++++++ MediaBrowser.Model/LiveTv/RecordingInfo.cs | 65 +++++++++++++++++-- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 + 9 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 MediaBrowser.Model/LiveTv/EpgFullInfo.cs create mode 100644 MediaBrowser.Model/LiveTv/EpgInfo.cs diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index f8e7b63709..6a8457ecb2 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -27,6 +27,13 @@ namespace MediaBrowser.Api.LiveTv { // Add filter by service if needed, and/or other filters } + + [Route("/LiveTv/EPG", "GET")] + [Api(Description = "Gets available live tv epgs..")] + public class GetEpg : IReturn> + { + // Add filter by service if needed, and/or other filters + } public class LiveTvService : BaseApiService { @@ -92,5 +99,23 @@ namespace MediaBrowser.Api.LiveTv return recordings.SelectMany(i => i); } + + public object Get(GetEpg request) + { + var result = GetEpgAsync(request).Result; + + return ToOptimizedResult(result); + } + + private async Task> GetEpgAsync(GetEpg request) + { + var services = _liveTvManager.Services; + + var tasks = services.Select(i => i.GetEpgAsync(CancellationToken.None)); + + var epg = await Task.WhenAll(tasks).ConfigureAwait(false); + + return epg.SelectMany(i => i); + } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs index 547fc6287c..8d8b638477 100644 --- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -13,6 +13,10 @@ namespace MediaBrowser.Controller.LiveTv /// The name. public string Name { get; set; } + /// + /// Get or sets the Id. + /// + /// The id of the channel. public string Id { get; set; } /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index a1e002bc82..86058696d3 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -24,5 +24,7 @@ namespace MediaBrowser.Controller.LiveTv Task> GetChannelsAsync(CancellationToken cancellationToken); Task> GetRecordingsAsync(CancellationToken cancellationToken); + + Task> GetEpgAsync(CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 8a6197857d..e254f9007c 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -230,6 +230,12 @@ LiveTv\ChannelType.cs + + LiveTv\EpgFullInfo.cs + + + LiveTv\EpgInfo.cs + LiveTv\LiveTvServiceInfo.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index dfff0356bc..b8625c7c67 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -217,6 +217,12 @@ LiveTv\ChannelType.cs + + LiveTv\EpgFullInfo.cs + + + LiveTv\EpgInfo.cs + LiveTv\LiveTvServiceInfo.cs diff --git a/MediaBrowser.Model/LiveTv/EpgFullInfo.cs b/MediaBrowser.Model/LiveTv/EpgFullInfo.cs new file mode 100644 index 0000000000..8e48537b82 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/EpgFullInfo.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.LiveTv +{ + public class EpgFullInfo + { + /// + /// ChannelId for the EPG. + /// + public string ChannelId { get; set; } + + /// + /// List of all the programs for a specific channel + /// + public List EpgInfos { get; set; } + } +} diff --git a/MediaBrowser.Model/LiveTv/EpgInfo.cs b/MediaBrowser.Model/LiveTv/EpgInfo.cs new file mode 100644 index 0000000000..3573e5deb0 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/EpgInfo.cs @@ -0,0 +1,32 @@ +using System; + +namespace MediaBrowser.Model.LiveTv +{ + public class EpgInfo + { + /// + /// Id of the program. + /// + public string Id { get; set; } + + /// + /// Description of the progam. + /// + public string Description { get; set; } + + /// + /// The start date of the program, in UTC. + /// + public DateTime StartDate { get; set; } + + /// + /// The end date of the program, in UTC. + /// + public DateTime EndDate { get; set; } + + /// + /// Genre of the program. + /// + public string Genre { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/RecordingInfo.cs b/MediaBrowser.Model/LiveTv/RecordingInfo.cs index dab37a3812..55a30a4b38 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfo.cs @@ -1,27 +1,78 @@ using System; +using System.Collections.Generic; namespace MediaBrowser.Model.LiveTv { public class RecordingInfo { - public string ChannelId { get; set; } - - public string ChannelName { get; set; } - + /// + /// Id of the recording. + /// public string Id { get; set; } + /// + /// ChannelId of the recording. + /// + public string ChannelId { get; set; } + + /// + /// ChannelName of the recording. + /// + public string ChannelName { get; set; } + + /// + /// Name of the recording. + /// public string Name { get; set; } + /// + /// Description of the recording. + /// public string Description { get; set; } /// - /// The start date of the recording, in UTC + /// The start date of the recording, in UTC. /// public DateTime StartDate { get; set; } /// - /// The end date of the recording, in UTC + /// The end date of the recording, in UTC. /// public DateTime EndDate { get; set; } + + /// + /// Status of the recording. + /// + public string Status { get; set; } //TODO: Enum for status?? Difference NextPvr,Argus,... + + /// + /// Quality of the Recording. + /// + public string Quality { get; set; } // TODO: Enum for quality?? Difference NextPvr,Argus,... + + /// + /// Recurring recording? + /// + public bool Recurring { get; set; } + + /// + /// Parent recurring. + /// + public string RecurringParent { get; set; } + + /// + /// Start date for the recurring, in UTC. + /// + public DateTime RecurrringStartDate { get; set; } + + /// + /// End date for the recurring, in UTC + /// + public DateTime RecurringEndDate { get; set; } + + /// + /// When do we need the recording? + /// + public List DayMask { get; set; } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index fc3b270f6b..30ce53121c 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -59,6 +59,8 @@ + +