From 4e04d31c7d13c2cec4f633ceab57acd8dae7ddc5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 May 2015 19:51:33 -0400 Subject: consolidate slideout panels --- MediaBrowser.Controller/Library/IUserDataManager.cs | 8 ++++++++ .../Persistence/IDisplayPreferencesRepository.cs | 6 +++--- MediaBrowser.Controller/Session/ISessionManager.cs | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs index f230f1472..56ac14e9d 100644 --- a/MediaBrowser.Controller/Library/IUserDataManager.cs +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -29,6 +29,14 @@ namespace MediaBrowser.Controller.Library /// Task. Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); + /// + /// Gets the user data. + /// + /// The user id. + /// The key. + /// Task{UserItemData}. + UserItemData GetUserData(string userId, string key); + /// /// Gets the user data. /// diff --git a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs index 66fac3462..17de730cb 100644 --- a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs +++ b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs @@ -25,9 +25,9 @@ namespace MediaBrowser.Controller.Persistence /// The client. /// The cancellation token. /// Task. - Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, + Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken); - + /// /// Saves all display preferences for a user /// @@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Persistence /// The user id. /// The client. /// Task{DisplayPreferences}. - DisplayPreferences GetDisplayPreferences(string displayPreferencesId, Guid userId, string client); + DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client); /// /// Gets all display preferences for the given user. diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 80025171d..dc9612c84 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -220,14 +220,14 @@ namespace MediaBrowser.Controller.Session /// /// The session identifier. /// The user identifier. - void AddAdditionalUser(string sessionId, Guid userId); + void AddAdditionalUser(string sessionId, string userId); /// /// Removes the additional user. /// /// The session identifier. /// The user identifier. - void RemoveAdditionalUser(string sessionId, Guid userId); + void RemoveAdditionalUser(string sessionId, string userId); /// /// Reports the now viewing item. -- cgit v1.2.3 From 25736b259a56ff11ca3b7298be023b87eb3fda99 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 May 2015 14:22:51 -0400 Subject: normalize tv recording objects --- MediaBrowser.Api/ItemUpdateService.cs | 2 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 8 +- .../Entities/Audio/MusicAlbum.cs | 9 + MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 14 +- .../MediaBrowser.LocalMetadata.csproj | 2 - .../Providers/AlbumXmlProvider.cs | 30 -- .../Providers/ArtistXmlProvider.cs | 30 -- .../Savers/SeasonXmlSaver.cs | 2 +- .../MediaBrowser.Model.Portable.csproj | 6 - .../MediaBrowser.Model.net35.csproj | 6 - MediaBrowser.Model/ApiClient/IApiClient.cs | 16 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 160 ++++++++++- MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs | 6 +- MediaBrowser.Model/LiveTv/RecordingGroupDto.cs | 40 --- MediaBrowser.Model/LiveTv/RecordingInfoDto.cs | 313 --------------------- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 - MediaBrowser.Model/Net/MimeTypes.cs | 154 ++++++---- MediaBrowser.Providers/Movies/MovieDbSearch.cs | 11 +- MediaBrowser.Providers/Omdb/OmdbItemProvider.cs | 112 +++----- .../Dto/DtoService.cs | 11 +- .../LiveTv/LiveTvDtoService.cs | 118 +------- .../LiveTv/LiveTvManager.cs | 170 +++++++---- .../Localization/JavaScript/javascript.json | 3 +- .../ApplicationHost.cs | 5 +- 24 files changed, 467 insertions(+), 763 deletions(-) delete mode 100644 MediaBrowser.LocalMetadata/Providers/AlbumXmlProvider.cs delete mode 100644 MediaBrowser.LocalMetadata/Providers/ArtistXmlProvider.cs delete mode 100644 MediaBrowser.Model/LiveTv/RecordingGroupDto.cs delete mode 100644 MediaBrowser.Model/LiveTv/RecordingInfoDto.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index bab02de35..8f7edabbb 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -428,7 +428,7 @@ namespace MediaBrowser.Api var series = item as Series; if (series != null) { - series.Status = request.Status; + series.Status = request.SeriesStatus; series.AirDays = request.AirDays; series.AirTime = request.AirTime; diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index b8b74369c..86d8b9f99 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Recordings", "GET", Summary = "Gets live tv recordings")] [Authenticated] - public class GetRecordings : IReturn> + public class GetRecordings : IReturn> { [ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string ChannelId { get; set; } @@ -107,7 +107,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Recordings/Groups", "GET", Summary = "Gets live tv recording groups")] [Authenticated] - public class GetRecordingGroups : IReturn> + public class GetRecordingGroups : IReturn> { [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string UserId { get; set; } @@ -115,7 +115,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Recordings/{Id}", "GET", Summary = "Gets a live tv recording")] [Authenticated] - public class GetRecording : IReturn + public class GetRecording : IReturn { [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } @@ -310,7 +310,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Recordings/Groups/{Id}", "GET", Summary = "Gets a recording group")] [Authenticated] - public class GetRecordingGroup : IReturn + public class GetRecordingGroup : IReturn { [ApiMember(Name = "Id", Description = "Recording group Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index c060f53a6..8a77d7616 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -121,6 +121,15 @@ namespace MediaBrowser.Controller.Entities.Audio .Select(i => i.GetLookupInfo()) .ToList(); + var album = id.SongInfos + .Select(i => i.Album) + .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + + if (!string.IsNullOrWhiteSpace(album)) + { + id.Name = album; + } + return id; } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 53eb18e7a..e84fe902d 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// The user. /// Task{RecordingInfoDto}. - Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null); + Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null); /// /// Gets the channel. @@ -113,7 +113,7 @@ namespace MediaBrowser.Controller.LiveTv /// The options. /// The cancellation token. /// QueryResult{RecordingInfoDto}. - Task> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken); + Task> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken); /// /// Gets the timers. @@ -218,7 +218,7 @@ namespace MediaBrowser.Controller.LiveTv /// The query. /// The cancellation token. /// Task{QueryResult{RecordingGroupDto}}. - Task> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken); + Task> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken); /// /// Closes the live stream. @@ -321,5 +321,13 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// Task<IEnumerable<MediaSourceInfo>>. Task> GetChannelMediaSources(string id, CancellationToken cancellationToken); + + /// + /// Adds the information to recording dto. + /// + /// The item. + /// The dto. + /// The user. + void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null); } } diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 894be8799..57174d63a 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -58,8 +58,6 @@ - - diff --git a/MediaBrowser.LocalMetadata/Providers/AlbumXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/AlbumXmlProvider.cs deleted file mode 100644 index 646922769..000000000 --- a/MediaBrowser.LocalMetadata/Providers/AlbumXmlProvider.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.IO; -using System.Threading; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.LocalMetadata.Providers -{ - public class AlbumXmlProvider : BaseXmlProvider - { - private readonly ILogger _logger; - - public AlbumXmlProvider(IFileSystem fileSystem, ILogger logger) - : base(fileSystem) - { - _logger = logger; - } - - protected override void Fetch(LocalMetadataResult result, string path, CancellationToken cancellationToken) - { - new BaseItemXmlParser(_logger).Fetch(result.Item, path, cancellationToken); - } - - protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService) - { - return directoryService.GetFile(Path.Combine(info.Path, "album.xml")); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Providers/ArtistXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/ArtistXmlProvider.cs deleted file mode 100644 index 0b5ebfb11..000000000 --- a/MediaBrowser.LocalMetadata/Providers/ArtistXmlProvider.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.IO; -using System.Threading; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.LocalMetadata.Providers -{ - class ArtistXmlProvider : BaseXmlProvider - { - private readonly ILogger _logger; - - public ArtistXmlProvider(IFileSystem fileSystem, ILogger logger) - : base(fileSystem) - { - _logger = logger; - } - - protected override void Fetch(LocalMetadataResult result, string path, CancellationToken cancellationToken) - { - new BaseItemXmlParser(_logger).Fetch(result.Item, path, cancellationToken); - } - - protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService) - { - return directoryService.GetFile(Path.Combine(info.Path, "artist.xml")); - } - } -} diff --git a/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs index a112f22fa..30f3e0ca1 100644 --- a/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/SeasonXmlSaver.cs @@ -11,7 +11,7 @@ using System.Threading; namespace MediaBrowser.LocalMetadata.Savers { - public class SeasonXmlSaver : IMetadataFileSaver + public class SeasonXmlSaver { public string Name { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index f70fe628e..a63b0a7c6 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -752,15 +752,9 @@ LiveTv\RecommendedProgramQuery.cs - - LiveTv\RecordingGroupDto.cs - LiveTv\RecordingGroupQuery.cs - - LiveTv\RecordingInfoDto.cs - LiveTv\RecordingQuery.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index bb8b09682..036064238 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -708,15 +708,9 @@ LiveTv\RecommendedProgramQuery.cs - - LiveTv\RecordingGroupDto.cs - LiveTv\RecordingGroupQuery.cs - - LiveTv\RecordingInfoDto.cs - LiveTv\RecordingQuery.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 026e65ec4..71ac0b14e 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -929,14 +929,6 @@ namespace MediaBrowser.Model.ApiClient /// System.String. string GetImageUrl(ChannelInfoDto item, ImageOptions options); - /// - /// Gets the image URL. - /// - /// The item. - /// The options. - /// System.String. - string GetImageUrl(RecordingInfoDto item, ImageOptions options); - /// /// Gets the image URL. /// @@ -1077,7 +1069,7 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// The cancellation token. /// Task{QueryResult{RecordingInfoDto}}. - Task> GetLiveTvRecordingsAsync(RecordingQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task> GetLiveTvRecordingsAsync(RecordingQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the live tv recording asynchronous. @@ -1086,7 +1078,7 @@ namespace MediaBrowser.Model.ApiClient /// The user identifier. /// The cancellation token. /// Task{RecordingInfoDto}. - Task GetLiveTvRecordingAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); + Task GetLiveTvRecordingAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the live tv recording groups asynchronous. @@ -1094,7 +1086,7 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// The cancellation token. /// Task{QueryResult{RecordingGroupDto}}. - Task> GetLiveTvRecordingGroupsAsync(RecordingGroupQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task> GetLiveTvRecordingGroupsAsync(RecordingGroupQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the live tv recording group asynchronous. @@ -1103,7 +1095,7 @@ namespace MediaBrowser.Model.ApiClient /// The user identifier. /// The cancellation token. /// Task{RecordingGroupDto}. - Task GetLiveTvRecordingGroupAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); + Task GetLiveTvRecordingGroupAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the live tv timers asynchronous. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index c772692a2..0f6ce4334 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Library; +using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Sync; using System; @@ -442,7 +443,57 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the status. /// /// The status. - public SeriesStatus? Status { get; set; } + public string Status { get; set; } + + [IgnoreDataMember] + public SeriesStatus? SeriesStatus + { + get + { + if (string.IsNullOrEmpty(Status)) + { + return null; + } + + return (SeriesStatus)Enum.Parse(typeof(SeriesStatus), Status, true); + } + set + { + if (value == null) + { + Status = null; + } + else + { + Status = value.Value.ToString(); + } + } + } + + [IgnoreDataMember] + public RecordingStatus? RecordingStatus + { + get + { + if (string.IsNullOrEmpty(Status)) + { + return null; + } + + return (RecordingStatus)Enum.Parse(typeof(RecordingStatus), Status, true); + } + set + { + if (value == null) + { + Status = null; + } + else + { + Status = value.Value.ToString(); + } + } + } /// /// Gets or sets the air time. @@ -797,6 +848,17 @@ namespace MediaBrowser.Model.Dto public double? Altitude { get; set; } public int? IsoSpeedRating { get; set; } + /// + /// Used by RecordingGroup + /// + public int? RecordingCount { get; set; } + + /// + /// Gets or sets the series timer identifier. + /// + /// The series timer identifier. + public string SeriesTimerId { get; set; } + /// /// Gets a value indicating whether this instance can resume. /// @@ -1017,5 +1079,101 @@ namespace MediaBrowser.Model.Dto /// Occurs when [property changed]. /// public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Gets or sets the program identifier. + /// + /// The program identifier. + public string ProgramId { get; set; } + + /// + /// Gets or sets the channel primary image tag. + /// + /// The channel primary image tag. + public string ChannelPrimaryImageTag { get; set; } + + /// + /// The start date of the recording, in UTC. + /// + public DateTime? StartDate { get; set; } + + /// + /// Gets or sets the original air date. + /// + /// The original air date. + public DateTime? OriginalAirDate { get; set; } + + /// + /// Gets or sets the completion percentage. + /// + /// The completion percentage. + public double? CompletionPercentage { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is repeat. + /// + /// true if this instance is repeat; otherwise, false. + public bool? IsRepeat { get; set; } + + /// + /// Gets or sets the episode title. + /// + /// The episode title. + public string EpisodeTitle { get; set; } + + /// + /// Gets or sets the type of the channel. + /// + /// The type of the channel. + public ChannelType? ChannelType { get; set; } + + /// + /// Gets or sets the audio. + /// + /// The audio. + public ProgramAudio? Audio { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is movie. + /// + /// true if this instance is movie; otherwise, false. + public bool? IsMovie { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is sports. + /// + /// true if this instance is sports; otherwise, false. + public bool? IsSports { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is series. + /// + /// true if this instance is series; otherwise, false. + public bool? IsSeries { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is live. + /// + /// true if this instance is live; otherwise, false. + public bool? IsLive { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is news. + /// + /// true if this instance is news; otherwise, false. + public bool? IsNews { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is kids. + /// + /// true if this instance is kids; otherwise, false. + public bool? IsKids { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is premiere. + /// + /// true if this instance is premiere; otherwise, false. + public bool? IsPremiere { get; set; } + } } diff --git a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs index 49e572418..296ead5c2 100644 --- a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs @@ -1,7 +1,7 @@ -using System; -using System.ComponentModel; -using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Extensions; +using System; +using System.ComponentModel; namespace MediaBrowser.Model.LiveTv { diff --git a/MediaBrowser.Model/LiveTv/RecordingGroupDto.cs b/MediaBrowser.Model/LiveTv/RecordingGroupDto.cs deleted file mode 100644 index 8a0b488cc..000000000 --- a/MediaBrowser.Model/LiveTv/RecordingGroupDto.cs +++ /dev/null @@ -1,40 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Extensions; -using System.ComponentModel; -using System.Diagnostics; - -namespace MediaBrowser.Model.LiveTv -{ - /// - /// Class RecordingGroupDto. - /// - [DebuggerDisplay("Name = {Name}, Count = {RecordingCount}")] - public class RecordingGroupDto : IHasPropertyChangedEvent, IHasServerId - { - /// - /// Gets or sets the server identifier. - /// - /// The server identifier. - public string ServerId { get; set; } - - /// - /// Gets or sets the name. - /// - /// The name. - public string Name { get; set; } - - /// - /// Gets or sets the identifier. - /// - /// The identifier. - public string Id { get; set; } - - /// - /// Gets or sets the recording count. - /// - /// The recording count. - public int RecordingCount { get; set; } - - public event PropertyChangedEventHandler PropertyChanged; - } -} diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs deleted file mode 100644 index 0988b11a6..000000000 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ /dev/null @@ -1,313 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.Library; -using MediaBrowser.Model.Sync; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Runtime.Serialization; - -namespace MediaBrowser.Model.LiveTv -{ - [DebuggerDisplay("Name = {Name}, ChannelName = {ChannelName}")] - public class RecordingInfoDto : IHasPropertyChangedEvent, IItemDto, IHasServerId, IHasSyncInfo - { - /// - /// Id of the recording. - /// - public string Id { get; set; } - - /// - /// Gets or sets the primary image aspect ratio. - /// - /// The primary image aspect ratio. - public double? PrimaryImageAspectRatio { get; set; } - - /// - /// Gets or sets the server identifier. - /// - /// The server identifier. - public string ServerId { get; set; } - - /// - /// Gets or sets the original primary image aspect ratio. - /// - /// The original primary image aspect ratio. - public double? OriginalPrimaryImageAspectRatio { get; set; } - - /// - /// Gets or sets a value indicating whether [supports synchronize]. - /// - /// null if [supports synchronize] contains no value, true if [supports synchronize]; otherwise, false. - public bool? SupportsSync { get; set; } - /// - /// Gets or sets a value indicating whether this instance has synchronize job. - /// - /// null if [has synchronize job] contains no value, true if [has synchronize job]; otherwise, false. - public bool? HasSyncJob { get; set; } - /// - /// Gets or sets a value indicating whether this instance is synced. - /// - /// null if [is synced] contains no value, true if [is synced]; otherwise, false. - public bool? IsSynced { get; set; } - /// - /// Gets or sets the synchronize status. - /// - /// The synchronize status. - public SyncJobItemStatus? SyncStatus { get; set; } - - /// - /// Gets or sets the series timer identifier. - /// - /// The series timer identifier. - public string SeriesTimerId { get; set; } - - /// - /// Gets or sets the external identifier. - /// - /// The external identifier. - public string ExternalId { get; set; } - - /// - /// Gets or sets the program identifier. - /// - /// The program identifier. - public string ProgramId { get; set; } - - /// - /// ChannelId of the recording. - /// - public string ChannelId { get; set; } - - /// - /// Gets or sets the play access. - /// - /// The play access. - public PlayAccess PlayAccess { get; set; } - - /// - /// Gets or sets the channel primary image tag. - /// - /// The channel primary image tag. - public string ChannelPrimaryImageTag { get; set; } - - /// - /// ChannelName of the recording. - /// - public string ChannelName { get; set; } - - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - - /// - /// Name of the recording. - /// - public string Name { get; set; } - - /// - /// Gets or sets the media streams. - /// - /// The media streams. - public List MediaStreams { get; set; } - - /// - /// Gets or sets the path. - /// - /// The path. - public string Path { get; set; } - - /// - /// Gets or sets a value indicating whether this instance can delete. - /// - /// null if [can delete] contains no value, true if [can delete]; otherwise, false. - public bool? CanDelete { get; set; } - - /// - /// Overview of the recording. - /// - public string Overview { 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; } - - /// - /// Gets or sets the original air date. - /// - /// The original air date. - public DateTime? OriginalAirDate { get; set; } - - /// - /// Gets or sets the status. - /// - /// The status. - public RecordingStatus Status { get; set; } - - /// - /// Gets or sets the name of the status. - /// - /// The name of the status. - public string StatusName { get; set; } - - /// - /// Gets or sets the completion percentage. - /// - /// The completion percentage. - public double? CompletionPercentage { get; set; } - - /// - /// Genre of the program. - /// - public List Genres { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is repeat. - /// - /// true if this instance is repeat; otherwise, false. - public bool IsRepeat { get; set; } - - /// - /// Gets or sets the episode title. - /// - /// The episode title. - public string EpisodeTitle { get; set; } - - /// - /// Gets or sets the run time ticks. - /// - /// The run time ticks. - public long? RunTimeTicks { get; set; } - - /// - /// Gets or sets the type of the media. - /// - /// The type of the media. - public string MediaType { get; set; } - - /// - /// Gets or sets the type of the channel. - /// - /// The type of the channel. - public ChannelType ChannelType { get; set; } - - /// - /// Gets or sets the official rating. - /// - /// The official rating. - public string OfficialRating { get; set; } - - /// - /// Gets or sets the community rating. - /// - /// The community rating. - public float? CommunityRating { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is hd. - /// - /// true if this instance is hd; otherwise, false. - public bool? IsHD { get; set; } - - /// - /// Gets or sets the audio. - /// - /// The audio. - public ProgramAudio? Audio { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is movie. - /// - /// true if this instance is movie; otherwise, false. - public bool IsMovie { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is sports. - /// - /// true if this instance is sports; otherwise, false. - public bool IsSports { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is series. - /// - /// true if this instance is series; otherwise, false. - public bool IsSeries { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is live. - /// - /// true if this instance is live; otherwise, false. - public bool IsLive { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is news. - /// - /// true if this instance is news; otherwise, false. - public bool IsNews { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is kids. - /// - /// true if this instance is kids; otherwise, false. - public bool IsKids { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is premiere. - /// - /// true if this instance is premiere; otherwise, false. - public bool IsPremiere { get; set; } - - /// - /// Gets or sets the image tags. - /// - /// The image tags. - public Dictionary ImageTags { get; set; } - - /// - /// Gets or sets the user data. - /// - /// The user data. - public UserItemDataDto UserData { get; set; } - - /// - /// Gets a value indicating whether this instance has primary image. - /// - /// true if this instance has primary image; otherwise, false. - [IgnoreDataMember] - public bool HasPrimaryImage - { - get { return ImageTags != null && ImageTags.ContainsKey(ImageType.Primary); } - } - - /// - /// Gets or sets the type. - /// - /// The type. - public string Type { get; set; } - - /// - /// Gets or sets the media sources. - /// - /// The media sources. - public List MediaSources { get; set; } - - public RecordingInfoDto() - { - Genres = new List(); - ImageTags = new Dictionary(); - MediaSources = new List(); - } - - public event PropertyChangedEventHandler PropertyChanged; - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 340bd9462..c567c1f6a 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -262,7 +262,6 @@ - @@ -299,7 +298,6 @@ - diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 56cfff733..efa5a5217 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -1,4 +1,5 @@ -using System; +using MediaBrowser.Model.Extensions; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -45,33 +46,50 @@ namespace MediaBrowser.Model.Net ".rec" }; - private static readonly Dictionary VideoFileExtensionsDictionary = VideoFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + private static Dictionary GetVideoFileExtensionsDictionary() + { + Dictionary dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (string ext in VideoFileExtensions) + { + dict[ext] = ext; + } + + return dict; + } + + private static readonly Dictionary VideoFileExtensionsDictionary = GetVideoFileExtensionsDictionary(); // http://en.wikipedia.org/wiki/Internet_media_type // Add more as needed - private static readonly Dictionary MimeTypeLookup = - new Dictionary(StringComparer.OrdinalIgnoreCase) - { - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".tbn", "image/jpeg"}, - {".png", "image/png"}, - {".gif", "image/gif"}, - {".webp", "image/webp"}, - {".ico", "image/vnd.microsoft.icon"}, - {".mpg", "video/mpeg"}, - {".mpeg", "video/mpeg"}, - {".ogv", "video/ogg"}, - {".mov", "video/quicktime"}, - {".webm", "video/webm"}, - {".mkv", "video/x-matroska"}, - {".wmv", "video/x-ms-wmv"}, - {".flv", "video/x-flv"}, - {".avi", "video/x-msvideo"}, - {".asf", "video/x-ms-asf"}, - {".m4v", "video/x-m4v"} - }; + private static Dictionary GetMimeTypeLookup() + { + Dictionary dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + dict.Add(".jpg", "image/jpeg"); + dict.Add(".jpeg", "image/jpeg"); + dict.Add(".tbn", "image/jpeg"); + dict.Add(".png", "image/png"); + dict.Add(".gif", "image/gif"); + dict.Add(".webp", "image/webp"); + dict.Add(".ico", "image/vnd.microsoft.icon"); + dict.Add(".mpg", "video/mpeg"); + dict.Add(".mpeg", "video/mpeg"); + dict.Add(".ogv", "video/ogg"); + dict.Add(".mov", "video/quicktime"); + dict.Add(".webm", "video/webm"); + dict.Add(".mkv", "video/x-matroska"); + dict.Add(".wmv", "video/x-ms-wmv"); + dict.Add(".flv", "video/x-flv"); + dict.Add(".avi", "video/x-msvideo"); + dict.Add(".asf", "video/x-ms-asf"); + dict.Add(".m4v", "video/x-m4v"); + + return dict; + } + + private static readonly Dictionary MimeTypeLookup = GetMimeTypeLookup(); private static readonly Dictionary ExtensionLookup = CreateExtensionLookup(); @@ -109,19 +127,19 @@ namespace MediaBrowser.Model.Net } // Type video - if (ext.Equals(".3gp", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".3gp")) { return "video/3gpp"; } - if (ext.Equals(".3g2", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".3g2")) { return "video/3gpp2"; } - if (ext.Equals(".ts", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".ts")) { return "video/mp2t"; } - if (ext.Equals(".mpd", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".mpd")) { return "video/vnd.mpeg.dash.mpd"; } @@ -133,134 +151,154 @@ namespace MediaBrowser.Model.Net } // Type text - if (ext.Equals(".css", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".css")) { return "text/css"; } - if (ext.Equals(".csv", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".csv")) { return "text/csv"; } - if (ext.Equals(".html", StringComparison.OrdinalIgnoreCase) || ext.Equals(".htm", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".html")) + { + return "text/html; charset=UTF-8"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".htm")) { return "text/html; charset=UTF-8"; } - if (ext.Equals(".txt", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".txt")) { return "text/plain"; } - if (ext.Equals(".xml", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".xml")) { return "application/xml"; } // Type document - if (ext.Equals(".pdf", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".pdf")) { return "application/pdf"; } - if (ext.Equals(".mobi", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".mobi")) { return "application/x-mobipocket-ebook"; } - if (ext.Equals(".epub", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".epub")) + { + return "application/epub+zip"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".cbz")) { return "application/epub+zip"; } - if (ext.Equals(".cbz", StringComparison.OrdinalIgnoreCase) || ext.Equals(".cbr", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".cbr")) { - return "application/x-cdisplay"; + return "application/epub+zip"; } // Type audio - if (ext.Equals(".mp3", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".mp3")) { return "audio/mpeg"; } - if (ext.Equals(".m4a", StringComparison.OrdinalIgnoreCase) || ext.Equals(".aac", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".m4a")) { return "audio/mp4"; } - if (ext.Equals(".webma", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".aac")) + { + return "audio/mp4"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".webma")) { return "audio/webm"; } - if (ext.Equals(".wav", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".wav")) { return "audio/wav"; } - if (ext.Equals(".wma", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".wma")) { return "audio/x-ms-wma"; } - if (ext.Equals(".flac", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".flac")) { return "audio/flac"; } - if (ext.Equals(".aac", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".aac")) { return "audio/x-aac"; } - if (ext.Equals(".ogg", StringComparison.OrdinalIgnoreCase) || ext.Equals(".oga", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".ogg")) + { + return "audio/ogg"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".oga")) { return "audio/ogg"; } // Playlists - if (ext.Equals(".m3u8", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".m3u8")) { return "application/x-mpegURL"; } // Misc - if (ext.Equals(".dll", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".dll")) { return "application/octet-stream"; } // Web - if (ext.Equals(".js", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".js")) { return "application/x-javascript"; } - if (ext.Equals(".json", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".json")) { return "application/json"; } - if (ext.Equals(".map", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".map")) { return "application/x-javascript"; } - if (ext.Equals(".woff", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".woff")) { return "font/woff"; } - if (ext.Equals(".ttf", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".ttf")) { return "font/ttf"; } - if (ext.Equals(".eot", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".eot")) { return "application/vnd.ms-fontobject"; } - if (ext.Equals(".svg", StringComparison.OrdinalIgnoreCase) || ext.Equals(".svgz", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".svg")) + { + return "image/svg+xml"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".svgz")) { return "image/svg+xml"; } - if (ext.Equals(".srt", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".srt")) { return "text/plain"; } - if (ext.Equals(".vtt", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".vtt")) { return "text/vtt"; } - if (ext.Equals(".ttml", StringComparison.OrdinalIgnoreCase)) + if (StringHelper.EqualsIgnoreCase(ext, ".ttml")) { return "application/ttml+xml"; } diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index 8a59d7a1b..6fb795411 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -58,10 +58,13 @@ namespace MediaBrowser.Providers.Movies var tmdbImageUrl = tmdbSettings.images.base_url + "original"; - var parsedName = _libraryManager.ParseName(name); - var yearInName = parsedName.Year; - name = parsedName.Name; - year = year ?? yearInName; + if (!string.IsNullOrWhiteSpace(name)) + { + var parsedName = _libraryManager.ParseName(name); + var yearInName = parsedName.Year; + name = parsedName.Name; + year = year ?? yearInName; + } _logger.Info("MovieDbProvider: Finding id for item: " + name); var language = idInfo.MetadataLanguage.ToLower(); diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index 1ee2d86de..c79d04b4f 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using System.Linq; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; @@ -52,28 +53,34 @@ namespace MediaBrowser.Providers.Omdb var list = new List(); var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(imdbId)) - { - return list; - } var url = "http://www.omdbapi.com/?plot=short&r=json"; var name = searchInfo.Name; var year = searchInfo.Year; - var parsedName = _libraryManager.ParseName(name); - var yearInName = parsedName.Year; - name = parsedName.Name; - year = year ?? yearInName; - - if (year.HasValue) + if (!string.IsNullOrWhiteSpace(name)) { - url += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture); + var parsedName = _libraryManager.ParseName(name); + var yearInName = parsedName.Year; + name = parsedName.Name; + year = year ?? yearInName; } + + if (string.IsNullOrWhiteSpace(imdbId)) + { + if (year.HasValue) + { + url += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture); + } - url += "&t=" + WebUtility.UrlEncode(name); - url += "&type=" + type; + url += "&t=" + WebUtility.UrlEncode(name); + url += "&type=" + type; + } + else + { + url += "&i=" + imdbId; + } using (var stream = await _httpClient.Get(new HttpRequestOptions { @@ -81,7 +88,7 @@ namespace MediaBrowser.Providers.Omdb ResourcePool = OmdbProvider.ResourcePool, CancellationToken = cancellationToken, CacheMode = CacheMode.Unconditional, - CacheLength = TimeSpan.FromDays(7) + CacheLength = TimeSpan.FromDays(2) }).ConfigureAwait(false)) { @@ -145,33 +152,18 @@ namespace MediaBrowser.Providers.Omdb Item = new Series() }; - var searchResult = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); - result.Item.Name = searchResult.Item4; - - if (!string.IsNullOrEmpty(searchResult.Item1)) - { - result.Item.SetProviderId(MetadataProviders.Imdb, searchResult.Item1); - } - - if (!string.IsNullOrEmpty(searchResult.Item2)) - { - result.Item.SetProviderId(MetadataProviders.Tmdb, searchResult.Item2); - } - - if (!string.IsNullOrEmpty(searchResult.Item3)) + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + if (string.IsNullOrWhiteSpace(imdbId)) { - result.Item.SetProviderId(MetadataProviders.Tvdb, searchResult.Item3); + imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); } - var imdbId = result.Item.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrEmpty(imdbId)) { result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) - .ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken).ConfigureAwait(false); } return result; @@ -191,64 +183,34 @@ namespace MediaBrowser.Providers.Omdb }; var imdbId = info.GetProviderId(MetadataProviders.Imdb); - - var searchResult = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); - result.Item.Name = searchResult.Item3; - if (string.IsNullOrWhiteSpace(imdbId)) { - imdbId = searchResult.Item1; - - if (!string.IsNullOrEmpty(searchResult.Item2)) - { - result.Item.SetProviderId(MetadataProviders.Tmdb, searchResult.Item2); - } + imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); } - if (!string.IsNullOrWhiteSpace(imdbId)) + if (!string.IsNullOrEmpty(imdbId)) { result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) - .ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken).ConfigureAwait(false); } return result; } - private async Task> GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) + private async Task GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) { - var result = await new GenericMovieDbInfo(_logger, _jsonSerializer, _libraryManager).GetMetadata(info, cancellationToken) - .ConfigureAwait(false); - - var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; - var tmdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tmdb) : null; - var name = result.HasMetadata ? result.Item.Name : null; - - return new Tuple(imdb, tmdb, name); + var results = await GetSearchResults(info, "movie", cancellationToken).ConfigureAwait(false); + var first = results.FirstOrDefault(); + return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } - private async Task> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) + private async Task GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) { - //var result = await TvdbSeriesProvider.Current.GetMetadata(info, cancellationToken) - // .ConfigureAwait(false); - - //var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; - //var tvdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tvdb) : null; - //var name = result.HasMetadata ? result.Item.Name : null; - - //return new Tuple(imdb, tvdb, name); - - var result = await MovieDbSeriesProvider.Current.GetMetadata(info, cancellationToken) - .ConfigureAwait(false); - - var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; - var tmdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tmdb) : null; - var tvdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tvdb) : null; - var name = result.HasMetadata ? result.Item.Name : null; - - return new Tuple(imdb, tmdb, tvdb, name); + var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false); + var first = results.FirstOrDefault(); + return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); } public Task GetImageResponse(string url, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 1b55f47d5..cf56fc9ce 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -46,8 +46,9 @@ namespace MediaBrowser.Server.Implementations.Dto private readonly IApplicationHost _appHost; private readonly Func _deviceManager; private readonly Func _mediaSourceManager; + private readonly Func _livetvManager; - public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func deviceManager, Func mediaSourceManager) + public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func deviceManager, Func mediaSourceManager, Func livetvManager) { _logger = logger; _libraryManager = libraryManager; @@ -62,6 +63,7 @@ namespace MediaBrowser.Server.Implementations.Dto _appHost = appHost; _deviceManager = deviceManager; _mediaSourceManager = mediaSourceManager; + _livetvManager = livetvManager; } /// @@ -350,6 +352,11 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Etag = item.GetEtag(user); } + if (item is ILiveTvRecording) + { + _livetvManager().AddInfoToRecordingDto(item, dto, user); + } + return dto; } @@ -1384,7 +1391,7 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.AirDays = series.AirDays; dto.AirTime = series.AirTime; - dto.Status = series.Status; + dto.SeriesStatus = series.Status; dto.SeasonCount = series.SeasonCount; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 00c15fdfc..939d057cb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -167,122 +167,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv return val.Value; } - public string GetStatusName(RecordingStatus status) - { - if (status == RecordingStatus.InProgress) - { - return "In Progress"; - } - - if (status == RecordingStatus.ConflictedNotOk) - { - return "Conflicted"; - } - - if (status == RecordingStatus.ConflictedOk) - { - return "Scheduled"; - } - - return status.ToString(); - } - - public RecordingInfoDto GetRecordingInfoDto(ILiveTvRecording recording, LiveTvChannel channel, ILiveTvService service, User user = null) - { - var info = recording.RecordingInfo; - - var dto = new RecordingInfoDto - { - Id = GetInternalRecordingId(service.Name, info.Id).ToString("N"), - SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"), - Type = recording.GetClientTypeName(), - Overview = info.Overview, - EndDate = info.EndDate, - Name = info.Name, - StartDate = info.StartDate, - ExternalId = info.Id, - ChannelId = GetInternalChannelId(service.Name, info.ChannelId).ToString("N"), - Status = info.Status, - StatusName = GetStatusName(info.Status), - Path = info.Path, - Genres = info.Genres, - IsRepeat = info.IsRepeat, - EpisodeTitle = info.EpisodeTitle, - ChannelType = info.ChannelType, - MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video, - CommunityRating = GetClientCommunityRating(info.CommunityRating), - OfficialRating = info.OfficialRating, - Audio = info.Audio, - IsHD = info.IsHD, - ServiceName = service.Name, - IsMovie = info.IsMovie, - IsSeries = info.IsSeries, - IsSports = info.IsSports, - IsLive = info.IsLive, - IsNews = info.IsNews, - IsKids = info.IsKids, - IsPremiere = info.IsPremiere, - RunTimeTicks = (info.EndDate - info.StartDate).Ticks, - OriginalAirDate = info.OriginalAirDate, - - MediaSources = recording.GetMediaSources(true).ToList(), - ServerId = _appHost.SystemId - }; - - dto.CanDelete = user == null - ? recording.CanDelete() - : recording.CanDelete(user); - - dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); - - if (info.Status == RecordingStatus.InProgress) - { - var now = DateTime.UtcNow.Ticks; - var start = info.StartDate.Ticks; - var end = info.EndDate.Ticks; - - var pct = now - start; - pct /= end; - pct *= 100; - dto.CompletionPercentage = pct; - } - - var imageTag = GetImageTag(recording); - - if (imageTag != null) - { - dto.ImageTags[ImageType.Primary] = imageTag; - _dtoService.AttachPrimaryImageAspectRatio(dto, recording, new List - { - ItemFields.PrimaryImageAspectRatio - }); - } - - if (user != null) - { - dto.UserData = _userDataManager.GetUserDataDto(recording, user); - - dto.PlayAccess = recording.GetPlayAccess(user); - } - - if (!string.IsNullOrEmpty(info.ProgramId)) - { - dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); - } - - if (channel != null) - { - dto.ChannelName = channel.Name; - - if (!string.IsNullOrEmpty(channel.PrimaryImagePath)) - { - dto.ChannelPrimaryImageTag = GetImageTag(channel); - } - } - - return dto; - } - public LiveTvTunerInfoDto GetTunerInfoDto(string serviceName, LiveTvTunerInfo info, string channelName) { var dto = new LiveTvTunerInfoDto @@ -430,7 +314,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return dto; } - private string GetImageTag(IHasImages info) + internal string GetImageTag(IHasImages info) { try { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index a82775de7..52c96bca6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -119,11 +119,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var dict = new Dictionary(); - foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram)) + foreach (var item in _itemRepo.GetItemsOfType(typeof(LiveTvProgram)) .Cast() .ToList()) { - dict[item.Id] = item; + dict[item.Id] = item; } _programs = dict; @@ -658,7 +658,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id); - var item = _itemRepo.RetrieveItem(id) as ILiveTvRecording; + var item = _itemRepo.RetrieveItem(id); if (item == null) { @@ -687,8 +687,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv isNew = true; } - item.RecordingInfo = info; - item.ServiceName = serviceName; + item.CommunityRating = info.CommunityRating; + item.OfficialRating = info.OfficialRating; + item.Overview = info.Overview; + item.EndDate = info.EndDate; + + var recording = (ILiveTvRecording)item; + + recording.RecordingInfo = info; + recording.ServiceName = serviceName; var originalPath = item.Path; @@ -709,9 +716,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv }, cancellationToken); - _libraryManager.RegisterItem((BaseItem)item); + _libraryManager.RegisterItem(item); - return item; + return recording; } private LiveTvChannel GetChannel(LiveTvProgram program) @@ -1355,20 +1362,89 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } - public async Task> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken) + public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null) { - var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + var recording = (ILiveTvRecording)item; + var service = GetService(recording); - var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false); + var channel = string.IsNullOrEmpty(recording.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, recording.RecordingInfo.ChannelId)); - var returnArray = internalResult.Items.Cast() - .Select(i => + var info = recording.RecordingInfo; + + dto.Id = _tvDtoService.GetInternalRecordingId(service.Name, info.Id).ToString("N"); + dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) + ? null + : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); + + dto.ChannelId = _tvDtoService.GetInternalChannelId(service.Name, info.ChannelId).ToString("N"); + + dto.StartDate = info.StartDate; + dto.RecordingStatus = info.Status; + dto.IsRepeat = info.IsRepeat; + dto.EpisodeTitle = info.EpisodeTitle; + dto.ChannelType = info.ChannelType; + dto.Audio = info.Audio; + dto.IsHD = info.IsHD; + dto.IsMovie = info.IsMovie; + dto.IsSeries = info.IsSeries; + dto.IsSports = info.IsSports; + dto.IsLive = info.IsLive; + dto.IsNews = info.IsNews; + dto.IsKids = info.IsKids; + dto.IsPremiere = info.IsPremiere; + dto.RunTimeTicks = (info.EndDate - info.StartDate).Ticks; + dto.OriginalAirDate = info.OriginalAirDate; + + dto.CanDelete = user == null + ? recording.CanDelete() + : recording.CanDelete(user); + + if (dto.MediaSources == null) + { + dto.MediaSources = recording.GetMediaSources(true).ToList(); + } + + if (dto.MediaStreams == null) + { + dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); + } + + if (info.Status == RecordingStatus.InProgress) + { + var now = DateTime.UtcNow.Ticks; + var start = info.StartDate.Ticks; + var end = info.EndDate.Ticks; + + var pct = now - start; + pct /= end; + pct *= 100; + dto.CompletionPercentage = pct; + } + + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = _tvDtoService.GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); + } + + if (channel != null) + { + dto.ChannelName = channel.Name; + + if (!string.IsNullOrEmpty(channel.PrimaryImagePath)) { - var service = GetService(i); + dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); + } + } + } - var channel = string.IsNullOrEmpty(i.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.RecordingInfo.ChannelId)); - return _tvDtoService.GetRecordingInfoDto(i, channel, service, user); - }) + public async Task> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken) + { + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + + var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false); + + var returnArray = internalResult.Items + .Select(i => _dtoService.GetBaseItemDto(i, options, user)) .ToArray(); if (user != null) @@ -1376,7 +1452,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv _dtoService.FillSyncInfo(returnArray, new DtoOptions(), user); } - return new QueryResult + return new QueryResult { Items = returnArray, TotalRecordCount = internalResult.TotalRecordCount @@ -1448,10 +1524,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task DeleteRecording(string recordingId) { - var dtoOptions = new DtoOptions(); - dtoOptions.Fields.Remove(ItemFields.SyncInfo); - - var recording = await GetRecording(recordingId, dtoOptions, CancellationToken.None).ConfigureAwait(false); + var recording = await GetInternalRecording(recordingId, CancellationToken.None).ConfigureAwait(false); if (recording == null) { @@ -1460,7 +1533,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(recording.ServiceName); - await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false); + await service.DeleteRecordingAsync(recording.RecordingInfo.Id, CancellationToken.None).ConfigureAwait(false); } public async Task CancelTimer(string id) @@ -1491,16 +1564,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); } - public async Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null) + public async Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null) { - var results = await GetRecordings(new RecordingQuery - { - UserId = user == null ? null : user.Id.ToString("N"), - Id = id + var item = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false); - }, options, cancellationToken).ConfigureAwait(false); + if (item == null) + { + return null; + } - return results.Items.FirstOrDefault(); + return _dtoService.GetBaseItemDto((BaseItem)item, options, user); } public async Task GetTimer(string id, CancellationToken cancellationToken) @@ -1776,60 +1849,57 @@ namespace MediaBrowser.Server.Implementations.LiveTv .ToList(); } - public async Task> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken) + public async Task> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken) { - var dtoOptions = new DtoOptions(); - dtoOptions.Fields.Remove(ItemFields.SyncInfo); - - var recordingResult = await GetRecordings(new RecordingQuery + var recordingResult = await GetInternalRecordings(new RecordingQuery { UserId = query.UserId - }, dtoOptions, cancellationToken).ConfigureAwait(false); + }, cancellationToken).ConfigureAwait(false); - var recordings = recordingResult.Items; + var recordings = recordingResult.Items.Cast().ToList(); - var groups = new List(); + var groups = new List(); var series = recordings - .Where(i => i.IsSeries) + .Where(i => i.RecordingInfo.IsSeries) .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase) .ToList(); - groups.AddRange(series.OrderByString(i => i.Key).Select(i => new RecordingGroupDto + groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto { Name = i.Key, RecordingCount = i.Count() })); - groups.Add(new RecordingGroupDto + groups.Add(new BaseItemDto { Name = "Kids", - RecordingCount = recordings.Count(i => i.IsKids) + RecordingCount = recordings.Count(i => i.RecordingInfo.IsKids) }); - groups.Add(new RecordingGroupDto + groups.Add(new BaseItemDto { Name = "Movies", - RecordingCount = recordings.Count(i => i.IsMovie) + RecordingCount = recordings.Count(i => i.RecordingInfo.IsMovie) }); - groups.Add(new RecordingGroupDto + groups.Add(new BaseItemDto { Name = "News", - RecordingCount = recordings.Count(i => i.IsNews) + RecordingCount = recordings.Count(i => i.RecordingInfo.IsNews) }); - groups.Add(new RecordingGroupDto + groups.Add(new BaseItemDto { Name = "Sports", - RecordingCount = recordings.Count(i => i.IsSports) + RecordingCount = recordings.Count(i => i.RecordingInfo.IsSports) }); - groups.Add(new RecordingGroupDto + groups.Add(new BaseItemDto { Name = "Others", - RecordingCount = recordings.Count(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries) + RecordingCount = recordings.Count(i => !i.RecordingInfo.IsSports && !i.RecordingInfo.IsNews && !i.RecordingInfo.IsMovie && !i.RecordingInfo.IsKids && !i.RecordingInfo.IsSeries) }); groups = groups @@ -1841,7 +1911,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv group.Id = group.Name.ToLower().GetMD5().ToString("N"); } - return new QueryResult + return new QueryResult { Items = groups.ToArray(), TotalRecordCount = groups.Count diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index c48de8797..286c7cd04 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -790,5 +790,6 @@ "OptionEnableFullscreen": "Enable Fullscreen", "ButtonServer": "Server", "HeaderAdmin": "Admin", - "HeaderLibrary": "Library" + "HeaderLibrary": "Library", + "HeaderMedia": "Media" } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 0c1452027..5625ef3be 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -50,6 +50,7 @@ using MediaBrowser.Dlna.Main; using MediaBrowser.Dlna.MediaReceiverRegistrar; using MediaBrowser.Dlna.Ssdp; using MediaBrowser.LocalMetadata.Providers; +using MediaBrowser.LocalMetadata.Savers; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.MediaEncoding.Encoder; using MediaBrowser.MediaEncoding.Subtitles; @@ -449,7 +450,7 @@ namespace MediaBrowser.Server.Startup.Common SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer); RegisterSingleInstance(SyncManager); - DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager); + DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager); RegisterSingleInstance(DtoService); var encryptionManager = new EncryptionManager(); @@ -989,7 +990,7 @@ namespace MediaBrowser.Server.Startup.Common list.Add(typeof(DlnaEntryPoint).Assembly); // Local metadata - list.Add(typeof(AlbumXmlProvider).Assembly); + list.Add(typeof(BoxSetXmlSaver).Assembly); // Xbmc list.Add(typeof(ArtistNfoProvider).Assembly); -- cgit v1.2.3 From ef8a1ccecbacab4ef535bb3e74bcb285a9f583fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 31 May 2015 15:12:58 -0400 Subject: normalize program object --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 6 +- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 14 +- .../MediaBrowser.Model.Portable.csproj | 3 - .../MediaBrowser.Model.net35.csproj | 3 - MediaBrowser.Model/ApiClient/IApiClient.cs | 14 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 6 + MediaBrowser.Model/LiveTv/ChannelInfoDto.cs | 2 +- MediaBrowser.Model/LiveTv/ProgramInfoDto.cs | 250 --------------------- MediaBrowser.Model/LiveTv/TimerInfoDto.cs | 6 +- MediaBrowser.Model/MediaBrowser.Model.csproj | 1 - .../Dto/DtoService.cs | 5 + .../LiveTv/LiveTvDtoService.cs | 82 +------ .../LiveTv/LiveTvManager.cs | 89 +++++--- 13 files changed, 97 insertions(+), 384 deletions(-) delete mode 100644 MediaBrowser.Model/LiveTv/ProgramInfoDto.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 86d8b9f99..c474642d5 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -161,7 +161,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Programs", "GET,POST", Summary = "Gets available live tv epgs..")] [Authenticated] - public class GetPrograms : IReturn> + public class GetPrograms : IReturn> { [ApiMember(Name = "ChannelIds", Description = "The channels to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string ChannelIds { get; set; } @@ -208,7 +208,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")] [Authenticated] - public class GetRecommendedPrograms : IReturn> + public class GetRecommendedPrograms : IReturn> { [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string UserId { get; set; } @@ -231,7 +231,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Programs/{Id}", "GET", Summary = "Gets a live tv program")] [Authenticated] - public class GetProgram : IReturn + public class GetProgram : IReturn { [ApiMember(Name = "Id", Description = "Program Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index e84fe902d..3aa1f66ef 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -170,7 +170,7 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// The user. /// Task{ProgramInfoDto}. - Task GetProgram(string id, CancellationToken cancellationToken, User user = null); + Task GetProgram(string id, CancellationToken cancellationToken, User user = null); /// /// Gets the programs. @@ -178,7 +178,7 @@ namespace MediaBrowser.Controller.LiveTv /// The query. /// The cancellation token. /// IEnumerable{ProgramInfo}. - Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken); + Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken); /// /// Updates the timer. @@ -240,7 +240,7 @@ namespace MediaBrowser.Controller.LiveTv /// The query. /// The cancellation token. /// Task{QueryResult{ProgramInfoDto}}. - Task> GetRecommendedPrograms(RecommendedProgramQuery query, + Task> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken); /// @@ -329,5 +329,13 @@ namespace MediaBrowser.Controller.LiveTv /// The dto. /// The user. void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null); + + /// + /// Adds the information to program dto. + /// + /// The item. + /// The dto. + /// The user. + void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, User user = null); } } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index a63b0a7c6..de9360e40 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -743,9 +743,6 @@ LiveTv\ProgramAudio.cs - - LiveTv\ProgramInfoDto.cs - LiveTv\ProgramQuery.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 036064238..ec7c3be5c 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -699,9 +699,6 @@ LiveTv\ProgramAudio.cs - - LiveTv\ProgramInfoDto.cs - LiveTv\ProgramQuery.cs diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 71ac0b14e..e52e7535b 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -929,14 +929,6 @@ namespace MediaBrowser.Model.ApiClient /// System.String. string GetImageUrl(ChannelInfoDto item, ImageOptions options); - /// - /// Gets the image URL. - /// - /// The item. - /// The options. - /// System.String. - string GetImageUrl(ProgramInfoDto item, ImageOptions options); - /// /// Gets the subtitle URL. /// @@ -1111,7 +1103,7 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// The cancellation token. /// Task{QueryResult{ProgramInfoDto}}. - Task> GetLiveTvProgramsAsync(ProgramQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task> GetLiveTvProgramsAsync(ProgramQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the live tv program asynchronous. @@ -1120,7 +1112,7 @@ namespace MediaBrowser.Model.ApiClient /// The user identifier. /// The cancellation token. /// Task{ProgramInfoDto}. - Task GetLiveTvProgramAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); + Task GetLiveTvProgramAsync(string id, string userId, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the recommended live tv programs asynchronous. @@ -1128,7 +1120,7 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// The cancellation token. /// Task{QueryResult{ProgramInfoDto}}. - Task> GetRecommendedLiveTvProgramsAsync(RecommendedProgramQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task> GetRecommendedLiveTvProgramsAsync(RecommendedProgramQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// /// Creates the live tv timer asynchronous. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 0f6ce4334..fb157e9ae 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1175,5 +1175,11 @@ namespace MediaBrowser.Model.Dto /// true if this instance is premiere; otherwise, false. public bool? IsPremiere { get; set; } + /// + /// Gets or sets the timer identifier. + /// + /// The timer identifier. + public string TimerId { get; set; } + } } diff --git a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs index 667ad4f14..fd901f29e 100644 --- a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs @@ -97,7 +97,7 @@ namespace MediaBrowser.Model.LiveTv /// Gets or sets the now playing program. /// /// The now playing program. - public ProgramInfoDto CurrentProgram { get; set; } + public BaseItemDto CurrentProgram { get; set; } /// /// Gets or sets the primary image aspect ratio, after image enhancements. diff --git a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs deleted file mode 100644 index 06136459f..000000000 --- a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs +++ /dev/null @@ -1,250 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.Library; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Runtime.Serialization; - -namespace MediaBrowser.Model.LiveTv -{ - [DebuggerDisplay("Name = {Name}, StartTime = {StartDate}, EndTime = {EndDate}")] - public class ProgramInfoDto : IHasPropertyChangedEvent, IItemDto, IHasServerId - { - /// - /// Id of the program. - /// - public string Id { get; set; } - - /// - /// Gets or sets the primary image aspect ratio. - /// - /// The primary image aspect ratio. - public double? PrimaryImageAspectRatio { get; set; } - - /// - /// Gets or sets the server identifier. - /// - /// The server identifier. - public string ServerId { get; set; } - - /// - /// Gets or sets the original primary image aspect ratio. - /// - /// The original primary image aspect ratio. - public double? OriginalPrimaryImageAspectRatio { get; set; } - - /// - /// Gets or sets the type of the media. - /// - /// The type of the media. - public string MediaType { get; set; } - - /// - /// Gets or sets the timer identifier. - /// - /// The timer identifier. - public string TimerId { get; set; } - - /// - /// Gets or sets the series timer identifier. - /// - /// The series timer identifier. - public string SeriesTimerId { get; set; } - - /// - /// Gets or sets the external identifier. - /// - /// The external identifier. - public string ExternalId { get; set; } - - /// - /// Gets or sets the channel identifier. - /// - /// The channel identifier. - public string ChannelId { get; set; } - - /// - /// Gets or sets the channel primary image tag. - /// - /// The channel primary image tag. - public string ChannelPrimaryImageTag { get; set; } - - /// - /// Gets or sets the play access. - /// - /// The play access. - public PlayAccess PlayAccess { get; set; } - - /// - /// Gets or sets the name of the channel. - /// - /// The name of the channel. - public string ChannelName { get; set; } - - /// - /// Gets or sets the community rating. - /// - /// The community rating. - public float? CommunityRating { get; set; } - - /// - /// Gets or sets the official rating. - /// - /// The official rating. - public string OfficialRating { get; set; } - - /// - /// Gets or sets the production year. - /// - /// The production year. - public int? ProductionYear { get; set; } - - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - - /// - /// Name of the program - /// - public string Name { get; set; } - - /// - /// Overview of the recording. - /// - public string Overview { 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 List Genres { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is hd. - /// - /// true if this instance is hd; otherwise, false. - public bool? IsHD { get; set; } - - /// - /// Gets or sets the audio. - /// - /// The audio. - public ProgramAudio? Audio { get; set; } - - /// - /// Gets or sets the original air date. - /// - /// The original air date. - public DateTime? OriginalAirDate { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is repeat. - /// - /// true if this instance is repeat; otherwise, false. - public bool IsRepeat { get; set; } - - /// - /// Gets or sets the episode title. - /// - /// The episode title. - public string EpisodeTitle { get; set; } - - /// - /// Gets or sets the image tags. - /// - /// The image tags. - public Dictionary ImageTags { get; set; } - - /// - /// Gets or sets the user data. - /// - /// The user data. - public UserItemDataDto UserData { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is movie. - /// - /// true if this instance is movie; otherwise, false. - public bool IsMovie { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is sports. - /// - /// true if this instance is sports; otherwise, false. - public bool IsSports { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is series. - /// - /// true if this instance is series; otherwise, false. - public bool IsSeries { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is live. - /// - /// true if this instance is live; otherwise, false. - public bool IsLive { get; set; } - - /// - /// Gets or sets the type. - /// - /// The type. - public string Type { get; set; } - - /// - /// Gets or sets the run time ticks. - /// - /// The run time ticks. - public long? RunTimeTicks { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is news. - /// - /// true if this instance is news; otherwise, false. - public bool IsNews { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is kids. - /// - /// true if this instance is kids; otherwise, false. - public bool IsKids { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is premiere. - /// - /// true if this instance is premiere; otherwise, false. - public bool IsPremiere { get; set; } - - /// - /// Gets a value indicating whether this instance has primary image. - /// - /// true if this instance has primary image; otherwise, false. - [IgnoreDataMember] - public bool HasPrimaryImage - { - get { return ImageTags != null && ImageTags.ContainsKey(ImageType.Primary); } - } - - public ProgramInfoDto() - { - Genres = new List(); - ImageTags = new Dictionary(); - } - - public event PropertyChangedEventHandler PropertyChanged; - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index 16cac945f..c33535a3d 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -1,4 +1,6 @@ -namespace MediaBrowser.Model.LiveTv +using MediaBrowser.Model.Dto; + +namespace MediaBrowser.Model.LiveTv { public class TimerInfoDto : BaseTimerInfoDto { @@ -30,7 +32,7 @@ /// Gets or sets the program information. /// /// The program information. - public ProgramInfoDto ProgramInfo { get; set; } + public BaseItemDto ProgramInfo { get; set; } } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index c567c1f6a..d134cb2e3 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -259,7 +259,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index cf56fc9ce..5853b5b75 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -357,6 +357,11 @@ namespace MediaBrowser.Server.Implementations.Dto _livetvManager().AddInfoToRecordingDto(item, dto, user); } + else if (item is LiveTvProgram) + { + _livetvManager().AddInfoToProgramDto(item, dto, user); + } + return dto; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 939d057cb..f24fe0019 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (program != null) { - dto.ProgramInfo = GetProgramInfoDto(program, channel); + dto.ProgramInfo = _dtoService.GetBaseItemDto(program, new DtoOptions()); dto.ProgramInfo.TimerId = dto.Id; dto.ProgramInfo.SeriesTimerId = dto.SeriesTimerId; @@ -238,77 +238,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (currentProgram != null) { - dto.CurrentProgram = GetProgramInfoDto(currentProgram, info, user); - } - - return dto; - } - - public ProgramInfoDto GetProgramInfoDto(LiveTvProgram item, LiveTvChannel channel, User user = null) - { - var dto = new ProgramInfoDto - { - Id = GetInternalProgramId(item.ServiceName, item.ExternalId).ToString("N"), - ChannelId = GetInternalChannelId(item.ServiceName, item.ExternalChannelId).ToString("N"), - Overview = item.Overview, - Genres = item.Genres, - ExternalId = item.ExternalId, - Name = item.Name, - ServiceName = item.ServiceName, - StartDate = item.StartDate, - OfficialRating = item.OfficialRating, - IsHD = item.IsHD, - OriginalAirDate = item.OriginalAirDate, - Audio = item.Audio, - CommunityRating = GetClientCommunityRating(item.CommunityRating), - IsRepeat = item.IsRepeat, - EpisodeTitle = item.EpisodeTitle, - IsMovie = item.IsMovie, - IsSeries = item.IsSeries, - IsSports = item.IsSports, - IsLive = item.IsLive, - IsNews = item.IsNews, - IsKids = item.IsKids, - IsPremiere = item.IsPremiere, - Type = "Program", - MediaType = item.MediaType, - ServerId = _appHost.SystemId, - ProductionYear = item.ProductionYear - }; - - if (item.EndDate.HasValue) - { - dto.EndDate = item.EndDate.Value; - - dto.RunTimeTicks = (item.EndDate.Value - item.StartDate).Ticks; - } - - if (channel != null) - { - dto.ChannelName = channel.Name; - - if (!string.IsNullOrEmpty(channel.PrimaryImagePath)) - { - dto.ChannelPrimaryImageTag = GetImageTag(channel); - } - } - - var imageTag = GetImageTag(item); - - if (imageTag != null) - { - dto.ImageTags[ImageType.Primary] = imageTag; - _dtoService.AttachPrimaryImageAspectRatio(dto, item, new List - { - ItemFields.PrimaryImageAspectRatio - }); - } - - if (user != null) - { - dto.UserData = _userDataManager.GetUserDataDto(item, user); - - dto.PlayAccess = item.GetPlayAccess(user); + dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, new DtoOptions(), user); } return dto; @@ -365,7 +295,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return name.ToLower().GetMBId(typeof(ILiveTvRecording)); } - public async Task GetTimerInfo(TimerInfoDto dto, bool isNew, ILiveTvManager liveTv, CancellationToken cancellationToken) + public async Task GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken) { var info = new TimerInfo { @@ -405,7 +335,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId)) { - var program = await liveTv.GetProgram(dto.ProgramId, cancellationToken).ConfigureAwait(false); + var program = liveTv.GetInternalProgram(dto.ProgramId); if (program != null) { @@ -426,7 +356,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return info; } - public async Task GetSeriesTimerInfo(SeriesTimerInfoDto dto, bool isNew, ILiveTvManager liveTv, CancellationToken cancellationToken) + public async Task GetSeriesTimerInfo(SeriesTimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken) { var info = new SeriesTimerInfo { @@ -468,7 +398,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId)) { - var program = await liveTv.GetProgram(dto.ProgramId, cancellationToken).ConfigureAwait(false); + var program = liveTv.GetInternalProgram(dto.ProgramId); if (program != null) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 52c96bca6..dbae6d03e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -284,7 +284,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return _libraryManager.GetItemById(id) as LiveTvChannel; } - private LiveTvProgram GetInternalProgram(string id) + internal LiveTvProgram GetInternalProgram(string id) { var guid = new Guid(id); @@ -732,20 +732,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv return GetInternalChannel(internalProgramChannelId); } - public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null) + public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null) { var program = GetInternalProgram(id); - var channel = GetChannel(program); - - var dto = _tvDtoService.GetProgramInfoDto(program, channel, user); + var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user); await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false); return dto; } - public async Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) + public async Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) { IEnumerable programs = GetPrograms(); @@ -839,19 +837,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv } var returnArray = returnPrograms - .Select(i => - { - var channel = GetChannel(i); - - return _tvDtoService.GetProgramInfoDto(i, channel, user); - }) + .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user)) .ToArray(); RefreshIfNeeded(programList); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); - var result = new QueryResult + var result = new QueryResult { Items = returnArray, TotalRecordCount = programList.Count @@ -924,24 +917,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv return result; } - public async Task> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken) + public async Task> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken) { var internalResult = await GetRecommendedProgramsInternal(query, cancellationToken).ConfigureAwait(false); var user = _userManager.GetUserById(query.UserId); var returnArray = internalResult.Items - .Select(i => - { - var channel = GetChannel(i); - - return _tvDtoService.GetProgramInfoDto(i, channel, user); - }) + .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user)) .ToArray(); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); - var result = new QueryResult + var result = new QueryResult { Items = returnArray, TotalRecordCount = internalResult.TotalRecordCount @@ -1020,37 +1008,40 @@ namespace MediaBrowser.Server.Implementations.LiveTv }).Sum(); } - private async Task AddRecordingInfo(IEnumerable programs, CancellationToken cancellationToken) + private async Task AddRecordingInfo(IEnumerable programs, CancellationToken cancellationToken) { var timers = new Dictionary>(); foreach (var program in programs) { + var internalProgram = GetInternalProgram(program.Id); + List timerList; - if (!timers.TryGetValue(program.ServiceName, out timerList)) + if (!timers.TryGetValue(internalProgram.ServiceName, out timerList)) { try { - var tempTimers = await GetService(program.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false); - timers[program.ServiceName] = timerList = tempTimers.ToList(); + var tempTimers = await GetService(internalProgram.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false); + timers[internalProgram.ServiceName] = timerList = tempTimers.ToList(); } catch (Exception ex) { _logger.ErrorException("Error getting timer infos", ex); - timers[program.ServiceName] = timerList = new List(); + timers[internalProgram.ServiceName] = timerList = new List(); } } - var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, program.ExternalId, StringComparison.OrdinalIgnoreCase)); + + var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, internalProgram.ExternalId, StringComparison.OrdinalIgnoreCase)); if (timer != null) { - program.TimerId = _tvDtoService.GetInternalTimerId(program.ServiceName, timer.Id) + program.TimerId = _tvDtoService.GetInternalTimerId(internalProgram.ServiceName, timer.Id) .ToString("N"); if (!string.IsNullOrEmpty(timer.SeriesTimerId)) { - program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(program.ServiceName, timer.SeriesTimerId) + program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(internalProgram.ServiceName, timer.SeriesTimerId) .ToString("N"); } } @@ -1362,6 +1353,43 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } + public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, User user = null) + { + var program = (LiveTvProgram)item; + var service = GetService(program); + + var channel = string.IsNullOrEmpty(program.ExternalChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, program.ExternalChannelId)); + + dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N"); + + dto.ChannelId = _tvDtoService.GetInternalChannelId(service.Name, program.ExternalChannelId).ToString("N"); + + dto.StartDate = program.StartDate; + dto.IsRepeat = program.IsRepeat; + dto.EpisodeTitle = program.EpisodeTitle; + dto.ChannelType = program.ChannelType; + dto.Audio = program.Audio; + dto.IsHD = program.IsHD; + dto.IsMovie = program.IsMovie; + dto.IsSeries = program.IsSeries; + dto.IsSports = program.IsSports; + dto.IsLive = program.IsLive; + dto.IsNews = program.IsNews; + dto.IsKids = program.IsKids; + dto.IsPremiere = program.IsPremiere; + dto.OriginalAirDate = program.OriginalAirDate; + + if (channel != null) + { + dto.ChannelName = channel.Name; + + if (!string.IsNullOrEmpty(channel.PrimaryImagePath)) + { + dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); + } + } + } + public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null) { var recording = (ILiveTvRecording)item; @@ -1392,7 +1420,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.IsNews = info.IsNews; dto.IsKids = info.IsKids; dto.IsPremiere = info.IsPremiere; - dto.RunTimeTicks = (info.EndDate - info.StartDate).Ticks; dto.OriginalAirDate = info.OriginalAirDate; dto.CanDelete = user == null @@ -1751,7 +1778,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Name = program.Name; info.Overview = program.Overview; info.ProgramId = programDto.Id; - info.ExternalProgramId = programDto.ExternalId; + info.ExternalProgramId = program.ExternalId; if (program.EndDate.HasValue) { -- cgit v1.2.3 From f2abd8ba39eefd5397eb3f0e327efbca8d8ecd0f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Jun 2015 10:49:23 -0400 Subject: update live tv database --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 11 +- MediaBrowser.Api/Playback/TranscodingThrottler.cs | 13 +- .../Channels/ChannelAudioItem.cs | 1 - .../Channels/ChannelFolderItem.cs | 1 - .../Channels/ChannelVideoItem.cs | 1 - MediaBrowser.Controller/Entities/BaseItem.cs | 6 + .../Entities/IHasProgramAttributes.cs | 9 + MediaBrowser.Controller/Entities/IHasStartDate.cs | 9 + .../Entities/InternalItemsQuery.cs | 12 + MediaBrowser.Controller/Library/ILibraryManager.cs | 8 + MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 20 +- .../MediaBrowser.Controller.csproj | 2 + .../Persistence/IItemRepository.cs | 29 +- MediaBrowser.Providers/Omdb/OmdbItemProvider.cs | 30 +- .../IO/LibraryMonitor.cs | 2 +- .../Library/LibraryManager.cs | 13 + .../LiveTv/LiveTvManager.cs | 377 ++++++++------------- .../LiveTv/ProgramImageProvider.cs | 4 +- .../Persistence/SqliteItemRepository.cs | 332 +++++++++++++++++- 20 files changed, 583 insertions(+), 299 deletions(-) create mode 100644 MediaBrowser.Controller/Entities/IHasProgramAttributes.cs create mode 100644 MediaBrowser.Controller/Entities/IHasStartDate.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index db3dbf048..68087309b 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -340,7 +340,7 @@ namespace MediaBrowser.Api // We can really reduce the timeout for apps that are using the newer api if (!string.IsNullOrWhiteSpace(job.PlaySessionId)) { - timerDuration = 60000; + timerDuration = 120000; } } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 6ca5c57f3..41d26417d 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -879,7 +879,7 @@ namespace MediaBrowser.Api.Playback.Hls if (!EnableSplitTranscoding(state)) { - args += " -copyts"; + //args += " -copyts"; } return args; @@ -910,11 +910,11 @@ namespace MediaBrowser.Api.Playback.Hls //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); - } + 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); } var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty; @@ -959,6 +959,7 @@ namespace MediaBrowser.Api.Playback.Hls private bool EnableSplitTranscoding(StreamState state) { + return false; if (string.Equals(Request.QueryString["EnableSplitTranscoding"], "false", StringComparison.OrdinalIgnoreCase)) { return false; diff --git a/MediaBrowser.Api/Playback/TranscodingThrottler.cs b/MediaBrowser.Api/Playback/TranscodingThrottler.cs index fec3dda86..f94d5d837 100644 --- a/MediaBrowser.Api/Playback/TranscodingThrottler.cs +++ b/MediaBrowser.Api/Playback/TranscodingThrottler.cs @@ -42,7 +42,14 @@ namespace MediaBrowser.Api.Playback var options = GetOptions(); - if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleThresholdInSeconds)) + var threshold = options.ThrottleThresholdInSeconds; + + if (!options.EnableThrottling) + { + threshold *= 2; + } + + if (IsThrottleAllowed(_job, threshold)) { PauseTranscoding(); } @@ -56,7 +63,7 @@ namespace MediaBrowser.Api.Playback { if (!_isPaused) { - _logger.Debug("Sending pause command to ffmpeg"); + //_logger.Debug("Sending pause command to ffmpeg"); try { @@ -74,7 +81,7 @@ namespace MediaBrowser.Api.Playback { if (_isPaused) { - _logger.Debug("Sending unpause command to ffmpeg"); + //_logger.Debug("Sending unpause command to ffmpeg"); try { diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index 82fe66c7b..aa4b6731c 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -15,7 +15,6 @@ namespace MediaBrowser.Controller.Channels { public string ExternalId { get; set; } - public string ChannelId { get; set; } public string DataVersion { get; set; } public ChannelItemType ChannelItemType { get; set; } diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index 641d37161..7e9da52a9 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Channels { public string ExternalId { get; set; } - public string ChannelId { get; set; } public string DataVersion { get; set; } public ChannelItemType ChannelItemType { get; set; } diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index ef3cc7cba..ca5e343f8 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -16,7 +16,6 @@ namespace MediaBrowser.Controller.Channels { public string ExternalId { get; set; } - public string ChannelId { get; set; } public string DataVersion { get; set; } public ChannelItemType ChannelItemType { get; set; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 8b6cbdc93..014b3ae6a 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.Entities public List ImageInfos { get; set; } + /// + /// Gets or sets the channel identifier. + /// + /// The channel identifier. + public string ChannelId { get; set; } + [IgnoreDataMember] public virtual bool SupportsAddingToPlaylist { diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs new file mode 100644 index 000000000..1878d8d2c --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Controller.Entities +{ + public interface IHasProgramAttributes + { + bool IsMovie { get; set; } + bool IsSports { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasStartDate.cs b/MediaBrowser.Controller/Entities/IHasStartDate.cs new file mode 100644 index 000000000..a6714fb96 --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasStartDate.cs @@ -0,0 +1,9 @@ +using System; + +namespace MediaBrowser.Controller.Entities +{ + public interface IHasStartDate + { + DateTime StartDate { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 727f756f1..245c11169 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -73,6 +73,17 @@ namespace MediaBrowser.Controller.Entities public string[] Tags { get; set; } public string[] OfficialRatings { get; set; } + public DateTime? MinStartDate { get; set; } + public DateTime? MaxStartDate { get; set; } + public DateTime? MinEndDate { get; set; } + public DateTime? MaxEndDate { get; set; } + public bool? IsAiring { get; set; } + + public bool? IsMovie { get; set; } + public bool? IsSports { get; set; } + + public string[] ChannelIds { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; @@ -89,6 +100,7 @@ namespace MediaBrowser.Controller.Entities Years = new int[] { }; PersonTypes = new string[] { }; PersonIds = new string[] { }; + ChannelIds = new string[] { }; } } } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index c00912115..aa8799fa6 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Library { @@ -132,6 +133,13 @@ namespace MediaBrowser.Controller.Library /// BaseItem. BaseItem GetItemById(Guid id); + /// + /// Gets the items. + /// + /// The query. + /// QueryResult<BaseItem>. + QueryResult GetItems(InternalItemsQuery query); + /// /// Gets the memory item by identifier. /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 0609df4c6..8232c5c7a 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; @@ -7,12 +6,10 @@ using MediaBrowser.Model.Users; using System; using System.Linq; using System.Runtime.Serialization; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvProgram : BaseItem, ILiveTvItem, IHasLookupInfo + public class LiveTvProgram : BaseItem, ILiveTvItem, IHasLookupInfo, IHasStartDate, IHasProgramAttributes { /// /// Gets the user data key. @@ -28,12 +25,6 @@ namespace MediaBrowser.Controller.LiveTv /// public string ExternalId { get; set; } - /// - /// Gets or sets the channel identifier. - /// - /// The channel identifier. - public string ExternalChannelId { get; set; } - /// /// Gets or sets the original air date. /// @@ -204,15 +195,6 @@ namespace MediaBrowser.Controller.LiveTv return "Program"; } - public override Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken) - { - DateLastSaved = DateTime.UtcNow; - - // Avoid library manager and keep out of in-memory cache - // Not great that this class has to know about that, but we'll improve that later. - return ItemRepository.SaveItem(this, cancellationToken); - } - protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b66e6b9c8..e1a18164e 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -149,10 +149,12 @@ + + diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index aa5376ec3..7c02a0ea1 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Persistence { @@ -102,13 +103,6 @@ namespace MediaBrowser.Controller.Persistence /// IEnumerable{ChildDefinition}. IEnumerable GetChildren(Guid parentId); - /// - /// Gets the type of the items of. - /// - /// The type. - /// IEnumerable{Guid}. - IEnumerable GetItemIdsOfType(Type type); - /// /// Saves the children. /// @@ -135,11 +129,24 @@ namespace MediaBrowser.Controller.Persistence Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken); /// - /// Gets the type of the items of. + /// Gets the item ids. /// - /// The type. - /// IEnumerable<BaseItem>. - IEnumerable GetItemsOfType(Type type); + /// The query. + /// IEnumerable<Guid>. + QueryResult GetItemIds(InternalItemsQuery query); + /// + /// Gets the items. + /// + /// The query. + /// QueryResult<BaseItem>. + QueryResult GetItems(InternalItemsQuery query); + + /// + /// Gets the item ids list. + /// + /// The query. + /// List<Guid>. + List GetItemIdsList(InternalItemsQuery query); } } diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index c79d04b4f..596b864f7 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -1,21 +1,20 @@ -using System.Linq; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; -using MediaBrowser.Providers.Movies; -using MediaBrowser.Providers.TV; using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; @@ -23,7 +22,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Omdb { public class OmdbItemProvider : IRemoteMetadataProvider, - IRemoteMetadataProvider, IRemoteMetadataProvider + IRemoteMetadataProvider, IRemoteMetadataProvider, IRemoteMetadataProvider { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; @@ -48,6 +47,16 @@ namespace MediaBrowser.Providers.Omdb return GetSearchResults(searchInfo, "movie", cancellationToken); } + public Task> GetSearchResults(LiveTvProgramLookupInfo searchInfo, CancellationToken cancellationToken) + { + if (!searchInfo.IsMovie) + { + return Task.FromResult>(new List()); + } + + return GetSearchResults(searchInfo, "movie", cancellationToken); + } + public async Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) { var list = new List(); @@ -169,13 +178,22 @@ namespace MediaBrowser.Providers.Omdb return result; } + public Task> GetMetadata(LiveTvProgramLookupInfo info, CancellationToken cancellationToken) + { + if (!info.IsMovie) + { + return Task.FromResult(new MetadataResult()); + } + return GetMovieResult(info, cancellationToken); + } + public Task> GetMetadata(MovieInfo info, CancellationToken cancellationToken) { return GetMovieResult(info, cancellationToken); } private async Task> GetMovieResult(ItemLookupInfo info, CancellationToken cancellationToken) - where T : Video, new() + where T : BaseItem, new() { var result = new MetadataResult { diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 491549d64..ef2888e4a 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -84,7 +84,7 @@ namespace MediaBrowser.Server.Implementations.IO // This is an arbitraty amount of time, but delay it because file system writes often trigger events after RemoveTempIgnore has been called. // Seeing long delays in some situations, especially over the network, sometimes up to 45 seconds // But if we make this delay too high, we risk missing legitimate changes - await Task.Delay(10000).ConfigureAwait(false); + await Task.Delay(15000).ConfigureAwait(false); string val; _tempIgnoredPaths.TryRemove(path, out val); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index ee0bf354f..ed5dde4c5 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -16,6 +16,7 @@ using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; using MediaBrowser.Naming.Audio; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.TV; @@ -1209,6 +1210,18 @@ namespace MediaBrowser.Server.Implementations.Library return item; } + public QueryResult GetItems(InternalItemsQuery query) + { + var result = ItemRepository.GetItemIdsList(query); + + var items = result.Select(GetItemById).ToArray(); + + return new QueryResult + { + Items = items + }; + } + /// /// Gets the intros. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index dbae6d03e..47e862b9f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -17,7 +17,6 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; using System; @@ -54,10 +53,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly ConcurrentDictionary _openStreams = new ConcurrentDictionary(); - private List _channelIdList = new List(); - private Dictionary _programs; - private readonly ConcurrentDictionary _refreshedPrograms = new ConcurrentDictionary(); - public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) { _config = config; @@ -108,44 +103,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv _taskManager.CancelIfRunningAndQueue(); } - private readonly object _programsDataLock = new object(); - private Dictionary GetProgramsDictionary() - { - if (_programs == null) - { - lock (_programsDataLock) - { - if (_programs == null) - { - var dict = new Dictionary(); - - foreach (var item in _itemRepo.GetItemsOfType(typeof(LiveTvProgram)) - .Cast() - .ToList()) - { - dict[item.Id] = item; - } - - _programs = dict; - } - } - } - - return _programs; - } - - private IEnumerable GetPrograms() - { - return GetProgramsDictionary().Values; - } - public async Task> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); - var channels = _channelIdList.Select(_libraryManager.GetItemById) - .Where(i => i != null) - .OfType(); + var channels = _libraryManager.GetItems(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvChannel).Name } + + }).Items.Cast(); if (user != null) { @@ -258,9 +224,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv var returnList = new List(); + var now = DateTime.UtcNow; + + var programs = _libraryManager.GetItems(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + MaxStartDate = now, + MinEndDate = now + + }).Items.Cast().OrderBy(i => i.StartDate).ToList(); + foreach (var channel in internalResult.Items) { - var currentProgram = GetCurrentProgram(channel.ExternalId); + var channelIdString = channel.Id.ToString("N"); + var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString, StringComparison.OrdinalIgnoreCase)); returnList.Add(_tvDtoService.GetChannelInfoDto(channel, currentProgram, user)); } @@ -286,34 +263,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv internal LiveTvProgram GetInternalProgram(string id) { - var guid = new Guid(id); - - LiveTvProgram obj = null; - - GetProgramsDictionary().TryGetValue(guid, out obj); - - if (obj != null) - { - RefreshIfNeeded(obj); - } - return obj; - } - - private void RefreshIfNeeded(LiveTvProgram program) - { - if (!_refreshedPrograms.ContainsKey(program.Id)) - { - _refreshedPrograms.TryAdd(program.Id, true); - _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions()); - } + return _libraryManager.GetItemById(id) as LiveTvProgram; } - private void RefreshIfNeeded(IEnumerable programs) + internal LiveTvProgram GetInternalProgram(Guid id) { - foreach (var program in programs) - { - RefreshIfNeeded(program); - } + return _libraryManager.GetItemById(id) as LiveTvProgram; } public async Task GetInternalRecording(string id, CancellationToken cancellationToken) @@ -598,14 +553,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv return item; } - private async Task GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken) + private async Task GetProgram(ProgramInfo info, string channelId, ChannelType channelType, string serviceName, CancellationToken cancellationToken) { var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id); var item = _libraryManager.GetItemById(id) as LiveTvProgram; + var isNew = false; if (item == null) { + isNew = true; item = new LiveTvProgram { Name = info.Name, @@ -619,8 +576,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ServiceName = serviceName; item.Audio = info.Audio; - item.ExternalChannelId = info.ChannelId; - item.CommunityRating = info.CommunityRating; + item.ChannelId = channelId; + item.CommunityRating = item.CommunityRating ?? info.CommunityRating; item.EndDate = info.EndDate; item.EpisodeTitle = info.EpisodeTitle; item.ExternalId = info.Id; @@ -636,8 +593,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.IsSeries = info.IsSeries; item.IsSports = info.IsSports; item.Name = info.Name; - item.OfficialRating = info.OfficialRating; - item.Overview = info.Overview; + item.OfficialRating = item.OfficialRating ?? info.OfficialRating; + item.Overview = item.Overview ?? info.Overview; item.OriginalAirDate = info.OriginalAirDate; item.ProviderImagePath = info.ImagePath; item.ProviderImageUrl = info.ImageUrl; @@ -647,7 +604,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; - await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + if (isNew) + { + await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + } + else + { + await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } + + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); return item; } @@ -721,17 +687,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv return recording; } - private LiveTvChannel GetChannel(LiveTvProgram program) - { - var programChannelId = program.ExternalChannelId; - - if (string.IsNullOrWhiteSpace(programChannelId)) return null; - - var internalProgramChannelId = _tvDtoService.GetInternalChannelId(program.ServiceName, programChannelId); - - return GetInternalChannel(internalProgramChannelId); - } - public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null) { var program = GetInternalProgram(id); @@ -745,64 +700,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) { - IEnumerable programs = GetPrograms(); - - if (query.MinEndDate.HasValue) + var internalQuery = new InternalItemsQuery { - var val = query.MinEndDate.Value; - - programs = programs.Where(i => i.EndDate.HasValue && i.EndDate.Value >= val); - } - - if (query.MinStartDate.HasValue) - { - var val = query.MinStartDate.Value; - - programs = programs.Where(i => i.StartDate >= val); - } - - if (query.MaxEndDate.HasValue) - { - var val = query.MaxEndDate.Value; - - programs = programs.Where(i => i.EndDate.HasValue && i.EndDate.Value <= val); - } - - if (query.MaxStartDate.HasValue) - { - var val = query.MaxStartDate.Value; - - programs = programs.Where(i => i.StartDate <= val); - } + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + MinEndDate = query.MinEndDate, + MinStartDate = query.MinStartDate, + MaxEndDate = query.MaxEndDate, + MaxStartDate = query.MaxStartDate, + ChannelIds = query.ChannelIds, + IsMovie = query.IsMovie, + IsSports = query.IsSports + }; if (query.HasAired.HasValue) { - var val = query.HasAired.Value; - programs = programs.Where(i => i.HasAired == val); - } - - if (query.ChannelIds.Length > 0) - { - var guids = query.ChannelIds.Select(i => new Guid(i)).ToList(); - - programs = programs.Where(i => + if (query.HasAired.Value) { - var programChannelId = i.ExternalChannelId; - - var service = GetService(i); - var internalProgramChannelId = _tvDtoService.GetInternalChannelId(service.Name, programChannelId); - - return guids.Contains(internalProgramChannelId); - }); + internalQuery.MaxEndDate = DateTime.UtcNow; + } + else + { + internalQuery.MinEndDate = DateTime.UtcNow; + } } - 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)); - } + IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); // Apply genre filter if (query.Genres.Length > 0) @@ -810,14 +732,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv programs = programs.Where(p => p.Genres.Any(g => query.Genres.Contains(g, StringComparer.OrdinalIgnoreCase))); } - if (query.IsMovie.HasValue) - { - programs = programs.Where(p => p.IsMovie == query.IsMovie); - } - - if (query.IsSports.HasValue) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + if (user != null) { - programs = programs.Where(p => p.IsSports == query.IsSports); + // 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) @@ -840,8 +760,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user)) .ToArray(); - RefreshIfNeeded(programList); - await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); var result = new QueryResult @@ -855,35 +773,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken) { - IEnumerable programs = GetPrograms(); - - var user = _userManager.GetUserById(query.UserId); - - // Avoid implicitly captured closure - var currentUser = user; - programs = programs.Where(i => i.IsVisible(currentUser)); - - if (query.IsAiring.HasValue) + var internalQuery = new InternalItemsQuery { - var val = query.IsAiring.Value; - programs = programs.Where(i => i.IsAiring == val); - } + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + IsAiring = query.IsAiring, + IsMovie = query.IsMovie, + IsSports = query.IsSports + }; if (query.HasAired.HasValue) { - var val = query.HasAired.Value; - programs = programs.Where(i => i.HasAired == val); + if (query.HasAired.Value) + { + internalQuery.MaxEndDate = DateTime.UtcNow; + } + else + { + internalQuery.MinEndDate = DateTime.UtcNow; + } } - if (query.IsMovie.HasValue) - { - programs = programs.Where(p => p.IsMovie == query.IsMovie.Value); - } + IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); - if (query.IsSports.HasValue) - { - programs = programs.Where(p => p.IsSports == query.IsSports.Value); - } + var user = _userManager.GetUserById(query.UserId); + + // Avoid implicitly captured closure + var currentUser = user; + programs = programs.Where(i => i.IsVisible(currentUser)); var programList = programs.ToList(); @@ -904,8 +820,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv programList = programs.ToList(); - RefreshIfNeeded(programList); - var returnArray = programList.ToArray(); var result = new QueryResult @@ -952,8 +866,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv score++; } - var internalChannelId = _tvDtoService.GetInternalChannelId(program.ServiceName, program.ExternalChannelId); - var channel = GetInternalChannel(internalChannelId); + var channel = GetInternalChannel(program.ChannelId); var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey()); @@ -1048,17 +961,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) + internal Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { - var innerProgress = new ActionableProgress(); - innerProgress.RegisterAction(p => progress.Report(p * .9)); - await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false); - - innerProgress = new ActionableProgress(); - innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); - await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); - - RefreshIfNeeded(GetPrograms().ToList()); + return RefreshChannelsInternal(progress, cancellationToken); } private async Task RefreshChannelsInternal(IProgress progress, CancellationToken cancellationToken) @@ -1068,6 +973,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv ? 0 : 1 / _services.Count; + var newChannelIdList = new List(); + var newProgramIdList = new List(); + foreach (var service in _services) { cancellationToken.ThrowIfCancellationRequested(); @@ -1077,7 +985,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv var innerProgress = new ActionableProgress(); innerProgress.RegisterAction(p => progress.Report(p * progressPerService)); - await RefreshChannelsInternal(service, innerProgress, cancellationToken).ConfigureAwait(false); + var idList = await RefreshChannelsInternal(service, innerProgress, cancellationToken).ConfigureAwait(false); + + newChannelIdList.AddRange(idList.Item1); + newProgramIdList.AddRange(idList.Item2); } catch (OperationCanceledException) { @@ -1095,10 +1006,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(100 * percent); } + await CleanDatabaseInternal(newChannelIdList, typeof(LiveTvChannel).Name, progress, cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(newProgramIdList, typeof(LiveTvProgram).Name, progress, cancellationToken).ConfigureAwait(false); + + // Load these now which will prefetch metadata + var dtoOptions = new DtoOptions(); + dtoOptions.Fields.Remove(ItemFields.SyncInfo); + await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false); + progress.Report(100); } - private async Task RefreshChannelsInternal(ILiveTvService service, IProgress progress, CancellationToken cancellationToken) + private async Task,List>> RefreshChannelsInternal(ILiveTvService service, IProgress progress, CancellationToken cancellationToken) { progress.Report(10); @@ -1137,23 +1056,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(5 * percent + 10); } - _channelIdList = list.Select(i => i.Id).ToList(); progress.Report(15); numComplete = 0; - var programs = new List(); + var programs = new List(); + var channels = new List(); var guideDays = GetGuideDays(list.Count); cancellationToken.ThrowIfCancellationRequested(); - foreach (var item in list) + foreach (var currentChannel in list) { + channels.Add(currentChannel.Id); cancellationToken.ThrowIfCancellationRequested(); - // Avoid implicitly captured closure - var currentChannel = item; - try { var start = DateTime.UtcNow.AddHours(-1); @@ -1161,9 +1078,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false); + var channelId = currentChannel.Id.ToString("N"); + foreach (var program in channelPrograms) { - programs.Add(await GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false)); + var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false); + programs.Add(programItem.Id); } } catch (OperationCanceledException) @@ -1181,44 +1101,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(80 * percent + 10); } - - lock (_programsDataLock) - { - _programs = programs.ToDictionary(i => i.Id); - } - - _refreshedPrograms.Clear(); - progress.Report(90); - - // Load these now which will prefetch metadata - var dtoOptions = new DtoOptions(); - dtoOptions.Fields.Remove(ItemFields.SyncInfo); - await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false); progress.Report(100); - } - private Task CleanDatabaseInternal(IProgress progress, CancellationToken cancellationToken) - { - return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken); + return new Tuple,List>(channels, programs); } - private async Task DeleteOldPrograms(List currentIdList, IProgress progress, CancellationToken cancellationToken) + private async Task CleanDatabaseInternal(List currentIdList, string typeName, IProgress progress, CancellationToken cancellationToken) { - var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList(); + var list = _itemRepo.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeName } + + }).Items.ToList(); var numComplete = 0; - foreach (var programId in list) + foreach (var itemId in list) { cancellationToken.ThrowIfCancellationRequested(); - if (!currentIdList.Contains(programId)) + if (!currentIdList.Contains(itemId)) { - var program = _libraryManager.GetItemById(programId); + var item = _libraryManager.GetItemById(itemId); - if (program != null) + if (item != null) { - await _libraryManager.DeleteItem(program).ConfigureAwait(false); + await _libraryManager.DeleteItem(item).ConfigureAwait(false); } } @@ -1358,11 +1266,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv var program = (LiveTvProgram)item; var service = GetService(program); - var channel = string.IsNullOrEmpty(program.ExternalChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, program.ExternalChannelId)); + var channel = GetInternalChannel(program.ChannelId); dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N"); - dto.ChannelId = _tvDtoService.GetInternalChannelId(service.Name, program.ExternalChannelId).ToString("N"); + dto.ChannelId = channel.Id.ToString("N"); dto.StartDate = program.StartDate; dto.IsRepeat = program.IsRepeat; @@ -1676,29 +1584,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var channel = GetInternalChannel(id); - var currentProgram = GetCurrentProgram(channel.ExternalId); - - var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user); + var now = DateTime.UtcNow; - return dto; - } + var programs = _libraryManager.GetItems(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + ChannelIds = new[] { id }, + MaxStartDate = now, + MinEndDate = now, + Limit = 1 - private LiveTvProgram GetCurrentProgram(string externalChannelId) - { - var now = DateTime.UtcNow; + }).Items.Cast(); - var program = GetPrograms() - .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase)) + var currentProgram = programs .OrderBy(i => i.StartDate) - .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue)) .FirstOrDefault(); - if (program != null) - { - RefreshIfNeeded(program); - } + var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user); - return program; + return dto; } private async Task> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null) @@ -1711,10 +1615,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (program != null) { + var channel = GetInternalChannel(program.ChannelId); + programInfo = new ProgramInfo { Audio = program.Audio, - ChannelId = program.ExternalChannelId, + ChannelId = channel.ExternalId, CommunityRating = program.CommunityRating, EndDate = program.EndDate ?? DateTime.MinValue, EpisodeTitle = program.EpisodeTitle, @@ -1990,15 +1896,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv public GuideInfo GetGuideInfo() { - var programs = GetPrograms().OrderBy(i => i.StartDate).ToList(); - - var startDate = programs.Count == 0 ? - DateTime.MinValue : - programs[0].StartDate; - - var endDate = programs.Count == 0 ? - DateTime.MinValue : - programs[programs.Count - 1].StartDate; + var startDate = DateTime.UtcNow; + var endDate = startDate.AddDays(14); return new GuideInfo { diff --git a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs index b01dddb94..134e24ef0 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -70,7 +70,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv { try { - var response = await service.GetProgramImageAsync(liveTvItem.ExternalId, liveTvItem.ExternalChannelId, cancellationToken).ConfigureAwait(false); + var channel = _liveTvManager.GetInternalChannel(liveTvItem.ChannelId); + + var response = await service.GetProgramImageAsync(liveTvItem.ExternalId, channel.ExternalId, cancellationToken).ConfigureAwait(false); if (response != null) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c5a9db87b..19aca1cf9 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1,12 +1,15 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; using System.Data; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -126,6 +129,12 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.RunQueries(queries, _logger); + _connection.AddColumn(_logger, "TypedBaseItems", "StartDate", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "EndDate", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "ChannelId", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsMovie", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsSports", "BIT"); + PrepareStatements(); _mediaStreamsRepository.Initialize(); @@ -143,10 +152,15 @@ namespace MediaBrowser.Server.Implementations.Persistence private void PrepareStatements() { _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (guid, type, data) values (@1, @2, @3)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (guid, type, data, StartDate, EndDate, ChannelId, IsMovie, IsSports) values (@1, @2, @3, @4, @5, @6, @7, @8)"; _saveItemCommand.Parameters.Add(_saveItemCommand, "@1"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@2"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@3"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@4"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@5"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@6"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@7"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@8"); _deleteChildrenCommand = _connection.CreateCommand(); _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; @@ -155,7 +169,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _deleteItemCommand = _connection.CreateCommand(); _deleteItemCommand.CommandText = "delete from TypedBaseItems where guid=@Id"; _deleteItemCommand.Parameters.Add(_deleteItemCommand, "@Id"); - + _saveChildrenCommand = _connection.CreateCommand(); _saveChildrenCommand.CommandText = "replace into ChildrenIds (ParentId, ItemId) values (@ParentId, @ItemId)"; _saveChildrenCommand.Parameters.Add(_saveChildrenCommand, "@ParentId"); @@ -200,7 +214,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); CheckDisposed(); - + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; @@ -217,6 +231,31 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(1).Value = item.GetType().FullName; _saveItemCommand.GetParameter(2).Value = _jsonSerializer.SerializeToBytes(item); + var hasStartDate = item as IHasStartDate; + if (hasStartDate != null) + { + _saveItemCommand.GetParameter(3).Value = hasStartDate.StartDate; + } + else + { + _saveItemCommand.GetParameter(3).Value = null; + } + + _saveItemCommand.GetParameter(4).Value = item.EndDate; + _saveItemCommand.GetParameter(5).Value = item.ChannelId; + + var hasProgramAttributes = item as IHasProgramAttributes; + if (hasProgramAttributes != null) + { + _saveItemCommand.GetParameter(6).Value = hasProgramAttributes.IsMovie; + _saveItemCommand.GetParameter(7).Value = hasProgramAttributes.IsSports; + } + else + { + _saveItemCommand.GetParameter(6).Value = null; + _saveItemCommand.GetParameter(7).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -254,7 +293,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _writeLock.Release(); } } - + /// /// Internal retrieve from items or users table /// @@ -270,7 +309,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select type,data from TypedBaseItems where guid = @guid"; @@ -467,7 +506,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select ItemId from ChildrenIds where ParentId = @ParentId"; @@ -492,7 +531,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select type,data from TypedBaseItems where guid in (select ItemId from ChildrenIds where ParentId = @ParentId)"; @@ -544,6 +583,279 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + public QueryResult GetItems(InternalItemsQuery query) + { + if (query == null) + { + throw new ArgumentNullException("query"); + } + + CheckDisposed(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select type,data from TypedBaseItems"; + + var whereClauses = GetWhereClauses(query, cmd, false); + + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + whereClauses = GetWhereClauses(query, cmd, true); + + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + cmd.CommandText += whereText; + + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); + } + + cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; + + var list = new List(); + var count = 0; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + { + while (reader.Read()) + { + list.Add(GetItem(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } + } + + return new QueryResult() + { + Items = list.ToArray(), + TotalRecordCount = count + }; + } + } + + public List GetItemIdsList(InternalItemsQuery query) + { + if (query == null) + { + throw new ArgumentNullException("query"); + } + + CheckDisposed(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select guid from TypedBaseItems"; + + var whereClauses = GetWhereClauses(query, cmd, false); + + whereClauses = GetWhereClauses(query, cmd, true); + + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + cmd.CommandText += whereText; + + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); + } + + var list = new List(); + + _logger.Debug(cmd.CommandText); + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + { + while (reader.Read()) + { + list.Add(reader.GetGuid(0)); + } + } + + return list; + } + } + + public QueryResult GetItemIds(InternalItemsQuery query) + { + if (query == null) + { + throw new ArgumentNullException("query"); + } + + CheckDisposed(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select guid from TypedBaseItems"; + + var whereClauses = GetWhereClauses(query, cmd, false); + + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + whereClauses = GetWhereClauses(query, cmd, true); + + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + cmd.CommandText += whereText; + + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); + } + + cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; + + var list = new List(); + var count = 0; + + _logger.Debug(cmd.CommandText); + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + { + while (reader.Read()) + { + list.Add(reader.GetGuid(0)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } + } + + return new QueryResult() + { + Items = list.ToArray(), + TotalRecordCount = count + }; + } + } + + private List GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, bool addPaging) + { + var whereClauses = new List(); + + if (query.IsMovie.HasValue) + { + whereClauses.Add("IsMovie=@IsMovie"); + cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie; + } + if (query.IsSports.HasValue) + { + whereClauses.Add("IsSports=@IsSports"); + cmd.Parameters.Add(cmd, "@IsSports", DbType.Boolean).Value = query.IsSports; + } + if (query.IncludeItemTypes.Length == 1) + { + whereClauses.Add("type=@type"); + cmd.Parameters.Add(cmd, "@type", DbType.String).Value = MapIncludeItemType(query.IncludeItemTypes[0]); + } + if (query.IncludeItemTypes.Length > 1) + { + var inClause = string.Join(",", query.IncludeItemTypes.Select(i => "'" + MapIncludeItemType(i) + "'").ToArray()); + whereClauses.Add(string.Format("type in ({0})", inClause)); + } + if (query.ChannelIds.Length == 1) + { + whereClauses.Add("ChannelId=@ChannelId"); + cmd.Parameters.Add(cmd, "@ChannelId", DbType.String).Value = query.ChannelIds[0]; + } + if (query.ChannelIds.Length > 1) + { + var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i + "'").ToArray()); + whereClauses.Add(string.Format("ChannelId in ({0})", inClause)); + } + + if (query.MinEndDate.HasValue) + { + whereClauses.Add("EndDate>=@MinEndDate"); + cmd.Parameters.Add(cmd, "@MinEndDate", DbType.Date).Value = query.MinEndDate.Value; + } + + if (query.MaxEndDate.HasValue) + { + whereClauses.Add("EndDate<=@MaxEndDate"); + cmd.Parameters.Add(cmd, "@MaxEndDate", DbType.Date).Value = query.MaxEndDate.Value; + } + + if (query.MinStartDate.HasValue) + { + whereClauses.Add("StartDate>=@MinStartDate"); + cmd.Parameters.Add(cmd, "@MinStartDate", DbType.Date).Value = query.MinStartDate.Value; + } + + if (query.MaxStartDate.HasValue) + { + whereClauses.Add("StartDate<=@MaxStartDate"); + cmd.Parameters.Add(cmd, "@MaxStartDate", DbType.Date).Value = query.MaxStartDate.Value; + } + + if (query.IsAiring.HasValue) + { + if (query.IsAiring.Value) + { + whereClauses.Add("StartDate<=@MaxStartDate"); + cmd.Parameters.Add(cmd, "@MaxStartDate", DbType.Date).Value = DateTime.UtcNow; + + whereClauses.Add("EndDate>=@MinEndDate"); + cmd.Parameters.Add(cmd, "@MinEndDate", DbType.Date).Value = DateTime.UtcNow; + } + else + { + whereClauses.Add("(StartDate>@IsAiringDate OR EndDate < @IsAiringDate)"); + cmd.Parameters.Add(cmd, "@IsAiringDate", DbType.Date).Value = DateTime.UtcNow; + } + } + + if (addPaging) + { + if (query.StartIndex.HasValue && query.StartIndex.Value > 0) + { + var pagingWhereText = whereClauses.Count == 0 ? + 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})", + pagingWhereText, + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture))); + } + } + + return whereClauses; + } + + // 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, typeof(LiveTvProgram).FullName}, + {typeof(LiveTvChannel).Name, typeof(LiveTvChannel).FullName} + }; + + private string MapIncludeItemType(string value) + { + string result; + if (_types.TryGetValue(value, out result)) + { + return result; + } + + return value; + } + public IEnumerable GetItemIdsOfType(Type type) { if (type == null) @@ -577,7 +889,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; @@ -595,7 +907,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _deleteItemCommand.GetParameter(0).Value = id; _deleteItemCommand.Transaction = transaction; _deleteItemCommand.ExecuteNonQuery(); - + transaction.Commit(); } catch (OperationCanceledException) @@ -642,7 +954,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; -- cgit v1.2.3 From 418bb8787869b13eca2da0095e94be6b22f2f10d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Jun 2015 13:07:55 -0400 Subject: update recording database --- MediaBrowser.Controller/Entities/IHasId.cs | 9 + MediaBrowser.Controller/Entities/IHasImages.cs | 9 +- .../Entities/IHasMediaSources.cs | 9 +- .../Entities/IHasProgramAttributes.cs | 12 +- MediaBrowser.Controller/Entities/IHasUserData.cs | 9 +- MediaBrowser.Controller/LiveTv/ILiveTvItem.cs | 5 +- MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 20 +- .../LiveTv/LiveTvAudioRecording.cs | 23 +++ .../LiveTv/LiveTvVideoRecording.cs | 23 +++ .../MediaBrowser.Controller.csproj | 1 + .../LiveTv/LiveTvDtoService.cs | 2 +- .../LiveTv/LiveTvManager.cs | 207 +++++++++++++-------- .../LiveTv/RecordingImageProvider.cs | 14 +- .../Persistence/SqliteItemRepository.cs | 28 +-- .../Session/SessionManager.cs | 10 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 19 files changed, 259 insertions(+), 134 deletions(-) create mode 100644 MediaBrowser.Controller/Entities/IHasId.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Entities/IHasId.cs b/MediaBrowser.Controller/Entities/IHasId.cs new file mode 100644 index 000000000..9698adf7a --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasId.cs @@ -0,0 +1,9 @@ +using System; + +namespace MediaBrowser.Controller.Entities +{ + public interface IHasId + { + Guid Id { get; } + } +} diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 1871d7b68..ffb351c94 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -1,13 +1,12 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities { - public interface IHasImages : IHasProviderIds + public interface IHasImages : IHasProviderIds, IHasId { /// /// Gets the name. @@ -27,12 +26,6 @@ namespace MediaBrowser.Controller.Entities /// The file name without extension. string FileNameWithoutExtension { get; } - /// - /// Gets the identifier. - /// - /// The identifier. - Guid Id { get; } - /// /// Gets the type of the location. /// diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs index 17a147806..85ce3c781 100644 --- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs +++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs @@ -1,17 +1,10 @@ using MediaBrowser.Model.Dto; -using System; using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { - public interface IHasMediaSources + public interface IHasMediaSources : IHasId { - /// - /// Gets the identifier. - /// - /// The identifier. - Guid Id { get; } - /// /// Gets the media sources. /// diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs index 1878d8d2c..391c8f7a7 100644 --- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -1,9 +1,19 @@ - +using MediaBrowser.Model.LiveTv; +using System; + namespace MediaBrowser.Controller.Entities { public interface IHasProgramAttributes { bool IsMovie { get; set; } bool IsSports { get; set; } + bool IsNews { get; set; } + bool IsKids { get; set; } + bool IsRepeat { get; set; } + bool? IsHD { get; set; } + bool IsLive { get; set; } + bool IsPremiere { get; set; } + ProgramAudio? Audio { get; set; } + DateTime? OriginalAirDate { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs index d576d90c4..34a820853 100644 --- a/MediaBrowser.Controller/Entities/IHasUserData.cs +++ b/MediaBrowser.Controller/Entities/IHasUserData.cs @@ -1,19 +1,12 @@ using MediaBrowser.Model.Dto; -using System; namespace MediaBrowser.Controller.Entities { /// /// Interface IHasUserData /// - public interface IHasUserData + public interface IHasUserData : IHasId { - /// - /// Gets or sets the identifier. - /// - /// The identifier. - Guid Id { get; set; } - /// /// Gets the user data key. /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs index 6c277a2e1..313675fb7 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs @@ -1,10 +1,9 @@ -using System; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.LiveTv { - public interface ILiveTvItem + public interface ILiveTvItem : IHasId { - Guid Id { get; } string ServiceName { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 93e1e576a..1dd267c93 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -2,19 +2,21 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Library; +using MediaBrowser.Model.LiveTv; +using System; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.LiveTv { - public interface ILiveTvRecording : IHasImages, IHasMediaSources, IHasUserData, ILiveTvItem + public interface ILiveTvRecording : IHasImages, IHasMediaSources, IHasUserData, ILiveTvItem, IHasStartDate, IHasProgramAttributes { + string ChannelId { get; } + string ProgramId { get; set; } string MediaType { get; } string Container { get; } - RecordingInfo RecordingInfo { get; set; } - long? RunTimeTicks { get; set; } string GetClientTypeName(); @@ -28,5 +30,17 @@ namespace MediaBrowser.Controller.LiveTv bool CanDelete(); bool CanDelete(User user); + + string ProviderImagePath { get; set; } + + string ProviderImageUrl { get; set; } + + string ExternalId { get; set; } + string EpisodeTitle { get; set; } + bool IsSeries { get; set; } + string SeriesTimerId { get; set; } + RecordingStatus Status { get; set; } + DateTime? EndDate { get; set; } + ChannelType ChannelType { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 0dc296d5a..20bde7483 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -3,7 +3,9 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Users; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -12,6 +14,27 @@ namespace MediaBrowser.Controller.LiveTv { public class LiveTvAudioRecording : Audio, ILiveTvRecording { + public string ExternalId { get; set; } + public string ProviderImagePath { get; set; } + public string ProviderImageUrl { get; set; } + public string EpisodeTitle { get; set; } + public bool IsSeries { get; set; } + public string SeriesTimerId { get; set; } + public DateTime StartDate { get; set; } + public RecordingStatus Status { get; set; } + public bool IsSports { get; set; } + public bool IsNews { get; set; } + public bool IsKids { get; set; } + public bool IsRepeat { get; set; } + public bool IsMovie { get; set; } + public bool? IsHD { get; set; } + public bool IsLive { get; set; } + public bool IsPremiere { get; set; } + public ChannelType ChannelType { get; set; } + public string ProgramId { get; set; } + public ProgramAudio? Audio { get; set; } + public DateTime? OriginalAirDate { get; set; } + /// /// Gets the user data key. /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 3669f9440..a9028989f 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -2,7 +2,9 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Users; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -11,6 +13,27 @@ namespace MediaBrowser.Controller.LiveTv { public class LiveTvVideoRecording : Video, ILiveTvRecording { + public string ExternalId { get; set; } + public string ProviderImagePath { get; set; } + public string ProviderImageUrl { get; set; } + public string EpisodeTitle { get; set; } + public bool IsSeries { get; set; } + public string SeriesTimerId { get; set; } + public DateTime StartDate { get; set; } + public RecordingStatus Status { get; set; } + public bool IsSports { get; set; } + public bool IsNews { get; set; } + public bool IsKids { get; set; } + public bool IsRepeat { get; set; } + public bool IsMovie { get; set; } + public bool? IsHD { get; set; } + public bool IsLive { get; set; } + public bool IsPremiere { get; set; } + public ChannelType ChannelType { get; set; } + public string ProgramId { get; set; } + public ProgramAudio? Audio { get; set; } + public DateTime? OriginalAirDate { get; set; } + /// /// Gets the user data key. /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index e1a18164e..216f1cf81 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -142,6 +142,7 @@ + diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index f24fe0019..72fea2c79 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -290,7 +290,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public Guid GetInternalRecordingId(string serviceName, string externalId) { - var name = serviceName + externalId + InternalVersionNumber; + var name = serviceName + externalId + InternalVersionNumber + "0"; return name.ToLower().GetMBId(typeof(ILiveTvRecording)); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 47e862b9f..e6dc268d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -53,6 +53,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly ConcurrentDictionary _openStreams = new ConcurrentDictionary(); + private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1); + public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) { _config = config; @@ -359,8 +361,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase); var service = GetService(recording); - _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.RecordingInfo.Id); - info = await service.GetRecordingStream(recording.RecordingInfo.Id, null, cancellationToken).ConfigureAwait(false); + _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId); + info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; if (info.RequiresClosing) @@ -618,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return item; } - private async Task GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken) + private async Task CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken) { var isNew = false; @@ -653,14 +655,36 @@ namespace MediaBrowser.Server.Implementations.LiveTv isNew = true; } + item.ChannelId = _tvDtoService.GetInternalChannelId(serviceName, info.ChannelId).ToString("N"); item.CommunityRating = info.CommunityRating; item.OfficialRating = info.OfficialRating; item.Overview = info.Overview; item.EndDate = info.EndDate; + item.Genres = info.Genres; var recording = (ILiveTvRecording)item; - recording.RecordingInfo = info; + recording.ProgramId = _tvDtoService.GetInternalProgramId(serviceName, info.ProgramId).ToString("N"); + recording.Audio = info.Audio; + recording.ChannelType = info.ChannelType; + recording.EndDate = info.EndDate; + recording.EpisodeTitle = info.EpisodeTitle; + recording.ProviderImagePath = info.ImagePath; + recording.ProviderImageUrl = info.ImageUrl; + recording.IsHD = info.IsHD; + recording.IsKids = info.IsKids; + recording.IsLive = info.IsLive; + recording.IsMovie = info.IsMovie; + recording.IsNews = info.IsNews; + recording.IsPremiere = info.IsPremiere; + recording.IsRepeat = info.IsRepeat; + recording.IsSeries = info.IsSeries; + recording.IsSports = info.IsSports; + recording.OriginalAirDate = info.OriginalAirDate; + recording.SeriesTimerId = info.SeriesTimerId; + recording.StartDate = info.StartDate; + recording.Status = info.Status; + recording.ServiceName = serviceName; var originalPath = item.Path; @@ -676,15 +700,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv var pathChanged = !string.Equals(originalPath, item.Path); - await item.RefreshMetadata(new MetadataRefreshOptions + if (isNew) { - ForceSave = isNew || pathChanged - - }, cancellationToken); + await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + } + else if (pathChanged) + { + await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } - _libraryManager.RegisterItem(item); + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); - return recording; + return item.Id; } public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null) @@ -1006,8 +1033,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(100 * percent); } - await CleanDatabaseInternal(newChannelIdList, typeof(LiveTvChannel).Name, progress, cancellationToken).ConfigureAwait(false); - await CleanDatabaseInternal(newProgramIdList, typeof(LiveTvProgram).Name, progress, cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); // Load these now which will prefetch metadata var dtoOptions = new DtoOptions(); @@ -1017,7 +1044,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(100); } - private async Task,List>> RefreshChannelsInternal(ILiveTvService service, IProgress progress, CancellationToken cancellationToken) + private async Task, List>> RefreshChannelsInternal(ILiveTvService service, IProgress progress, CancellationToken cancellationToken) { progress.Report(10); @@ -1103,14 +1130,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv } progress.Report(100); - return new Tuple,List>(channels, programs); + return new Tuple, List>(channels, programs); } - private async Task CleanDatabaseInternal(List currentIdList, string typeName, IProgress progress, CancellationToken cancellationToken) + private async Task CleanDatabaseInternal(List currentIdList, string[] validTypes, IProgress progress, CancellationToken cancellationToken) { var list = _itemRepo.GetItemIds(new InternalItemsQuery { - IncludeItemTypes = new[] { typeName } + IncludeItemTypes = validTypes }).Items.ToList(); @@ -1163,64 +1190,103 @@ namespace MediaBrowser.Server.Implementations.LiveTv return channels.Select(i => new Tuple(service.Name, i)); } - public async Task> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken) + private DateTime _lastRecordingRefreshTime; + private async Task RefreshRecordings(CancellationToken cancellationToken) { - var tasks = _services.Select(async i => + const int cacheMinutes = 5; + + if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes) { - try + return; + } + + await _refreshRecordingsLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes) { - var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); - return recs.Select(r => new Tuple(r, i)); + return; } - catch (Exception ex) + + var tasks = _services.Select(async i => { - _logger.ErrorException("Error getting recordings", ex); - return new List>(); - } - }); - var results = await Task.WhenAll(tasks).ConfigureAwait(false); - var recordings = results.SelectMany(i => i.ToList()); + try + { + var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); + return recs.Select(r => new Tuple(r, i)); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting recordings", ex); + return new List>(); + } + }); - var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + var results = await Task.WhenAll(tasks).ConfigureAwait(false); + + var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken)); + + var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false); + + CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new Progress(), cancellationToken).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.UtcNow; + } + finally + { + _refreshRecordingsLock.Release(); + } + } + + public async Task> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken) + { + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); if (user != null && !IsLiveTvEnabled(user)) { - recordings = new List>(); + return new QueryResult(); } - if (!string.IsNullOrEmpty(query.ChannelId)) + await RefreshRecordings(cancellationToken).ConfigureAwait(false); + + var internalQuery = new InternalItemsQuery { - var guid = new Guid(query.ChannelId); + IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name } + }; - recordings = recordings - .Where(i => _tvDtoService.GetInternalChannelId(i.Item2.Name, i.Item1.ChannelId) == guid); + if (!string.IsNullOrEmpty(query.ChannelId)) + { + internalQuery.ChannelIds = new[] { query.ChannelId }; } + var queryResult = _libraryManager.GetItems(internalQuery); + IEnumerable recordings = queryResult.Items.Cast(); + if (!string.IsNullOrEmpty(query.Id)) { var guid = new Guid(query.Id); recordings = recordings - .Where(i => _tvDtoService.GetInternalRecordingId(i.Item2.Name, i.Item1.Id) == guid); + .Where(i => i.Id == guid); } if (!string.IsNullOrEmpty(query.GroupId)) { var guid = new Guid(query.GroupId); - recordings = recordings.Where(i => GetRecordingGroupIds(i.Item1).Contains(guid)); + recordings = recordings.Where(i => GetRecordingGroupIds(i).Contains(guid)); } if (query.IsInProgress.HasValue) { var val = query.IsInProgress.Value; - recordings = recordings.Where(i => (i.Item1.Status == RecordingStatus.InProgress) == val); + recordings = recordings.Where(i => (i.Status == RecordingStatus.InProgress) == val); } if (query.Status.HasValue) { var val = query.Status.Value; - recordings = recordings.Where(i => (i.Item1.Status == val)); + recordings = recordings.Where(i => (i.Status == val)); } if (!string.IsNullOrEmpty(query.SeriesTimerId)) @@ -1228,21 +1294,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv var guid = new Guid(query.SeriesTimerId); recordings = recordings - .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.Item2.Name, i.Item1.SeriesTimerId) == guid); + .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid); } - recordings = recordings.OrderByDescending(i => i.Item1.StartDate); - - IEnumerable entities = await GetEntities(recordings, cancellationToken).ConfigureAwait(false); - if (user != null) { var currentUser = user; - entities = entities.Where(i => i.IsParentalAllowed(currentUser)); + recordings = recordings.Where(i => i.IsParentalAllowed(currentUser)); } - var entityList = entities.ToList(); - entities = entityList; + recordings = recordings.OrderByDescending(i => i.StartDate); + + var entityList = recordings.ToList(); + IEnumerable entities = entityList; if (query.StartIndex.HasValue) { @@ -1270,7 +1334,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N"); - dto.ChannelId = channel.Id.ToString("N"); + dto.ChannelId = item.ChannelId; dto.StartDate = program.StartDate; dto.IsRepeat = program.IsRepeat; @@ -1303,16 +1367,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv var recording = (ILiveTvRecording)item; var service = GetService(recording); - var channel = string.IsNullOrEmpty(recording.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, recording.RecordingInfo.ChannelId)); + var channel = string.IsNullOrWhiteSpace(recording.ChannelId) ? null : GetInternalChannel(recording.ChannelId); - var info = recording.RecordingInfo; + var info = recording; - dto.Id = _tvDtoService.GetInternalRecordingId(service.Name, info.Id).ToString("N"); + dto.Id = item.Id.ToString("N"); dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); - dto.ChannelId = _tvDtoService.GetInternalChannelId(service.Name, info.ChannelId).ToString("N"); + dto.ChannelId = item.ChannelId; dto.StartDate = info.StartDate; dto.RecordingStatus = info.Status; @@ -1344,11 +1408,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); } - if (info.Status == RecordingStatus.InProgress) + if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue) { var now = DateTime.UtcNow.Ticks; var start = info.StartDate.Ticks; - var end = info.EndDate.Ticks; + var end = info.EndDate.Value.Ticks; var pct = now - start; pct /= end; @@ -1356,10 +1420,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.CompletionPercentage = pct; } - if (!string.IsNullOrEmpty(info.ProgramId)) - { - dto.ProgramId = _tvDtoService.GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); - } + dto.ProgramId = info.ProgramId; if (channel != null) { @@ -1394,13 +1455,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } - private Task GetEntities(IEnumerable> recordings, CancellationToken cancellationToken) - { - var tasks = recordings.Select(i => GetRecording(i.Item1, i.Item2.Name, cancellationToken)); - - return Task.WhenAll(tasks); - } - public async Task> GetTimers(TimerQuery query, CancellationToken cancellationToken) { var tasks = _services.Select(async i => @@ -1468,7 +1522,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(recording.ServiceName); - await service.DeleteRecordingAsync(recording.RecordingInfo.Id, CancellationToken.None).ConfigureAwait(false); + await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task CancelTimer(string id) @@ -1483,6 +1538,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(timer.ServiceName); await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task CancelSeriesTimer(string id) @@ -1497,6 +1553,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(timer.ServiceName); await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null) @@ -1705,6 +1762,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Priority = defaultValues.Priority; await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) @@ -1718,6 +1776,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Priority = defaultValues.Priority; await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken) @@ -1727,6 +1786,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(timer.ServiceName); await service.UpdateTimerAsync(info, cancellationToken).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } public async Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) @@ -1736,9 +1796,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(timer.ServiceName); await service.UpdateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false); + _lastRecordingRefreshTime = DateTime.MinValue; } - private IEnumerable GetRecordingGroupNames(RecordingInfo recording) + private IEnumerable GetRecordingGroupNames(ILiveTvRecording recording) { var list = new List(); @@ -1775,7 +1836,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return list; } - private List GetRecordingGroupIds(RecordingInfo recording) + private List GetRecordingGroupIds(ILiveTvRecording recording) { return GetRecordingGroupNames(recording).Select(i => i.ToLower() .GetMD5()) @@ -1795,7 +1856,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var groups = new List(); var series = recordings - .Where(i => i.RecordingInfo.IsSeries) + .Where(i => i.IsSeries) .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase) .ToList(); @@ -1808,31 +1869,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv groups.Add(new BaseItemDto { Name = "Kids", - RecordingCount = recordings.Count(i => i.RecordingInfo.IsKids) + RecordingCount = recordings.Count(i => i.IsKids) }); groups.Add(new BaseItemDto { Name = "Movies", - RecordingCount = recordings.Count(i => i.RecordingInfo.IsMovie) + RecordingCount = recordings.Count(i => i.IsMovie) }); groups.Add(new BaseItemDto { Name = "News", - RecordingCount = recordings.Count(i => i.RecordingInfo.IsNews) + RecordingCount = recordings.Count(i => i.IsNews) }); groups.Add(new BaseItemDto { Name = "Sports", - RecordingCount = recordings.Count(i => i.RecordingInfo.IsSports) + RecordingCount = recordings.Count(i => i.IsSports) }); groups.Add(new BaseItemDto { Name = "Others", - RecordingCount = recordings.Count(i => !i.RecordingInfo.IsSports && !i.RecordingInfo.IsNews && !i.RecordingInfo.IsMovie && !i.RecordingInfo.IsKids && !i.RecordingInfo.IsSeries) + RecordingCount = recordings.Count(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries) }); groups = groups diff --git a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs index 710247da7..adf1e7516 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs @@ -36,17 +36,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv var imageResponse = new DynamicImageResponse(); - if (!string.IsNullOrEmpty(liveTvItem.RecordingInfo.ImagePath)) + if (!string.IsNullOrEmpty(liveTvItem.ProviderImagePath)) { - imageResponse.Path = liveTvItem.RecordingInfo.ImagePath; + imageResponse.Path = liveTvItem.ProviderImagePath; imageResponse.HasImage = true; } - else if (!string.IsNullOrEmpty(liveTvItem.RecordingInfo.ImageUrl)) + else if (!string.IsNullOrEmpty(liveTvItem.ProviderImageUrl)) { var options = new HttpRequestOptions { CancellationToken = cancellationToken, - Url = liveTvItem.RecordingInfo.ImageUrl + Url = liveTvItem.ProviderImageUrl }; var response = await _httpClient.GetResponse(options).ConfigureAwait(false); @@ -62,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv _logger.Error("Provider did not return an image content type."); } } - else if (liveTvItem.RecordingInfo.HasImage ?? true) + else { var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, liveTvItem.ServiceName, StringComparison.OrdinalIgnoreCase)); @@ -70,7 +70,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { try { - var response = await service.GetRecordingImageAsync(liveTvItem.RecordingInfo.Id, cancellationToken).ConfigureAwait(false); + var response = await service.GetRecordingImageAsync(liveTvItem.ExternalId, cancellationToken).ConfigureAwait(false); if (response != null) { @@ -109,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (liveTvItem != null) { - return !liveTvItem.HasImage(ImageType.Primary) && (liveTvItem.RecordingInfo.HasImage ?? true); + return !liveTvItem.HasImage(ImageType.Primary) && (!string.IsNullOrWhiteSpace(liveTvItem.ProviderImagePath) || !string.IsNullOrWhiteSpace(liveTvItem.ProviderImageUrl)); } return false; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 19aca1cf9..8b93c36a5 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -759,14 +759,17 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("IsSports=@IsSports"); cmd.Parameters.Add(cmd, "@IsSports", DbType.Boolean).Value = query.IsSports; } - if (query.IncludeItemTypes.Length == 1) + + var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); + + if (includeTypes.Length == 1) { whereClauses.Add("type=@type"); - cmd.Parameters.Add(cmd, "@type", DbType.String).Value = MapIncludeItemType(query.IncludeItemTypes[0]); + cmd.Parameters.Add(cmd, "@type", DbType.String).Value = includeTypes[0]; } - if (query.IncludeItemTypes.Length > 1) + if (includeTypes.Length > 1) { - var inClause = string.Join(",", query.IncludeItemTypes.Select(i => "'" + MapIncludeItemType(i) + "'").ToArray()); + var inClause = string.Join(",", includeTypes.Select(i => "'" + i + "'").ToArray()); whereClauses.Add(string.Format("type in ({0})", inClause)); } if (query.ChannelIds.Length == 1) @@ -818,7 +821,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { whereClauses.Add("(StartDate>@IsAiringDate OR EndDate < @IsAiringDate)"); cmd.Parameters.Add(cmd, "@IsAiringDate", DbType.Date).Value = DateTime.UtcNow; - } + } } if (addPaging) @@ -839,21 +842,24 @@ namespace MediaBrowser.Server.Implementations.Persistence } // 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) + readonly Dictionary _types = new Dictionary(StringComparer.OrdinalIgnoreCase) { - {typeof(LiveTvProgram).Name, typeof(LiveTvProgram).FullName}, - {typeof(LiveTvChannel).Name, typeof(LiveTvChannel).FullName} + {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}}, + {"Recording", new []{typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName}} }; - private string MapIncludeItemType(string value) + private IEnumerable MapIncludeItemTypes(string value) { - string result; + string[] result; if (_types.TryGetValue(value, out result)) { return result; } - return value; + return new[] { value }; } public IEnumerable GetItemIdsOfType(Type type) diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 1baaa952a..f657d5403 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1528,16 +1528,16 @@ namespace MediaBrowser.Server.Implementations.Session } var recording = item as ILiveTvRecording; - if (recording != null && recording.RecordingInfo != null) + if (recording != null) { - if (recording.RecordingInfo.IsSeries) + if (recording.IsSeries) { - info.Name = recording.RecordingInfo.EpisodeTitle; - info.SeriesName = recording.RecordingInfo.Name; + info.Name = recording.EpisodeTitle; + info.SeriesName = recording.Name; if (string.IsNullOrWhiteSpace(info.Name)) { - info.Name = recording.RecordingInfo.Name; + info.Name = recording.Name; } } } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index f2d46de3e..57c619976 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.622 + 3.0.624 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index ab7d095f3..dcd913774 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.622 + 3.0.624 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 67385bc3d..10cee8dc2 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.622 + 3.0.624 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index e91b97464..d171dab17 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.622 + 3.0.624 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 08dbe39f9979ec94eeff1256acc21d798b1e6ad8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 1 Jun 2015 13:49:11 -0400 Subject: add IsKids column --- MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 3 ++- .../Persistence/SqliteItemRepository.cs | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 245c11169..faa9bc875 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -81,7 +81,8 @@ namespace MediaBrowser.Controller.Entities public bool? IsMovie { get; set; } public bool? IsSports { get; set; } - + public bool? IsKids { get; set; } + public string[] ChannelIds { get; set; } public InternalItemsQuery() diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 8b93c36a5..09786e08c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -134,6 +134,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "ChannelId", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "IsMovie", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "IsSports", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsKids", "BIT"); PrepareStatements(); @@ -152,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private void PrepareStatements() { _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (guid, type, data, StartDate, EndDate, ChannelId, IsMovie, IsSports) values (@1, @2, @3, @4, @5, @6, @7, @8)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (guid, type, data, StartDate, EndDate, ChannelId, IsKids, IsMovie, IsSports) values (@1, @2, @3, @4, @5, @6, @7, @8, @9)"; _saveItemCommand.Parameters.Add(_saveItemCommand, "@1"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@2"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@3"); @@ -161,6 +162,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.Parameters.Add(_saveItemCommand, "@6"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@7"); _saveItemCommand.Parameters.Add(_saveItemCommand, "@8"); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@9"); _deleteChildrenCommand = _connection.CreateCommand(); _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; @@ -247,13 +249,15 @@ namespace MediaBrowser.Server.Implementations.Persistence var hasProgramAttributes = item as IHasProgramAttributes; if (hasProgramAttributes != null) { - _saveItemCommand.GetParameter(6).Value = hasProgramAttributes.IsMovie; - _saveItemCommand.GetParameter(7).Value = hasProgramAttributes.IsSports; + _saveItemCommand.GetParameter(6).Value = hasProgramAttributes.IsKids; + _saveItemCommand.GetParameter(7).Value = hasProgramAttributes.IsMovie; + _saveItemCommand.GetParameter(8).Value = hasProgramAttributes.IsSports; } else { _saveItemCommand.GetParameter(6).Value = null; _saveItemCommand.GetParameter(7).Value = null; + _saveItemCommand.GetParameter(8).Value = null; } _saveItemCommand.Transaction = transaction; @@ -754,6 +758,11 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("IsMovie=@IsMovie"); cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie; } + if (query.IsKids.HasValue) + { + whereClauses.Add("IsKids=@IsKids"); + cmd.Parameters.Add(cmd, "@IsKids", DbType.Boolean).Value = query.IsKids; + } if (query.IsSports.HasValue) { whereClauses.Add("IsSports=@IsSports"); -- cgit v1.2.3 From cf0fd249406f0a1434a47140bb929cfd346578ef Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Jun 2015 13:46:44 -0400 Subject: update voice script --- .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Controller/Sync/ISyncManager.cs | 2 +- MediaBrowser.Controller/Sync/ISyncRepository.cs | 2 +- MediaBrowser.Controller/Sync/SyncedItemProgress.cs | 10 ++ MediaBrowser.Model/Dto/BaseItemDto.cs | 5 + .../Dto/DtoService.cs | 103 +++++++++++++-------- .../Sync/SyncManager.cs | 4 +- .../Sync/SyncRepository.cs | 17 +++- .../MediaBrowser.WebDashboard.csproj | 4 +- 9 files changed, 98 insertions(+), 50 deletions(-) create mode 100644 MediaBrowser.Controller/Sync/SyncedItemProgress.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 216f1cf81..bf86c049f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -411,6 +411,7 @@ + diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 97591551c..fd373050f 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetLibraryItemIds(SyncJobItemQuery query); + QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); /// /// Reports the synchronize job item transfer beginning. diff --git a/MediaBrowser.Controller/Sync/ISyncRepository.cs b/MediaBrowser.Controller/Sync/ISyncRepository.cs index 315f5f541..2af09dbaa 100644 --- a/MediaBrowser.Controller/Sync/ISyncRepository.cs +++ b/MediaBrowser.Controller/Sync/ISyncRepository.cs @@ -74,6 +74,6 @@ namespace MediaBrowser.Controller.Sync /// /// The query. /// QueryResult<System.String>. - QueryResult GetLibraryItemIds(SyncJobItemQuery query); + QueryResult GetSyncedItemProgresses(SyncJobItemQuery query); } } diff --git a/MediaBrowser.Controller/Sync/SyncedItemProgress.cs b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs new file mode 100644 index 000000000..edb42eb0f --- /dev/null +++ b/MediaBrowser.Controller/Sync/SyncedItemProgress.cs @@ -0,0 +1,10 @@ +using MediaBrowser.Model.Sync; + +namespace MediaBrowser.Controller.Sync +{ + public class SyncedItemProgress + { + public string ItemId { get; set; } + public SyncJobItemStatus Status { get; set; } + } +} diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index fb157e9ae..7c5d9e9a1 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -100,6 +100,11 @@ namespace MediaBrowser.Model.Dto /// /// The synchronize status. public SyncJobItemStatus? SyncStatus { get; set; } + /// + /// Gets or sets the synchronize percent. + /// + /// The synchronize percent. + public double? SyncPercent { get; set; } /// /// Gets or sets the DVD season number. diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 5853b5b75..f9dfb1350 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -87,13 +87,14 @@ namespace MediaBrowser.Server.Implementations.Dto public IEnumerable GetBaseItemDtos(IEnumerable items, DtoOptions options, User user = null, BaseItem owner = null) { - var tuple = GetItemIdsWithSyncJobs(options); + var syncJobItems = GetSyncedItemProgress(options); + var syncDictionary = syncJobItems.ToDictionary(i => i.ItemId); var list = new List(); foreach (var item in items) { - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var dto = GetBaseItemDtoInternal(item, options, syncDictionary, user, owner); var byName = item as IItemByName; @@ -111,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - FillSyncInfo(dto, item, tuple.Item1, tuple.Item2, options, user); + FillSyncInfo(dto, item, syncJobItems, options, user); list.Add(dto); } @@ -121,7 +122,9 @@ namespace MediaBrowser.Server.Implementations.Dto public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var syncProgress = GetSyncedItemProgress(options); + + var dto = GetBaseItemDtoInternal(item, options, syncProgress.ToDictionary(i => i.ItemId), user, owner); var byName = item as IItemByName; @@ -138,35 +141,35 @@ namespace MediaBrowser.Server.Implementations.Dto SetItemByNameInfo(item, dto, libraryItems.ToList(), user); } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } - private Tuple, IEnumerable> GetItemIdsWithSyncJobs(DtoOptions options) + private SyncedItemProgress[] GetSyncedItemProgress(DtoOptions options) { if (!options.Fields.Contains(ItemFields.SyncInfo)) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[]{}; } var deviceId = options.DeviceId; if (string.IsNullOrWhiteSpace(deviceId)) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[] { }; } var caps = _deviceManager().GetCapabilities(deviceId); if (caps == null || !caps.SupportsSync) { - return new Tuple, IEnumerable>(new List(), new List()); + return new SyncedItemProgress[] { }; } - var result1 = _syncManager.GetLibraryItemIds(new SyncJobItemQuery + return _syncManager.GetSyncedItemProgresses(new SyncJobItemQuery { TargetId = deviceId, Statuses = new[] @@ -174,38 +177,28 @@ namespace MediaBrowser.Server.Implementations.Dto SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.Transferring, - SyncJobItemStatus.ReadyToTransfer - } - }); - - var result2 = _syncManager.GetLibraryItemIds(new SyncJobItemQuery - { - TargetId = deviceId, - Statuses = new[] - { + SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced } - }); - - return new Tuple, IEnumerable>(result1.Items, result2.Items); + }).Items; } public void FillSyncInfo(IEnumerable dtos, DtoOptions options, User user) { if (options.Fields.Contains(ItemFields.SyncInfo)) { - var tuple = GetItemIdsWithSyncJobs(options); + var syncProgress = GetSyncedItemProgress(options); foreach (var dto in dtos) { var item = _libraryManager.GetItemById(dto.Id); - FillSyncInfo(dto, item, tuple.Item1, tuple.Item2, options, user); + FillSyncInfo(dto, item, syncProgress, options, user); } } } - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user) + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, SyncedItemProgress[] syncProgress) { if (options.Fields.Contains(ItemFields.SyncInfo)) { @@ -215,10 +208,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (dto.SupportsSync ?? false) { - var tuple = GetItemIdsWithSyncJobs(options); - - dto.HasSyncJob = tuple.Item1.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); - dto.IsSynced = tuple.Item2.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); + dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); + dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); if (dto.IsSynced.Value) { @@ -232,7 +223,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, IEnumerable itemIdsWithPendingSyncJobs, IEnumerable syncedItemIds, DtoOptions options, User user) + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, SyncedItemProgress[] syncProgress, DtoOptions options, User user) { if (options.Fields.Contains(ItemFields.SyncInfo)) { @@ -242,8 +233,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (dto.SupportsSync ?? false) { - dto.HasSyncJob = itemIdsWithPendingSyncJobs.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); - dto.IsSynced = syncedItemIds.Contains(dto.Id, StringComparer.OrdinalIgnoreCase); + dto.HasSyncJob = syncProgress.Any(i => i.Status != SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); + dto.IsSynced = syncProgress.Any(i => i.Status == SyncJobItemStatus.Synced && string.Equals(i.ItemId, dto.Id, StringComparison.OrdinalIgnoreCase)); if (dto.IsSynced.Value) { @@ -257,7 +248,7 @@ namespace MediaBrowser.Server.Implementations.Dto } } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary syncProgress, User user = null, BaseItem owner = null) { var fields = options.Fields; @@ -301,7 +292,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (user != null) { - AttachUserSpecificInfo(dto, item, user, fields); + AttachUserSpecificInfo(dto, item, user, fields, syncProgress); } var hasMediaSources = item as IHasMediaSources; @@ -368,14 +359,16 @@ namespace MediaBrowser.Server.Implementations.Dto public BaseItemDto GetItemByNameDto(T item, DtoOptions options, List taggedItems, User user = null) where T : BaseItem, IItemByName { - var dto = GetBaseItemDtoInternal(item, options, user); + var syncProgress = GetSyncedItemProgress(options); + + var dto = GetBaseItemDtoInternal(item, options, syncProgress.ToDictionary(i => i.ItemId), user); if (options.Fields.Contains(ItemFields.ItemCounts)) { SetItemByNameInfo(item, dto, taggedItems, user); } - FillSyncInfo(dto, item, options, user); + FillSyncInfo(dto, item, options, user, syncProgress); return dto; } @@ -415,7 +408,8 @@ namespace MediaBrowser.Server.Implementations.Dto /// The item. /// The user. /// The fields. - private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields) + /// The synchronize progress. + private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List fields, Dictionary syncProgress) { if (item.IsFolder) { @@ -433,7 +427,7 @@ namespace MediaBrowser.Server.Implementations.Dto // TODO: Disable for CollectionFolder if (!(folder is UserRootFolder) && !(folder is UserView)) { - SetSpecialCounts(folder, user, dto, fields); + SetSpecialCounts(folder, user, dto, fields, syncProgress); } dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100; @@ -1599,8 +1593,9 @@ namespace MediaBrowser.Server.Implementations.Dto /// The user. /// The dto. /// The fields. + /// The synchronize progress. /// Task. - private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields) + private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List fields, Dictionary syncProgress) { var recursiveItemCount = 0; var unplayed = 0; @@ -1608,6 +1603,8 @@ namespace MediaBrowser.Server.Implementations.Dto DateTime? dateLastMediaAdded = null; double totalPercentPlayed = 0; + double totalSyncPercent = 0; + var addSyncInfo = fields.Contains(ItemFields.SyncInfo); IEnumerable children; @@ -1666,6 +1663,27 @@ namespace MediaBrowser.Server.Implementations.Dto } runtime += child.RunTimeTicks ?? 0; + + if (addSyncInfo) + { + double percent = 0; + SyncedItemProgress syncItemProgress; + if (syncProgress.TryGetValue(dto.Id, out syncItemProgress)) + { + switch (syncItemProgress.Status) + { + case SyncJobItemStatus.Synced: + percent = 100; + break; + case SyncJobItemStatus.Converting: + case SyncJobItemStatus.ReadyToTransfer: + case SyncJobItemStatus.Transferring: + percent = 50; + break; + } + } + totalSyncPercent += percent; + } } dto.RecursiveItemCount = recursiveItemCount; @@ -1674,6 +1692,11 @@ namespace MediaBrowser.Server.Implementations.Dto if (recursiveItemCount > 0) { dto.UserData.PlayedPercentage = totalPercentPlayed / recursiveItemCount; + + if (addSyncInfo) + { + dto.SyncPercent = totalSyncPercent / recursiveItemCount; + } } if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks)) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index d47135c65..8461176b4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1131,9 +1131,9 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } - public QueryResult GetLibraryItemIds(SyncJobItemQuery query) + public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) { - return _repo.GetLibraryItemIds(query); + return _repo.GetSyncedItemProgresses(query); } public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 5ad351af5..75c929016 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -627,9 +627,9 @@ namespace MediaBrowser.Server.Implementations.Sync } } - public QueryResult GetLibraryItemIds(SyncJobItemQuery query) + public QueryResult GetSyncedItemProgresses(SyncJobItemQuery query) { - return GetJobItemReader(query, "select ItemId from SyncJobItems", GetItemId); + return GetJobItemReader(query, "select ItemId,Status from SyncJobItems", GetSyncedItemProgress); } public QueryResult GetJobItems(SyncJobItemQuery query) @@ -788,9 +788,18 @@ namespace MediaBrowser.Server.Implementations.Sync return info; } - private string GetItemId(IDataReader reader) + private SyncedItemProgress GetSyncedItemProgress(IDataReader reader) { - return reader.GetString(0); + var item = new SyncedItemProgress(); + + item.ItemId = reader.GetString(0); + + if (!reader.IsDBNull(1)) + { + item.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(1), true); + } + + return item; } /// diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 84b0d2d85..a4a5b672e 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -117,7 +117,7 @@ PreserveNewest - + PreserveNewest @@ -201,7 +201,7 @@ PreserveNewest - + PreserveNewest -- cgit v1.2.3 From 92ce7c0fa84055dd90d33fe2fa5c1b78274047a8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Jun 2015 23:16:15 -0400 Subject: fix tv recording retrieval --- .../LiveTv/LiveTvAudioRecording.cs | 8 ++- .../LiveTv/LiveTvVideoRecording.cs | 8 ++- .../Persistence/SqliteItemRepository.cs | 62 ++++++++++++++-------- 3 files changed, 45 insertions(+), 33 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 20bde7483..3da12cd80 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -43,16 +43,14 @@ namespace MediaBrowser.Controller.LiveTv { var name = GetClientTypeName(); - if (!string.IsNullOrEmpty(RecordingInfo.ProgramId)) + if (!string.IsNullOrEmpty(ProgramId)) { - return name + "-" + RecordingInfo.ProgramId; + return name + "-" + ProgramId; } - return name + "-" + RecordingInfo.Name + (RecordingInfo.EpisodeTitle ?? string.Empty); + return name + "-" + Name + (EpisodeTitle ?? string.Empty); } - public RecordingInfo RecordingInfo { get; set; } - public string ServiceName { get; set; } /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index a9028989f..179c33d09 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -42,16 +42,14 @@ namespace MediaBrowser.Controller.LiveTv { var name = GetClientTypeName(); - if (!string.IsNullOrEmpty(RecordingInfo.ProgramId)) + if (!string.IsNullOrEmpty(ProgramId)) { - return name + "-" + RecordingInfo.ProgramId; + return name + "-" + ProgramId; } - return name + "-" + RecordingInfo.Name + (RecordingInfo.EpisodeTitle ?? string.Empty); + return name + "-" + Name + (EpisodeTitle ?? string.Empty); } - public RecordingInfo RecordingInfo { get; set; } - public string ServiceName { get; set; } [IgnoreDataMember] diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 09786e08c..9a013e2e7 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -135,6 +135,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "IsMovie", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "IsSports", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "IsKids", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "CommunityRating", "Float"); + _connection.AddColumn(_logger, "TypedBaseItems", "CustomRating", "Text"); PrepareStatements(); @@ -152,17 +154,26 @@ namespace MediaBrowser.Server.Implementations.Persistence /// private void PrepareStatements() { + var saveColumns = new List + { + "guid", + "type", + "data", + "StartDate", + "EndDate", + "ChannelId", + "IsKids", + "IsMovie", + "IsSports", + "CommunityRating", + "CustomRating" + }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (guid, type, data, StartDate, EndDate, ChannelId, IsKids, IsMovie, IsSports) values (@1, @2, @3, @4, @5, @6, @7, @8, @9)"; - _saveItemCommand.Parameters.Add(_saveItemCommand, "@1"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@2"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@3"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@4"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@5"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@6"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@7"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@8"); - _saveItemCommand.Parameters.Add(_saveItemCommand, "@9"); + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11)"; + for (var i = 1; i <= saveColumns.Count; i++) + { + _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); + } _deleteChildrenCommand = _connection.CreateCommand(); _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; @@ -229,37 +240,42 @@ namespace MediaBrowser.Server.Implementations.Persistence { cancellationToken.ThrowIfCancellationRequested(); - _saveItemCommand.GetParameter(0).Value = item.Id; - _saveItemCommand.GetParameter(1).Value = item.GetType().FullName; - _saveItemCommand.GetParameter(2).Value = _jsonSerializer.SerializeToBytes(item); + var index = 0; + + _saveItemCommand.GetParameter(index++).Value = item.Id; + _saveItemCommand.GetParameter(index++).Value = item.GetType().FullName; + _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item); var hasStartDate = item as IHasStartDate; if (hasStartDate != null) { - _saveItemCommand.GetParameter(3).Value = hasStartDate.StartDate; + _saveItemCommand.GetParameter(index++).Value = hasStartDate.StartDate; } else { - _saveItemCommand.GetParameter(3).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; } - _saveItemCommand.GetParameter(4).Value = item.EndDate; - _saveItemCommand.GetParameter(5).Value = item.ChannelId; + _saveItemCommand.GetParameter(index++).Value = item.EndDate; + _saveItemCommand.GetParameter(index++).Value = item.ChannelId; var hasProgramAttributes = item as IHasProgramAttributes; if (hasProgramAttributes != null) { - _saveItemCommand.GetParameter(6).Value = hasProgramAttributes.IsKids; - _saveItemCommand.GetParameter(7).Value = hasProgramAttributes.IsMovie; - _saveItemCommand.GetParameter(8).Value = hasProgramAttributes.IsSports; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsKids; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsMovie; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSports; } else { - _saveItemCommand.GetParameter(6).Value = null; - _saveItemCommand.GetParameter(7).Value = null; - _saveItemCommand.GetParameter(8).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; } + _saveItemCommand.GetParameter(index++).Value = item.CommunityRating; + _saveItemCommand.GetParameter(index++).Value = item.CustomRating; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); -- cgit v1.2.3 From 7990f9ca50c21be298d8fa90ce70015a80b976c3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 4 Jun 2015 16:27:46 -0400 Subject: update connect --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 6 +++ MediaBrowser.Controller/LiveTv/ILiveTvItem.cs | 1 + .../Music/FanArtArtistProvider.cs | 2 +- .../TV/FanArtTvUpdatesPostScanTask.cs | 2 +- .../Connect/ConnectEntryPoint.cs | 45 +++++++++++++--------- .../LiveTv/LiveTvManager.cs | 2 + .../Localization/JavaScript/javascript.json | 3 +- .../MediaBrowser.WebDashboard.csproj | 6 +++ 8 files changed, 45 insertions(+), 22 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index a19b66af6..c0917b8df 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1768,6 +1768,12 @@ namespace MediaBrowser.Api.Playback state.InputAudioSync = "1"; } + if (string.Equals(mediaSource.Container, "wma", StringComparison.OrdinalIgnoreCase)) + { + // Seeing some stuttering when transcoding wma to audio-only HLS + state.InputAudioSync = "1"; + } + var mediaStreams = mediaSource.MediaStreams; if (videoRequest != null) diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs index 313675fb7..36727f4ae 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvItem.cs @@ -5,5 +5,6 @@ namespace MediaBrowser.Controller.LiveTv public interface ILiveTvItem : IHasId { string ServiceName { get; set; } + string ExternalId { get; set; } } } diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index 0ed654962..597c5c0bc 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -8,6 +8,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.TV; using System; using System.Collections.Generic; using System.Globalization; @@ -17,7 +18,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; -using MediaBrowser.Providers.TV; namespace MediaBrowser.Providers.Music { diff --git a/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs b/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs index 115b80434..64c6488fb 100644 --- a/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/FanArtTvUpdatesPostScanTask.cs @@ -130,7 +130,7 @@ namespace MediaBrowser.Providers.TV { var json = await reader.ReadToEndAsync().ConfigureAwait(false); - if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(json, "null", StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(json)) { return new List(); } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 6dc83bc74..770eaa41f 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Configuration; +using System.Linq; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Plugins; @@ -38,34 +39,40 @@ namespace MediaBrowser.Server.Implementations.Connect _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } + private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.mediabrowser.tv/service/ip" }; + private async void TimerCallback(object state) { - try + foreach (var ipLookupUrl in _ipLookups) { - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = "http://bot.whatismyipaddress.com/" - - }).ConfigureAwait(false)) + try { - using (var reader = new StreamReader(stream)) + using (var stream = await _httpClient.Get(new HttpRequestOptions { - var address = await reader.ReadToEndAsync().ConfigureAwait(false); + Url = ipLookupUrl - if (IsValid(address)) + }).ConfigureAwait(false)) + { + using (var reader = new StreamReader(stream)) { - ((ConnectManager)_connectManager).OnWanAddressResolved(address); - CacheAddress(address); + var address = await reader.ReadToEndAsync().ConfigureAwait(false); + + if (IsValid(address)) + { + ((ConnectManager)_connectManager).OnWanAddressResolved(address); + CacheAddress(address); + return; + } } } } - } - catch (HttpException) - { - } - catch (Exception ex) - { - _logger.ErrorException("Error getting connection info", ex); + catch (HttpException) + { + } + catch (Exception ex) + { + _logger.ErrorException("Error getting connection info", ex); + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 6e6be03a4..f6c69d8d6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -664,6 +664,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv var recording = (ILiveTvRecording)item; + recording.ExternalId = info.Id; + recording.ProgramId = _tvDtoService.GetInternalProgramId(serviceName, info.ProgramId).ToString("N"); recording.Audio = info.Audio; recording.ChannelType = info.ChannelType; diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index c4100f219..1ccf21119 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -800,5 +800,6 @@ "HeaderYouSaid": "You Said...", "MessageWeDidntRecognizeCommand": "We're sorry, we didn't recognize that command.", "MessageIfYouBlockedVoice": "If you denied voice access to the app you'll need to reconfigure before trying again.", - "MessageNoItemsFound": "No items found." + "MessageNoItemsFound": "No items found.", + "ButtonManageServer": "Manage Server" } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 71f1f3415..48cd3f234 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,6 +90,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -123,6 +126,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 67c4c9381f3c56f44d7ecadb3b95f72929b8af6e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Jun 2015 17:22:44 -0400 Subject: 3.0.5641.0 --- .../Subtitles/ISubtitleProvider.cs | 8 +++++ .../Subtitles/OpenSubtitleDownloader.cs | 36 ++++++++++++++++++---- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 24 +++++++-------- .../Connect/ConnectEntryPoint.cs | 9 ++++-- SharedVersion.cs | 4 +-- 5 files changed, 58 insertions(+), 23 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs b/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs index dceea0cc6..5cb106fec 100644 --- a/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs +++ b/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Providers; using System.Collections.Generic; using System.Threading; @@ -35,5 +36,12 @@ namespace MediaBrowser.Controller.Subtitles /// The cancellation token. /// Task{SubtitleResponse}. Task GetSubtitles(string id, CancellationToken cancellationToken); + + /// + /// Gets the supported languages. + /// + /// The cancellation token. + /// Task<IEnumerable<NameIdPair>>. + Task> GetSupportedLanguages(CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs index 289c5661f..54db0d5fa 100644 --- a/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs +++ b/MediaBrowser.Providers/Subtitles/OpenSubtitleDownloader.cs @@ -5,10 +5,11 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; using OpenSubtitlesHandler; using System; using System.Collections.Generic; @@ -38,17 +39,23 @@ namespace MediaBrowser.Providers.Subtitles // And the user may restart the server private const int MaxDownloadsPerDay = 150; - public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption) + private readonly IJsonSerializer _json; + + public OpenSubtitleDownloader(ILogManager logManager, IHttpClient httpClient, IServerConfigurationManager config, IEncryptionManager encryption, IJsonSerializer json) { _logger = logManager.GetLogger(GetType().Name); _httpClient = httpClient; _config = config; _encryption = encryption; + _json = json; _config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating; // Reset the count every 24 hours _dailyTimer = new Timer(state => _dailyDownloadCount = 0, null, TimeSpan.FromHours(24), TimeSpan.FromHours(24)); + + Utilities.HttpClient = httpClient; + OpenSubtitles.SetUserAgent("mediabrowser.tv"); } private const string PasswordHashPrefix = "h:"; @@ -195,6 +202,26 @@ namespace MediaBrowser.Providers.Subtitles _lastLogin = DateTime.UtcNow; } + public async Task> GetSupportedLanguages(CancellationToken cancellationToken) + { + await Login(cancellationToken).ConfigureAwait(false); + + var result = OpenSubtitles.GetSubLanguages("en"); + if (!(result is MethodResponseGetSubLanguages)) + { + _logger.Error("Invalid response type"); + return new List(); + } + + var results = ((MethodResponseGetSubLanguages)result).Languages; + + return results.Select(i => new NameIdPair + { + Name = i.LanguageName, + Id = i.SubLanguageID + }); + } + public async Task> Search(SubtitleSearchRequest request, CancellationToken cancellationToken) { var imdbIdText = request.GetProviderId(MetadataProviders.Imdb); @@ -229,9 +256,6 @@ namespace MediaBrowser.Providers.Subtitles return new List(); } - Utilities.HttpClient = _httpClient; - OpenSubtitles.SetUserAgent("mediabrowser.tv"); - await Login(cancellationToken).ConfigureAwait(false); var subLanguageId = request.Language; @@ -260,7 +284,7 @@ namespace MediaBrowser.Providers.Subtitles var result = await OpenSubtitles.SearchSubtitlesAsync(parms.ToArray(), cancellationToken).ConfigureAwait(false); if (!(result is MethodResponseSubtitleSearch)) { - _logger.Debug("Invalid response type"); + _logger.Error("Invalid response type"); return new List(); } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 60e484a36..8bdd914df 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -398,21 +398,21 @@ namespace MediaBrowser.Providers.TV } } - if (titles.Any(t => string.Equals(t, comparableName, StringComparison.OrdinalIgnoreCase))) + foreach (var title in titles) { - var id = node.SelectSingleNode("./seriesid") ?? - node.SelectSingleNode("./id"); - - if (id != null) + if (string.Equals(title, comparableName, StringComparison.OrdinalIgnoreCase)) { - searchResult.Name = titles.FirstOrDefault(); - searchResult.SetProviderId(MetadataProviders.Tvdb, id.InnerText); - searchResults.Add(searchResult); - } - } + var id = node.SelectSingleNode("./seriesid") ?? + node.SelectSingleNode("./id"); - foreach (var title in titles) - { + if (id != null) + { + searchResult.Name = title; + searchResult.SetProviderId(MetadataProviders.Tvdb, id.InnerText); + searchResults.Add(searchResult); + } + break; + } _logger.Info("TVDb Provider - " + title + " did not match " + comparableName); } } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 770eaa41f..973519a77 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -1,4 +1,4 @@ -using System.Linq; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Connect; @@ -22,14 +22,16 @@ namespace MediaBrowser.Server.Implementations.Connect private readonly IConnectManager _connectManager; private readonly INetworkManager _networkManager; + private readonly IApplicationHost _appHost; - public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager) + public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost) { _httpClient = httpClient; _appPaths = appPaths; _logger = logger; _networkManager = networkManager; _connectManager = connectManager; + _appHost = appHost; } public void Run() @@ -49,7 +51,8 @@ namespace MediaBrowser.Server.Implementations.Connect { using (var stream = await _httpClient.Get(new HttpRequestOptions { - Url = ipLookupUrl + Url = ipLookupUrl, + UserAgent = "Emby Server/" + _appHost.ApplicationVersion }).ConfigureAwait(false)) { diff --git a/SharedVersion.cs b/SharedVersion.cs index c576e56f1..c81991d9a 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5621.4")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5641.0")] -- cgit v1.2.3