diff options
Diffstat (limited to 'MediaBrowser.Controller/LiveTv')
17 files changed, 2070 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs new file mode 100644 index 000000000..c000da852 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -0,0 +1,74 @@ +using MediaBrowser.Model.LiveTv; + +namespace MediaBrowser.Controller.LiveTv +{ + /// <summary> + /// Class ChannelInfo + /// </summary> + public class ChannelInfo + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the number. + /// </summary> + /// <value>The number.</value> + public string Number { get; set; } + + /// <summary> + /// Get or sets the Id. + /// </summary> + /// <value>The id of the channel.</value> + public string Id { get; set; } + + public string Path { get; set; } + + public string TunerChannelId { get; set; } + + public string CallSign { get; set; } + + /// <summary> + /// Gets or sets the tuner host identifier. + /// </summary> + /// <value>The tuner host identifier.</value> + public string TunerHostId { get; set; } + + /// <summary> + /// Gets or sets the type of the channel. + /// </summary> + /// <value>The type of the channel.</value> + public ChannelType ChannelType { get; set; } + + /// <summary> + /// Supply the image path if it can be accessed directly from the file system + /// </summary> + /// <value>The image path.</value> + public string ImagePath { get; set; } + + /// <summary> + /// Supply the image url if it can be downloaded + /// </summary> + /// <value>The image URL.</value> + public string ImageUrl { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has image. + /// </summary> + /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> + public bool? HasImage { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is favorite. + /// </summary> + /// <value><c>null</c> if [is favorite] contains no value, <c>true</c> if [is favorite]; otherwise, <c>false</c>.</value> + public bool? IsFavorite { get; set; } + + public bool? IsHD { get; set; } + public string AudioCodec { get; set; } + public string VideoCodec { get; set; } + public string[] Tags { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs new file mode 100644 index 000000000..faf4a34df --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs @@ -0,0 +1,19 @@ +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface IListingsProvider + { + string Name { get; } + string Type { get; } + Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); + Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); + Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location); + Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs new file mode 100644 index 000000000..a7f675034 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -0,0 +1,293 @@ +using System; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Querying; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Controller.Library; + +namespace MediaBrowser.Controller.LiveTv +{ + /// <summary> + /// Manages all live tv services installed on the server + /// </summary> + public interface ILiveTvManager + { + /// <summary> + /// Gets the services. + /// </summary> + /// <value>The services.</value> + IReadOnlyList<ILiveTvService> Services { get; } + + /// <summary> + /// Gets the new timer defaults asynchronous. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{TimerInfo}.</returns> + Task<SeriesTimerInfoDto> GetNewTimerDefaults(CancellationToken cancellationToken); + + /// <summary> + /// Gets the new timer defaults. + /// </summary> + /// <param name="programId">The program identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{SeriesTimerInfoDto}.</returns> + Task<SeriesTimerInfoDto> GetNewTimerDefaults(string programId, CancellationToken cancellationToken); + + /// <summary> + /// Cancels the timer. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>Task.</returns> + Task CancelTimer(string id); + + /// <summary> + /// Cancels the series timer. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>Task.</returns> + Task CancelSeriesTimer(string id); + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="services">The services.</param> + /// <param name="tunerHosts">The tuner hosts.</param> + /// <param name="listingProviders">The listing providers.</param> + void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders); + + /// <summary> + /// Gets the timer. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{TimerInfoDto}.</returns> + Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken); + + /// <summary> + /// Gets the series timer. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{TimerInfoDto}.</returns> + Task<SeriesTimerInfoDto> GetSeriesTimer(string id, CancellationToken cancellationToken); + + /// <summary> + /// Gets the recordings. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="options">The options.</param> + QueryResult<BaseItemDto> GetRecordings(RecordingQuery query, DtoOptions options); + + /// <summary> + /// Gets the timers. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{QueryResult{TimerInfoDto}}.</returns> + Task<QueryResult<TimerInfoDto>> GetTimers(TimerQuery query, CancellationToken cancellationToken); + + /// <summary> + /// Gets the series timers. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{QueryResult{SeriesTimerInfoDto}}.</returns> + Task<QueryResult<SeriesTimerInfoDto>> GetSeriesTimers(SeriesTimerQuery query, CancellationToken cancellationToken); + + /// <summary> + /// Gets the channel stream. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="mediaSourceId">The media source identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{StreamResponseInfo}.</returns> + Task<Tuple<MediaSourceInfo, ILiveStream>> GetChannelStream(string id, string mediaSourceId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken); + + /// <summary> + /// Gets the program. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="user">The user.</param> + /// <returns>Task{ProgramInfoDto}.</returns> + Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null); + + /// <summary> + /// Gets the programs. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="options">The options.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>IEnumerable{ProgramInfo}.</returns> + Task<QueryResult<BaseItemDto>> GetPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken); + + /// <summary> + /// Updates the timer. + /// </summary> + /// <param name="timer">The timer.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken); + + /// <summary> + /// Updates the timer. + /// </summary> + /// <param name="timer">The timer.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken); + + /// <summary> + /// Creates the timer. + /// </summary> + /// <param name="timer">The timer.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CreateTimer(TimerInfoDto timer, CancellationToken cancellationToken); + + /// <summary> + /// Creates the series timer. + /// </summary> + /// <param name="timer">The timer.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken); + + /// <summary> + /// Gets the guide information. + /// </summary> + /// <returns>GuideInfo.</returns> + GuideInfo GetGuideInfo(); + + /// <summary> + /// Gets the recommended programs. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="options">The options.</param> + /// <param name="cancellationToken">The cancellation token.</param> + QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken); + + /// <summary> + /// Gets the recommended programs internal. + /// </summary> + QueryResult<BaseItem> GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken); + + /// <summary> + /// Gets the live tv information. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{LiveTvInfo}.</returns> + LiveTvInfo GetLiveTvInfo(CancellationToken cancellationToken); + + /// <summary> + /// Resets the tuner. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task ResetTuner(string id, CancellationToken cancellationToken); + + /// <summary> + /// Gets the live tv folder. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + Folder GetInternalLiveTvFolder(CancellationToken cancellationToken); + + /// <summary> + /// Gets the enabled users. + /// </summary> + /// <returns>IEnumerable{User}.</returns> + IEnumerable<User> GetEnabledUsers(); + + /// <summary> + /// Gets the internal channels. + /// </summary> + QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken); + + /// <summary> + /// Gets the channel media sources. + /// </summary> + Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(BaseItem item, CancellationToken cancellationToken); + + /// <summary> + /// Adds the information to program dto. + /// </summary> + /// <param name="programs">The programs.</param> + /// <param name="fields">The fields.</param> + /// <param name="user">The user.</param> + /// <returns>Task.</returns> + Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> programs, ItemFields[] fields, User user = null); + + /// <summary> + /// Saves the tuner host. + /// </summary> + Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true); + /// <summary> + /// Saves the listing provider. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="validateLogin">if set to <c>true</c> [validate login].</param> + /// <param name="validateListings">if set to <c>true</c> [validate listings].</param> + /// <returns>Task.</returns> + Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings); + + void DeleteListingsProvider(string id); + + Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber); + + TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, NameValuePair[] mappings, List<ChannelInfo> providerChannels); + + /// <summary> + /// Gets the lineups. + /// </summary> + /// <param name="providerType">Type of the provider.</param> + /// <param name="providerId">The provider identifier.</param> + /// <param name="country">The country.</param> + /// <param name="location">The location.</param> + /// <returns>Task<List<NameIdPair>>.</returns> + Task<List<NameIdPair>> GetLineups(string providerType, string providerId, string country, string location); + + /// <summary> + /// Adds the channel information. + /// </summary> + /// <param name="items">The items.</param> + /// <param name="options">The options.</param> + /// <param name="user">The user.</param> + void AddChannelInfo(List<Tuple<BaseItemDto, LiveTvChannel>> items, DtoOptions options, User user); + + Task<List<ChannelInfo>> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken); + Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken); + + IListingsProvider[] ListingProviders { get; } + + List<NameIdPair> GetTunerHostTypes(); + Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken); + + event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled; + event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled; + event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated; + event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated; + + string GetEmbyTvActiveRecordingPath(string id); + + ActiveRecordingInfo GetActiveRecordingInfo(string path); + + void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, ActiveRecordingInfo activeRecordingInfo, User user = null); + + List<BaseItem> GetRecordingFolders(User user); + } + + public class ActiveRecordingInfo + { + public string Id { get; set; } + public string Path { get; set; } + public TimerInfo Timer { get; set; } + public CancellationTokenSource CancellationTokenSource { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs new file mode 100644 index 000000000..601fb69aa --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -0,0 +1,190 @@ +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Model.Dto; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Library; + +namespace MediaBrowser.Controller.LiveTv +{ + /// <summary> + /// Represents a single live tv back end (next pvr, media portal, etc). + /// </summary> + public interface ILiveTvService + { + /// <summary> + /// Occurs when [data source changed]. + /// </summary> + event EventHandler DataSourceChanged; + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Gets the home page URL. + /// </summary> + /// <value>The home page URL.</value> + string HomePageUrl { get; } + + /// <summary> + /// Gets the channels async. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{IEnumerable{ChannelInfo}}.</returns> + Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken cancellationToken); + + /// <summary> + /// Cancels the timer asynchronous. + /// </summary> + /// <param name="timerId">The timer identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CancelTimerAsync(string timerId, CancellationToken cancellationToken); + + /// <summary> + /// Cancels the series timer asynchronous. + /// </summary> + /// <param name="timerId">The timer identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken); + + /// <summary> + /// Creates the timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken); + + /// <summary> + /// Creates the series timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken); + + /// <summary> + /// Updates the timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken); + + /// <summary> + /// Updates the series timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken); + + /// <summary> + /// Gets the recordings asynchronous. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{IEnumerable{RecordingInfo}}.</returns> + Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken); + + /// <summary> + /// Gets the new timer defaults asynchronous. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="program">The program.</param> + /// <returns>Task{SeriesTimerInfo}.</returns> + Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null); + + /// <summary> + /// Gets the series timers asynchronous. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{IEnumerable{SeriesTimerInfo}}.</returns> + Task<IEnumerable<SeriesTimerInfo>> GetSeriesTimersAsync(CancellationToken cancellationToken); + + /// <summary> + /// Gets the programs asynchronous. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="startDateUtc">The start date UTC.</param> + /// <param name="endDateUtc">The end date UTC.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{IEnumerable{ProgramInfo}}.</returns> + Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); + + /// <summary> + /// Gets the channel stream. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="streamId">The stream identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{Stream}.</returns> + Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken); + + /// <summary> + /// Gets the channel stream media sources. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<List<MediaSourceInfo>>.</returns> + Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); + + /// <summary> + /// Closes the live stream. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CloseLiveStream(string id, CancellationToken cancellationToken); + + /// <summary> + /// Records the live stream. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task RecordLiveStream(string id, CancellationToken cancellationToken); + + /// <summary> + /// Resets the tuner. + /// </summary> + /// <param name="id">The identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task ResetTuner(string id, CancellationToken cancellationToken); + } + + public interface ISupportsNewTimerIds + { + /// <summary> + /// Creates the timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task<string> CreateTimer(TimerInfo info, CancellationToken cancellationToken); + + /// <summary> + /// Creates the series timer asynchronous. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task<string> CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken); + } + + public interface ISupportsDirectStreamProvider + { + Task<ILiveStream> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken); + } + + public interface ISupportsUpdatingDefaults + { + Task UpdateTimerDefaults(SeriesTimerInfo info, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs new file mode 100644 index 000000000..d5a0e2115 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -0,0 +1,62 @@ +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Library; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface ITunerHost + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + /// <summary> + /// Gets the type. + /// </summary> + /// <value>The type.</value> + string Type { get; } + /// <summary> + /// Gets the channels. + /// </summary> + /// <returns>Task<IEnumerable<ChannelInfo>>.</returns> + Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken); + /// <summary> + /// Gets the tuner infos. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<List<LiveTvTunerInfo>>.</returns> + Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken); + /// <summary> + /// Gets the channel stream. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="streamId">The stream identifier.</param> + Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken); + /// <summary> + /// Gets the channel stream media sources. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<List<MediaSourceInfo>>.</returns> + Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); + + Task<List<TunerHostInfo>> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken); + bool IsSupported + { + get; + } + } + public interface IConfigurableTunerHost + { + /// <summary> + /// Validates the specified information. + /// </summary> + /// <param name="info">The information.</param> + /// <returns>Task.</returns> + Task Validate(TunerHostInfo info); + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs new file mode 100644 index 000000000..9e2d29eb6 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -0,0 +1,197 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.MediaInfo; +using System.Collections.Generic; +using System.Globalization; +using MediaBrowser.Model.Serialization; +using System; +using System.Linq; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes + { + public override List<string> GetUserDataKeys() + { + var list = base.GetUserDataKeys(); + + if (!ConfigurationManager.Configuration.DisableLiveTvChannelUserDataName) + { + list.Insert(0, GetClientTypeName() + "-" + Name); + } + + return list; + } + + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.LiveTvChannel; + } + + [IgnoreDataMember] + public override bool SupportsPositionTicksResume + { + get + { + return false; + } + } + + [IgnoreDataMember] + public override SourceType SourceType + { + get { return SourceType.LiveTV; } + } + + [IgnoreDataMember] + public override bool EnableRememberingTrackSelections + { + get + { + return false; + } + } + + /// <summary> + /// Gets or sets the number. + /// </summary> + /// <value>The number.</value> + public string Number { get; set; } + + /// <summary> + /// Gets or sets the type of the channel. + /// </summary> + /// <value>The type of the channel.</value> + public ChannelType ChannelType { get; set; } + + [IgnoreDataMember] + public override LocationType LocationType + { + get + { + // TODO: This should be removed + return LocationType.Remote; + } + } + + protected override string CreateSortName() + { + if (!string.IsNullOrEmpty(Number)) + { + double number = 0; + + if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number)) + { + return string.Format("{0:00000.0}", number) + "-" + (Name ?? string.Empty); + } + } + + return (Number ?? string.Empty) + "-" + (Name ?? string.Empty); + } + + [IgnoreDataMember] + public override string MediaType + { + get + { + return ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video; + } + } + + public override string GetClientTypeName() + { + return "TvChannel"; + } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return new List<BaseItem>(); + } + + public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution) + { + var list = new List<MediaSourceInfo>(); + + var info = new MediaSourceInfo + { + Id = Id.ToString("N"), + Protocol = PathProtocol ?? MediaProtocol.File, + MediaStreams = new List<MediaStream>(), + Name = Name, + Path = Path, + RunTimeTicks = RunTimeTicks, + Type = MediaSourceType.Placeholder, + IsInfiniteStream = RunTimeTicks == null + }; + + list.Add(info); + + return list; + } + + public override List<MediaStream> GetMediaStreams() + { + return new List<MediaStream>(); + } + + protected override string GetInternalMetadataPath(string basePath) + { + return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata"); + } + + public override bool CanDelete() + { + return false; + } + + [IgnoreDataMember] + public bool IsMovie { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is sports. + /// </summary> + /// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSports { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is series. + /// </summary> + /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is news. + /// </summary> + /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsNews { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is kids. + /// </summary> + /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsKids + { + get + { + return Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase); + } + } + + [IgnoreDataMember] + public bool IsRepeat { get; set; } + + /// <summary> + /// Gets or sets the episode title. + /// </summary> + /// <value>The episode title.</value> + [IgnoreDataMember] + public string EpisodeTitle { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs b/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs new file mode 100644 index 000000000..a7735ad80 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs @@ -0,0 +1,20 @@ +using System; + +namespace MediaBrowser.Controller.LiveTv +{ + /// <summary> + /// Class LiveTvConflictException. + /// </summary> + public class LiveTvConflictException : Exception + { + public LiveTvConflictException() + { + + } + public LiveTvConflictException(string message) + : base(message) + { + + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs new file mode 100644 index 000000000..fa3aab4f2 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -0,0 +1,349 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveTvProgram : BaseItem, IHasLookupInfo<ItemLookupInfo>, IHasStartDate, IHasProgramAttributes + { + public LiveTvProgram() + { + IsVirtualItem = true; + } + + public override List<string> GetUserDataKeys() + { + var list = base.GetUserDataKeys(); + + if (!IsSeries) + { + var key = this.GetProviderId(MetadataProviders.Imdb); + if (!string.IsNullOrEmpty(key)) + { + list.Insert(0, key); + } + + key = this.GetProviderId(MetadataProviders.Tmdb); + if (!string.IsNullOrEmpty(key)) + { + list.Insert(0, key); + } + } + else if (!string.IsNullOrEmpty(EpisodeTitle)) + { + var name = GetClientTypeName(); + + list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty)); + } + + return list; + } + + public static double GetDefaultPrimaryImageAspectRatio(IHasProgramAttributes item) + { + var serviceName = item.ServiceName; + + if (item.IsMovie) + { + if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase)) + { + double value = 2; + value /= 3; + + return value; + } + else + { + double value = 16; + value /= 9; + + return value; + } + } + else + { + if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase)) + { + double value = 2; + value /= 3; + + return value; + } + else + { + double value = 16; + value /= 9; + + return value; + } + } + } + + private static string EmbyServiceName = "Emby"; + public override double GetDefaultPrimaryImageAspectRatio() + { + return GetDefaultPrimaryImageAspectRatio(this); + } + + [IgnoreDataMember] + public override SourceType SourceType + { + get { return SourceType.LiveTV; } + } + + /// <summary> + /// The start date of the program, in UTC. + /// </summary> + [IgnoreDataMember] + public DateTime StartDate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is repeat. + /// </summary> + /// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsRepeat { get; set; } + + /// <summary> + /// Gets or sets the episode title. + /// </summary> + /// <value>The episode title.</value> + [IgnoreDataMember] + public string EpisodeTitle { get; set; } + + [IgnoreDataMember] + public string ShowId { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is movie. + /// </summary> + /// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsMovie { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is sports. + /// </summary> + /// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSports + { + get + { + return Tags.Contains("Sports", StringComparer.OrdinalIgnoreCase); + } + } + + /// <summary> + /// Gets or sets a value indicating whether this instance is series. + /// </summary> + /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is live. + /// </summary> + /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsLive + { + get + { + return Tags.Contains("Live", StringComparer.OrdinalIgnoreCase); + } + } + + /// <summary> + /// Gets or sets a value indicating whether this instance is news. + /// </summary> + /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsNews + { + get + { + return Tags.Contains("News", StringComparer.OrdinalIgnoreCase); + } + } + + /// <summary> + /// Gets or sets a value indicating whether this instance is kids. + /// </summary> + /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsKids + { + get + { + return Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase); + } + } + + /// <summary> + /// Gets or sets a value indicating whether this instance is premiere. + /// </summary> + /// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsPremiere + { + get + { + return Tags.Contains("Premiere", StringComparer.OrdinalIgnoreCase); + } + } + + /// <summary> + /// Returns the folder containing the item. + /// If the item is a folder, it returns the folder itself + /// </summary> + /// <value>The containing folder path.</value> + [IgnoreDataMember] + public override string ContainingFolderPath + { + get + { + return Path; + } + } + + //[IgnoreDataMember] + //public override string MediaType + //{ + // get + // { + // return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio; + // } + //} + + [IgnoreDataMember] + public bool IsAiring + { + get + { + var now = DateTime.UtcNow; + + return now >= StartDate && now < EndDate; + } + } + + [IgnoreDataMember] + public bool HasAired + { + get + { + var now = DateTime.UtcNow; + + return now >= EndDate; + } + } + + public override string GetClientTypeName() + { + return "Program"; + } + + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.LiveTvProgram; + } + + protected override string GetInternalMetadataPath(string basePath) + { + return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); + } + + public override bool CanDelete() + { + return false; + } + + [IgnoreDataMember] + public override bool SupportsPeople + { + get + { + // Optimization + if (IsNews || IsSports) + { + return false; + } + + return base.SupportsPeople; + } + } + + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + + private LiveTvOptions GetConfiguration() + { + return ConfigurationManager.GetConfiguration<LiveTvOptions>("livetv"); + } + + private ListingsProviderInfo GetListingsProviderInfo() + { + if (string.Equals(ServiceName, "Emby", StringComparison.OrdinalIgnoreCase)) + { + var config = GetConfiguration(); + + return config.ListingProviders.FirstOrDefault(i => !string.IsNullOrEmpty(i.MoviePrefix)); + } + + return null; + } + + protected override string GetNameForMetadataLookup() + { + var name = base.GetNameForMetadataLookup(); + + var listings = GetListingsProviderInfo(); + + if (listings != null) + { + if (!string.IsNullOrEmpty(listings.MoviePrefix) && name.StartsWith(listings.MoviePrefix, StringComparison.OrdinalIgnoreCase)) + { + name = name.Substring(listings.MoviePrefix.Length).Trim(); + } + } + + return name; + } + + public override List<ExternalUrl> GetRelatedUrls() + { + var list = base.GetRelatedUrls(); + + var imdbId = this.GetProviderId(MetadataProviders.Imdb); + if (!string.IsNullOrEmpty(imdbId)) + { + if (IsMovie) + { + list.Add(new ExternalUrl + { + Name = "Trakt", + Url = string.Format("https://trakt.tv/movies/{0}", imdbId) + }); + } + } + + return list; + } + + public string SeriesName { get; set;} + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs new file mode 100644 index 000000000..4da238acf --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs @@ -0,0 +1,49 @@ +using MediaBrowser.Model.LiveTv; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveTvServiceStatusInfo + { + /// <summary> + /// Gets or sets the status. + /// </summary> + /// <value>The status.</value> + public LiveTvServiceStatus Status { get; set; } + + /// <summary> + /// Gets or sets the status message. + /// </summary> + /// <value>The status message.</value> + public string StatusMessage { get; set; } + + /// <summary> + /// Gets or sets the version. + /// </summary> + /// <value>The version.</value> + public string Version { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has update available. + /// </summary> + /// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value> + public bool HasUpdateAvailable { get; set; } + + /// <summary> + /// Gets or sets the tuners. + /// </summary> + /// <value>The tuners.</value> + public List<LiveTvTunerInfo> Tuners { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is visible. + /// </summary> + /// <value><c>true</c> if this instance is visible; otherwise, <c>false</c>.</value> + public bool IsVisible { get; set; } + + public LiveTvServiceStatusInfo() + { + Tuners = new List<LiveTvTunerInfo>(); + IsVisible = true; + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs new file mode 100644 index 000000000..5c001f288 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs @@ -0,0 +1,73 @@ +using MediaBrowser.Model.LiveTv; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveTvTunerInfo + { + /// <summary> + /// Gets or sets the type of the source. + /// </summary> + /// <value>The type of the source.</value> + public string SourceType { get; set; } + + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the identifier. + /// </summary> + /// <value>The identifier.</value> + public string Id { get; set; } + + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + public string Url { get; set; } + + /// <summary> + /// Gets or sets the status. + /// </summary> + /// <value>The status.</value> + public LiveTvTunerStatus Status { get; set; } + + /// <summary> + /// Gets or sets the channel identifier. + /// </summary> + /// <value>The channel identifier.</value> + public string ChannelId { get; set; } + + /// <summary> + /// Gets or sets the recording identifier. + /// </summary> + /// <value>The recording identifier.</value> + public string RecordingId { get; set; } + + /// <summary> + /// Gets or sets the name of the program. + /// </summary> + /// <value>The name of the program.</value> + public string ProgramName { get; set; } + + /// <summary> + /// Gets or sets the clients. + /// </summary> + /// <value>The clients.</value> + public List<string> Clients { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance can reset. + /// </summary> + /// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value> + public bool CanReset { get; set; } + + public LiveTvTunerInfo() + { + Clients = new List<string>(); + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs new file mode 100644 index 000000000..9e3cbdded --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -0,0 +1,213 @@ +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Controller.LiveTv +{ + public class ProgramInfo + { + /// <summary> + /// Id of the program. + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Gets or sets the channel identifier. + /// </summary> + /// <value>The channel identifier.</value> + public string ChannelId { get; set; } + + /// <summary> + /// Name of the program + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the official rating. + /// </summary> + /// <value>The official rating.</value> + public string OfficialRating { get; set; } + + /// <summary> + /// Gets or sets the overview. + /// </summary> + /// <value>The overview.</value> + public string Overview { get; set; } + /// <summary> + /// Gets or sets the short overview. + /// </summary> + /// <value>The short overview.</value> + public string ShortOverview { get; set; } + + /// <summary> + /// The start date of the program, in UTC. + /// </summary> + public DateTime StartDate { get; set; } + + /// <summary> + /// The end date of the program, in UTC. + /// </summary> + public DateTime EndDate { get; set; } + + /// <summary> + /// Genre of the program. + /// </summary> + public List<string> Genres { get; set; } + + /// <summary> + /// Gets or sets the original air date. + /// </summary> + /// <value>The original air date.</value> + public DateTime? OriginalAirDate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is hd. + /// </summary> + /// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value> + public bool? IsHD { get; set; } + + public bool? Is3D { get; set; } + + /// <summary> + /// Gets or sets the audio. + /// </summary> + /// <value>The audio.</value> + public ProgramAudio? Audio { get; set; } + + /// <summary> + /// Gets or sets the community rating. + /// </summary> + /// <value>The community rating.</value> + public float? CommunityRating { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is repeat. + /// </summary> + /// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value> + public bool IsRepeat { get; set; } + + public bool IsSubjectToBlackout { get; set; } + + /// <summary> + /// Gets or sets the episode title. + /// </summary> + /// <value>The episode title.</value> + public string EpisodeTitle { get; set; } + + /// <summary> + /// Supply the image path if it can be accessed directly from the file system + /// </summary> + /// <value>The image path.</value> + public string ImagePath { get; set; } + + /// <summary> + /// Supply the image url if it can be downloaded + /// </summary> + /// <value>The image URL.</value> + public string ImageUrl { get; set; } + + public string ThumbImageUrl { get; set; } + + public string LogoImageUrl { get; set; } + + public string BackdropImageUrl { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has image. + /// </summary> + /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> + public bool? HasImage { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is movie. + /// </summary> + /// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value> + public bool IsMovie { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is sports. + /// </summary> + /// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value> + public bool IsSports { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is series. + /// </summary> + /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is live. + /// </summary> + /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + public bool IsLive { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is news. + /// </summary> + /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + public bool IsNews { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is kids. + /// </summary> + /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> + public bool IsKids { get; set; } + + public bool IsEducational { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is premiere. + /// </summary> + /// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value> + public bool IsPremiere { get; set; } + + /// <summary> + /// Gets or sets the production year. + /// </summary> + /// <value>The production year.</value> + public int? ProductionYear { get; set; } + /// <summary> + /// Gets or sets the home page URL. + /// </summary> + /// <value>The home page URL.</value> + public string HomePageUrl { get; set; } + /// <summary> + /// Gets or sets the series identifier. + /// </summary> + /// <value>The series identifier.</value> + public string SeriesId { get; set; } + /// <summary> + /// Gets or sets the show identifier. + /// </summary> + /// <value>The show identifier.</value> + public string ShowId { get; set; } + /// <summary> + /// Gets or sets the season number. + /// </summary> + /// <value>The season number.</value> + public int? SeasonNumber { get; set; } + /// <summary> + /// Gets or sets the episode number. + /// </summary> + /// <value>The episode number.</value> + public int? EpisodeNumber { get; set; } + /// <summary> + /// Gets or sets the etag. + /// </summary> + /// <value>The etag.</value> + public string Etag { get; set; } + + public Dictionary<string, string> ProviderIds { get; set; } + public Dictionary<string, string> SeriesProviderIds { get; set; } + + public ProgramInfo() + { + Genres = new List<string>(); + + ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs new file mode 100644 index 000000000..3006b9bbe --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -0,0 +1,205 @@ +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.LiveTv +{ + public class RecordingInfo + { + /// <summary> + /// Id of the recording. + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Gets or sets the series timer identifier. + /// </summary> + /// <value>The series timer identifier.</value> + public string SeriesTimerId { get; set; } + + /// <summary> + /// Gets or sets the timer identifier. + /// </summary> + /// <value>The timer identifier.</value> + public string TimerId { get; set; } + + /// <summary> + /// ChannelId of the recording. + /// </summary> + public string ChannelId { get; set; } + + /// <summary> + /// Gets or sets the type of the channel. + /// </summary> + /// <value>The type of the channel.</value> + public ChannelType ChannelType { get; set; } + + /// <summary> + /// Name of the recording. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the path. + /// </summary> + /// <value>The path.</value> + public string Path { get; set; } + + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + public string Url { get; set; } + + /// <summary> + /// Gets or sets the overview. + /// </summary> + /// <value>The overview.</value> + public string Overview { get; set; } + + /// <summary> + /// The start date of the recording, in UTC. + /// </summary> + public DateTime StartDate { get; set; } + + /// <summary> + /// The end date of the recording, in UTC. + /// </summary> + public DateTime EndDate { get; set; } + + /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + /// <summary> + /// Gets or sets the status. + /// </summary> + /// <value>The status.</value> + public RecordingStatus Status { get; set; } + + /// <summary> + /// Genre of the program. + /// </summary> + public List<string> Genres { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is repeat. + /// </summary> + /// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value> + public bool IsRepeat { get; set; } + + /// <summary> + /// Gets or sets the episode title. + /// </summary> + /// <value>The episode title.</value> + public string EpisodeTitle { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is hd. + /// </summary> + /// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value> + public bool? IsHD { get; set; } + + /// <summary> + /// Gets or sets the audio. + /// </summary> + /// <value>The audio.</value> + public ProgramAudio? Audio { get; set; } + + /// <summary> + /// Gets or sets the original air date. + /// </summary> + /// <value>The original air date.</value> + public DateTime? OriginalAirDate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is movie. + /// </summary> + /// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value> + public bool IsMovie { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is sports. + /// </summary> + /// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value> + public bool IsSports { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is series. + /// </summary> + /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is live. + /// </summary> + /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + public bool IsLive { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is news. + /// </summary> + /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + public bool IsNews { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is kids. + /// </summary> + /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> + public bool IsKids { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is premiere. + /// </summary> + /// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value> + public bool IsPremiere { get; set; } + + /// <summary> + /// Gets or sets the official rating. + /// </summary> + /// <value>The official rating.</value> + public string OfficialRating { get; set; } + + /// <summary> + /// Gets or sets the community rating. + /// </summary> + /// <value>The community rating.</value> + public float? CommunityRating { get; set; } + + /// <summary> + /// Supply the image path if it can be accessed directly from the file system + /// </summary> + /// <value>The image path.</value> + public string ImagePath { get; set; } + + /// <summary> + /// Supply the image url if it can be downloaded + /// </summary> + /// <value>The image URL.</value> + public string ImageUrl { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has image. + /// </summary> + /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> + public bool? HasImage { get; set; } + /// <summary> + /// Gets or sets the show identifier. + /// </summary> + /// <value>The show identifier.</value> + public string ShowId { get; set; } + + /// <summary> + /// Gets or sets the date last updated. + /// </summary> + /// <value>The date last updated.</value> + public DateTime DateLastUpdated { get; set; } + + public RecordingInfo() + { + Genres = new List<string>(); + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs b/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs new file mode 100644 index 000000000..90ea329fe --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs @@ -0,0 +1,12 @@ +using MediaBrowser.Model.LiveTv; +using System; + +namespace MediaBrowser.Controller.LiveTv +{ + public class RecordingStatusChangedEventArgs : EventArgs + { + public string RecordingId { get; set; } + + public RecordingStatus NewStatus { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs new file mode 100644 index 000000000..5c73ed833 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using MediaBrowser.Model.LiveTv; + +namespace MediaBrowser.Controller.LiveTv +{ + public class SeriesTimerInfo + { + /// <summary> + /// Id of the recording. + /// </summary> + public string Id { get; set; } + + /// <summary> + /// ChannelId of the recording. + /// </summary> + public string ChannelId { get; set; } + + /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + /// <summary> + /// Name of the recording. + /// </summary> + public string Name { get; set; } + + public string ServiceName { get; set; } + + /// <summary> + /// Description of the recording. + /// </summary> + public string Overview { get; set; } + + /// <summary> + /// The start date of the recording, in UTC. + /// </summary> + public DateTime StartDate { get; set; } + + /// <summary> + /// The end date of the recording, in UTC. + /// </summary> + public DateTime EndDate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [record any time]. + /// </summary> + /// <value><c>true</c> if [record any time]; otherwise, <c>false</c>.</value> + public bool RecordAnyTime { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [record any channel]. + /// </summary> + /// <value><c>true</c> if [record any channel]; otherwise, <c>false</c>.</value> + public bool RecordAnyChannel { get; set; } + + public int KeepUpTo { get; set; } + public KeepUntil KeepUntil { get; set; } + + public bool SkipEpisodesInLibrary { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [record new only]. + /// </summary> + /// <value><c>true</c> if [record new only]; otherwise, <c>false</c>.</value> + public bool RecordNewOnly { get; set; } + + /// <summary> + /// Gets or sets the days. + /// </summary> + /// <value>The days.</value> + public List<DayOfWeek> Days { get; set; } + + /// <summary> + /// Gets or sets the priority. + /// </summary> + /// <value>The priority.</value> + public int Priority { get; set; } + + /// <summary> + /// Gets or sets the pre padding seconds. + /// </summary> + /// <value>The pre padding seconds.</value> + public int PrePaddingSeconds { get; set; } + + /// <summary> + /// Gets or sets the post padding seconds. + /// </summary> + /// <value>The post padding seconds.</value> + public int PostPaddingSeconds { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is pre padding required. + /// </summary> + /// <value><c>true</c> if this instance is pre padding required; otherwise, <c>false</c>.</value> + public bool IsPrePaddingRequired { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is post padding required. + /// </summary> + /// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value> + public bool IsPostPaddingRequired { get; set; } + + /// <summary> + /// Gets or sets the series identifier. + /// </summary> + /// <value>The series identifier.</value> + public string SeriesId { get; set; } + + public SeriesTimerInfo() + { + Days = new List<DayOfWeek>(); + SkipEpisodesInLibrary = true; + KeepUntil = KeepUntil.UntilDeleted; + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs new file mode 100644 index 000000000..5b71a26a2 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs @@ -0,0 +1,10 @@ +using System; + +namespace MediaBrowser.Controller.LiveTv +{ + public class TimerEventInfo + { + public string Id { get; set; } + public Guid ProgramId { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs new file mode 100644 index 000000000..baf0b0b13 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -0,0 +1,175 @@ +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Controller.LiveTv +{ + public class TimerInfo + { + public TimerInfo() + { + Genres = new string[] { }; + KeepUntil = KeepUntil.UntilDeleted; + ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + Tags = new string[] { }; + } + + public Dictionary<string, string> ProviderIds { get; set; } + public Dictionary<string, string> SeriesProviderIds { get; set; } + public string[] Tags { get; set; } + + /// <summary> + /// Id of the recording. + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Gets or sets the series timer identifier. + /// </summary> + /// <value>The series timer identifier.</value> + public string SeriesTimerId { get; set; } + + /// <summary> + /// ChannelId of the recording. + /// </summary> + public string ChannelId { get; set; } + + /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + public string ShowId { get; set; } + + /// <summary> + /// Name of the recording. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Description of the recording. + /// </summary> + public string Overview { get; set; } + + public string SeriesId { get; set; } + + /// <summary> + /// The start date of the recording, in UTC. + /// </summary> + public DateTime StartDate { get; set; } + + /// <summary> + /// The end date of the recording, in UTC. + /// </summary> + public DateTime EndDate { get; set; } + + /// <summary> + /// Gets or sets the status. + /// </summary> + /// <value>The status.</value> + public RecordingStatus Status { get; set; } + + /// <summary> + /// Gets or sets the pre padding seconds. + /// </summary> + /// <value>The pre padding seconds.</value> + public int PrePaddingSeconds { get; set; } + + /// <summary> + /// Gets or sets the post padding seconds. + /// </summary> + /// <value>The post padding seconds.</value> + public int PostPaddingSeconds { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is pre padding required. + /// </summary> + /// <value><c>true</c> if this instance is pre padding required; otherwise, <c>false</c>.</value> + public bool IsPrePaddingRequired { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is post padding required. + /// </summary> + /// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value> + public bool IsPostPaddingRequired { get; set; } + + public bool IsManual { get; set; } + + /// <summary> + /// Gets or sets the priority. + /// </summary> + /// <value>The priority.</value> + public int Priority { get; set; } + + public int RetryCount { get; set; } + + // Program properties + public int? SeasonNumber { get; set; } + /// <summary> + /// Gets or sets the episode number. + /// </summary> + /// <value>The episode number.</value> + public int? EpisodeNumber { get; set; } + public bool IsMovie { get; set; } + public bool IsKids + { + get + { + return Tags.Contains("Kids", StringComparer.OrdinalIgnoreCase); + } + } + public bool IsSports + { + get + { + return Tags.Contains("Sports", StringComparer.OrdinalIgnoreCase); + } + } + public bool IsNews + { + get + { + return Tags.Contains("News", StringComparer.OrdinalIgnoreCase); + } + } + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is live. + /// </summary> + /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsLive + { + get + { + return Tags.Contains("Live", StringComparer.OrdinalIgnoreCase); + } + } + + [IgnoreDataMember] + public bool IsPremiere + { + get + { + return Tags.Contains("Premiere", StringComparer.OrdinalIgnoreCase); + } + } + + public int? ProductionYear { get; set; } + public string EpisodeTitle { get; set; } + public DateTime? OriginalAirDate { get; set; } + public bool IsProgramSeries { get; set; } + public bool IsRepeat { get; set; } + public string HomePageUrl { get; set; } + public float? CommunityRating { get; set; } + public string OfficialRating { get; set; } + public string[] Genres { get; set; } + public string RecordingPath { get; set; } + public KeepUntil KeepUntil { get; set; } + } +} diff --git a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs new file mode 100644 index 000000000..3b2df0471 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs @@ -0,0 +1,10 @@ +namespace MediaBrowser.Controller.LiveTv +{ + public class TunerChannelMapping + { + public string Name { get; set; } + public string ProviderChannelName { get; set; } + public string ProviderChannelId { get; set; } + public string Id { get; set; } + } +} |
