diff --git a/MediaBrowser.Plugins.VuPlus/RecordingsChannel.cs b/MediaBrowser.Plugins.VuPlus/RecordingsChannel.cs new file mode 100644 index 0000000..261e881 --- /dev/null +++ b/MediaBrowser.Plugins.VuPlus/RecordingsChannel.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Channels; +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Controller.LiveTv; +using System.Linq; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Model.Dto; +using System.Globalization; +using MediaBrowser.Controller.Entities; + +namespace MediaBrowser.Plugins.VuPlus +{ + public class RecordingsChannel : IChannel, IHasCacheKey, ISupportsDelete, ISupportsLatestMedia + { + public ILiveTvManager _liveTvManager; + + public RecordingsChannel(ILiveTvManager liveTvManager) + { + _liveTvManager = liveTvManager; + } + + public string Name + { + get + { + return "VuPlus Recordings"; + } + } + + public string Description + { + get + { + return "VuPlus Recordings"; + } + } + + public string DataVersion + { + get + { + return "1"; + } + } + + public string HomePageUrl + { + get { return null; } + } + + public ChannelParentalRating ParentalRating + { + get { return ChannelParentalRating.GeneralAudience; } + } + + public string GetCacheKey(string userId) + { + var now = DateTime.UtcNow; + + var values = new List(); + + values.Add(now.DayOfYear.ToString(CultureInfo.InvariantCulture)); + values.Add(now.Hour.ToString(CultureInfo.InvariantCulture)); + + double minute = now.Minute; + minute /= 5; + + values.Add(Math.Floor(minute).ToString(CultureInfo.InvariantCulture)); + + values.Add(GetService().LastRecordingChange.Ticks.ToString(CultureInfo.InvariantCulture)); + + return string.Join("-", values.ToArray()); + } + + public InternalChannelFeatures GetChannelFeatures() + { + return new InternalChannelFeatures + { + ContentTypes = new List + { + ChannelMediaContentType.Movie, + ChannelMediaContentType.Episode, + ChannelMediaContentType.Clip + }, + MediaTypes = new List + { + ChannelMediaType.Audio, + ChannelMediaType.Video + }, + SupportsContentDownloading = true + }; + } + + public Task GetChannelImage(ImageType type, CancellationToken cancellationToken) + { + if (type == ImageType.Primary) + { + return Task.FromResult(new DynamicImageResponse + { + Path = "https://github.com/CompoUK/MediaBrowser.Plugins.VuPlus/blob/master/src/Images/Vu+.png?raw=true", + Protocol = MediaProtocol.Http, + HasImage = true + }); + } + + return Task.FromResult(new DynamicImageResponse + { + HasImage = false + }); + } + + public IEnumerable GetSupportedChannelImages() + { + return new List + { + ImageType.Primary + }; + } + + public bool IsEnabledFor(string userId) + { + return true; + } + + private LiveTvService GetService() + { + return _liveTvManager.Services.OfType().First(); + } + + public bool CanDelete(BaseItem item) + { + return !item.IsFolder; + } + + public Task DeleteItem(string id, CancellationToken cancellationToken) + { + return GetService().DeleteRecordingAsync(id, cancellationToken); + } + + public async Task> GetLatestMedia(ChannelLatestMediaSearch request, CancellationToken cancellationToken) + { + var result = await GetChannelItems(new InternalChannelItemQuery(), i => true, cancellationToken).ConfigureAwait(false); + + return result.Items.OrderByDescending(i => i.DateCreated ?? DateTime.MinValue); + } + + public Task GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(query.FolderId)) + { + return GetRecordingGroups(query, cancellationToken); + } + + if (query.FolderId.StartsWith("series_", StringComparison.OrdinalIgnoreCase)) + { + var hash = query.FolderId.Split('_')[1]; + return GetChannelItems(query, i => i.IsSeries && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken); + } + + if (string.Equals(query.FolderId, "kids", StringComparison.OrdinalIgnoreCase)) + { + return GetChannelItems(query, i => i.IsKids, cancellationToken); + } + + if (string.Equals(query.FolderId, "movies", StringComparison.OrdinalIgnoreCase)) + { + return GetChannelItems(query, i => i.IsMovie, cancellationToken); + } + + if (string.Equals(query.FolderId, "news", StringComparison.OrdinalIgnoreCase)) + { + return GetChannelItems(query, i => i.IsNews, cancellationToken); + } + + if (string.Equals(query.FolderId, "sports", StringComparison.OrdinalIgnoreCase)) + { + return GetChannelItems(query, i => i.IsSports, cancellationToken); + } + + if (string.Equals(query.FolderId, "others", StringComparison.OrdinalIgnoreCase)) + { + return GetChannelItems(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken); + } + + var result = new ChannelItemResult() + { + Items = new List() + }; + + return Task.FromResult(result); + } + + public async Task GetChannelItems(InternalChannelItemQuery query, Func filter, CancellationToken cancellationToken) + { + var service = GetService(); + var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false); + + var result = new ChannelItemResult() + { + Items = new List() + }; + + result.Items.AddRange(allRecordings.Where(filter).Select(ConvertToChannelItem)); + + return result; + } + + private ChannelItemInfo ConvertToChannelItem(MyRecordingInfo item) + { + var channelItem = new ChannelItemInfo + { + Name = string.IsNullOrEmpty(item.EpisodeTitle) ? item.Name : item.EpisodeTitle, + SeriesName = !string.IsNullOrEmpty(item.EpisodeTitle) || item.IsSeries ? item.Name : null, + OfficialRating = item.OfficialRating, + CommunityRating = item.CommunityRating, + ContentType = item.IsMovie ? ChannelMediaContentType.Movie : (item.IsSeries ? ChannelMediaContentType.Episode : ChannelMediaContentType.Clip), + Genres = item.Genres, + ImageUrl = item.ImageUrl, + //HomePageUrl = item.HomePageUrl + Id = item.Id, + //IndexNumber = item.IndexNumber, + MediaType = item.ChannelType == Model.LiveTv.ChannelType.TV ? ChannelMediaType.Video : ChannelMediaType.Audio, + MediaSources = new List + { + new MediaSourceInfo + { + Path = item.Path, + Protocol = item.Path.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? MediaProtocol.Http : MediaProtocol.File, + Id = item.Id + } + }, + //ParentIndexNumber = item.ParentIndexNumber, + PremiereDate = item.OriginalAirDate, + //ProductionYear = item.ProductionYear, + //Studios = item.Studios, + Type = ChannelItemType.Media, + DateModified = item.DateLastUpdated, + Overview = item.Overview, + //People = item.People + EnableMediaProbe = true, + IsLiveStream = item.Status == Model.LiveTv.RecordingStatus.InProgress, + Etag = item.Status.ToString() + }; + + return channelItem; + } + + private async Task GetRecordingGroups(InternalChannelItemQuery query, CancellationToken cancellationToken) + { + var service = GetService(); + + var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false); + var result = new ChannelItemResult() + { + Items = new List() + }; + + var series = allRecordings + .Where(i => i.IsSeries) + .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase); + + result.Items.AddRange(series.OrderBy(i => i.Key).Select(i => new ChannelItemInfo + { + Name = i.Key, + FolderType = ChannelFolderType.Container, + Id = "series_" + i.Key.GetMD5().ToString("N"), + Type = ChannelItemType.Folder, + ImageUrl = i.First().ImageUrl + })); + + var kids = allRecordings.FirstOrDefault(i => i.IsKids); + + if (kids != null) + { + result.Items.Add(new ChannelItemInfo + { + Name = "Kids", + FolderType = ChannelFolderType.Container, + Id = "kids", + Type = ChannelItemType.Folder, + ImageUrl = kids.ImageUrl + }); + } + + var movies = allRecordings.FirstOrDefault(i => i.IsMovie); + if (movies != null) + { + result.Items.Add(new ChannelItemInfo + { + Name = "Movies", + FolderType = ChannelFolderType.Container, + Id = "movies", + Type = ChannelItemType.Folder, + ImageUrl = movies.ImageUrl + }); + } + + var news = allRecordings.FirstOrDefault(i => i.IsNews); + if (news != null) + { + result.Items.Add(new ChannelItemInfo + { + Name = "News", + FolderType = ChannelFolderType.Container, + Id = "news", + Type = ChannelItemType.Folder, + ImageUrl = news.ImageUrl + }); + } + + var sports = allRecordings.FirstOrDefault(i => i.IsSports); + if (sports != null) + { + result.Items.Add(new ChannelItemInfo + { + Name = "Sports", + FolderType = ChannelFolderType.Container, + Id = "sports", + Type = ChannelItemType.Folder, + ImageUrl = sports.ImageUrl + }); + } + + var other = allRecordings.FirstOrDefault(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries); + if (other != null) + { + result.Items.Add(new ChannelItemInfo + { + Name = "Others", + FolderType = ChannelFolderType.Container, + Id = "others", + Type = ChannelItemType.Folder, + ImageUrl = other.ImageUrl + }); + } + + return result; + } + } + +}