Esempio n. 1
0
 /// <summary>
 /// Henter alle channel typene vi bruker som start side da man åpner pluginet
 /// gir en søt liten oversikt over ting som man kanskje vil søke opp
 /// </summary>
 /// <returns><see cref="ChannelItemResult"/> containing the types of categories.</returns>
 public static async Task <ChannelItemResult> GetChannelCategoriesAsync(ILogger logger, IMemoryCache memoryCache)
 {
     if (memoryCache.TryGetValue("nrk-categories", out ChannelItemResult cachedValue))
     {
         logger.LogInformation("Function={function} FolderId={folderId} Cache Hit", nameof(GetChannelCategoriesAsync), "nrk-categories");
         return(cachedValue);
     }
     else
     {
         logger.LogInformation("Function={function} FolderId={folderId} web download", nameof(GetChannelCategoriesAsync), "nrk-categories");
         HttpClient        httpClient = new HttpClient();
         string            json       = new StreamReader(await httpClient.GetStreamAsync("https://psapi.nrk.no/tv/pages")).ReadToEnd();
         var               root       = Newtonsoft.Json.JsonConvert.DeserializeObject <Categories.root>(json);
         ChannelItemResult result     = new ChannelItemResult();
         foreach (var v in root.PageListItems)
         {
             result.Items.Add(new ChannelItemInfo
             {
                 Id          = "https://psapi.nrk.no/tv/pages/" + v.Id,
                 Name        = v.Title,
                 FolderType  = ChannelFolderType.Container,
                 Type        = ChannelItemType.Folder,
                 MediaType   = ChannelMediaType.Video,
                 HomePageUrl = "https://tv.nrk.no" + v.Links.Self.Href,
                 ImageUrl    = v.Image.WebImages[0].Uri ?? v.Image.WebImages[1].Uri ?? v.Image.WebImages[2].Uri ?? v.Image.WebImages[3].Uri ?? v.Image.WebImages[4].Uri
             });
             result.TotalRecordCount++;
         }
         memoryCache.Set("nrk-categories", result, DateTimeOffset.Now.AddDays(7));
         return(result);
     }
 }
Esempio n. 2
0
        public async Task <ChannelItemResult> FindMatches(string eventId, string dayId, CancellationToken cancellationToken)
        {
            var days = await _lolEventVodsService.GetEventDays(eventId, cancellationToken);

            var day = days.FirstOrDefault(d => d.DayId == dayId);

            if (day == null)
            {
                _logger.Warn("DayId \"{0}\" couldn't be found in EventId \"{1}\"", dayId, eventId);
                return(new ChannelItemResult());
            }

            var result = new ChannelItemResult {
                Items = new List <ChannelItemInfo>()
            };

            if (day.FullStream != null)
            {
                result.Items.Add(CreateChannelItemVideo(day));
            }
            result.Items.AddRange(day.Matches
                                  .Select(match => CreateChannelItemFolders(eventId, dayId, match)));
            result.TotalRecordCount = result.Items.Count;
            return(result);
        }
Esempio n. 3
0
        private async Task <ChannelItemResult> GetCategories()
        {
            if (memoryCache.TryGetValue("pornhub-categories", out ChannelItemResult o))
            {
                return(o);
            }
            HttpClient httpClient = new HttpClient();
            string     json       = await httpClient.GetStringAsync("https://www.pornhub.com/webmasters/categories");

            var results = JsonConvert.DeserializeObject <CategoryResults.root>(json);
            ChannelItemResult result = new ChannelItemResult();

            foreach (var category in results.Categories)
            {
                result.Items.Add(new ChannelItemInfo()
                {
                    Id   = category.category,
                    Name = category.category,
                    Type = ChannelItemType.Folder,
                });
                result.TotalRecordCount++;
            }
            memoryCache.Set("pornhub-categories", result, DateTimeOffset.Now.AddDays(7));
            return(result);
        }
Esempio n. 4
0
        private async Task <ChannelItemResult> GetRecordingSeasonGroups(InternalChannelItemQuery query, Func <MyRecordingInfo, bool> filter, CancellationToken cancellationToken)
        {
            var service = GetService();

            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>(),
            };

            var season = allRecordings.Where(filter)
                         .GroupBy(i => i.SeasonNumber, i => i.Name, (key, g) => new { SeasonNumber = key, Name = g.ToList() });

            result.Items.AddRange(season.OrderBy(i => i.SeasonNumber).Select(i => new ChannelItemInfo
            {
                Name              = "Season " + i.SeasonNumber,
                FolderType        = ChannelFolderType.Container,
                Id                = "season_" + i.SeasonNumber.ToString().GetMD5().ToString("N") + "_" + i.Name.First().ToString(),
                Type              = ChannelItemType.Folder,
                ParentIndexNumber = i.SeasonNumber,
            }));

            result.Items.OrderBy(i => i.Name);

            return(result);
        }
Esempio n. 5
0
        private async Task <ChannelItemResult> GetRecordingNameGroups(InternalChannelItemQuery query, Func <MyRecordingInfo, bool> filter, CancellationToken cancellationToken)
        {
            var pluginPath = Plugin.Instance.ConfigurationFilePath.Remove(Plugin.Instance.ConfigurationFilePath.Length - 4);
            var service    = GetService();

            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>(),
            };

            var doublenames = allRecordings.Where(filter)
                              .GroupBy(i => i.Name).Where(i => i.Count() > 1).Select(i => i.Key)
                              .ToLookup(i => i, StringComparer.OrdinalIgnoreCase);

            result.Items.AddRange(doublenames.OrderBy(i => i.Key).Select(i => new ChannelItemInfo
            {
                Name       = i.Key,
                FolderType = ChannelFolderType.Container,
                Id         = "name_" + i.Key.GetMD5().ToString("N"),
                Type       = ChannelItemType.Folder,
                ImageUrl   = File.Exists(Path.Combine(pluginPath, "recordingposters", String.Join("", i.Key.Split(Path.GetInvalidFileNameChars())) + ".jpg")) ?
                             Path.Combine(pluginPath, "recordingposters", String.Join("", i.Key.Split(Path.GetInvalidFileNameChars())) + ".jpg") : String.Empty,
            }));

            var singlenames = allRecordings.Where(filter)
                              .GroupBy(i => i.Name).Where(c => c.Count() == 1).Select(g => g.First());

            result.Items.AddRange(singlenames.Select(ConvertToChannelItem));

            result.Items.OrderBy(i => i.Name);

            return(result);
        }
        private async Task <ChannelItemResult> GetRecordingSeriesGroups(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            var pluginPath = Plugin.Instance.ConfigurationFilePath.Remove(Plugin.Instance.ConfigurationFilePath.Length - 4);
            var service    = GetService();

            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>(),
            };

            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,
                SeriesName   = i.Key,
                Id           = "series_" + i.Key.GetMD5().ToString("N"),
                Type         = ChannelItemType.Folder,
                FolderType   = ChannelFolderType.Container,
                DateModified = allRecordings.Where(r => r.Name.Equals(i.Key)).OrderByDescending(d => d.StartDate).Select(d => d.StartDate).FirstOrDefault(),
                ImageUrl     = File.Exists(Path.Combine(pluginPath, "recordingposters", String.Join("", i.Key.Split(Path.GetInvalidFileNameChars())) + ".jpg")) ?
                               Path.Combine(pluginPath, "recordingposters", String.Join("", i.Key.Split(Path.GetInvalidFileNameChars())) + ".jpg") : String.Empty,
            }));

            return(result);
        }
Esempio n. 7
0
        public static async Task <ChannelItemResult> GetSeasonInfoAsync(InternalChannelItemQuery query, ILogger logger, IMemoryCache memoryCache)
        {
            if (memoryCache.TryGetValue("nrk-categories-seasoninfo-" + query.FolderId, out ChannelItemResult cachedValue))
            {
                logger.LogInformation("Function={function} FolderId={folderId} Cache Hit", nameof(GetSeasonInfoAsync), "nrk-categories-seasoninfo-" + query.FolderId);
                return(cachedValue);
            }
            else
            {
                logger.LogInformation("Function={function} FolderId={folderId} web download", nameof(GetSeasonInfoAsync), "nrk-categories-seasoninfo-" + query.FolderId);
                HttpClient        httpClient = new HttpClient();
                string            json       = new StreamReader(await httpClient.GetStreamAsync(query.FolderId)).ReadToEnd();
                var               root       = Newtonsoft.Json.JsonConvert.DeserializeObject <SeasonInfo.root>(json);
                ChannelItemResult result     = new ChannelItemResult();

                foreach (var emb in root.Embedded.Seasons)
                {
                    ChannelItemInfo info = new ChannelItemInfo()
                    {
                        FolderType  = ChannelFolderType.Container,
                        SeriesName  = root.Sequential.Titles.Title,
                        Name        = emb.Titles.Title,
                        Overview    = root.Sequential.Titles.Subtitle,
                        HomePageUrl = "https://tv.nrk.no" + emb.Links.Series.Href,
                        Id          = "https://psapi.nrk.no" + emb.Links.Self.Href,
                        MediaType   = ChannelMediaType.Video,
                        Type        = ChannelItemType.Folder
                    };
                    result.Items.Add(info);
                    result.TotalRecordCount++;
                }
                memoryCache.Set("nrk-categories-seasoninfo-" + query.FolderId, result, DateTimeOffset.Now.AddDays(7));
                return(result);
            }
        }
        public async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>()
            };

            result.Items.AddRange(DataGenerator.GetChannelItemInfos());
            return(result);
        }
        public async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, Func <MyRecordingInfo, bool> filter, CancellationToken cancellationToken)
        {
            var service       = GetService();
            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult
            {
                Items = allRecordings.Where(filter).Select(info => ConvertToChannelItem(info)).ToList()
            };

            return(result);
        }
Esempio n. 10
0
        private void CacheResponse(ChannelItemResult result, string path)
        {
            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));

                _jsonSerializer.SerializeToFile(result, path);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error writing to channel cache file: {0}", ex, path);
            }
        }
        private async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, Func <MyRecordingInfo, bool> filter, CancellationToken cancellationToken)
        {
            var service       = GetService();
            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>()
            };

            result.Items.AddRange(allRecordings.Where(filter).Select(ConvertToChannelItem));

            return(result);
        }
Esempio n. 12
0
        public async Task <ChannelItemResult> FindEvents(int limit, int offset, CancellationToken cancellationToken)
        {
            var events = await GetEvents(limit, offset, cancellationToken);

            var result = new ChannelItemResult
            {
                Items = events.Items
                        .Where(evt => evt.Status != EventStatus.None)
                        .Select(CreateChannelItemFolders)
                        .ToList()
            };

            result.TotalRecordCount = SetTotalRecordCount(limit, offset, result.Items.Count, events.After);
            return(result);
        }
        public async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            ChannelItemResult result = null;

            _logger.Debug("cat ID : " + query.FolderId);

            if (query.FolderId == null)
            {
                result = await GetChannelsInternal(query, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                result = await GetChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
            }

            return(result);
        }
    public Task <ChannelItemResult> 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 <ChannelItemInfo>()
        };

        return(Task.FromResult(result));
    }
Esempio n. 15
0
        private async Task <ChannelItemResult> GetVideos(string CategoryName)
        {
            if (memoryCache.TryGetValue("pornhub-" + CategoryName, out ChannelItemResult o))
            {
                return(o);
            }
            HttpClient        httpClient = new HttpClient();
            ChannelItemResult result     = new ChannelItemResult();

            for (int i = 1; 10 >= i; i++)
            {
                string json    = new WebClient().DownloadString("https://www.pornhub.com/webmasters/search?q=&category=" + CategoryName + "&ordering=newest&thumbsize=large&page=" + i.ToString());
                var    results = JsonConvert.DeserializeObject <SearchResult.root>(json);
                foreach (var video in results.Videos)
                {
                    result.Items.Add(new ChannelItemInfo()
                    {
                        CommunityRating = float.Parse(video.Rating.ToString()),
                        DateCreated     = Convert.ToDateTime(video.PublishDate),
                        ContentType     = ChannelMediaContentType.Clip,
                        Name            = video.Title,
                        ImageUrl        = video.DefaultThumb,
                        FolderType      = ChannelFolderType.Container,
                        Type            = ChannelItemType.Media,
                        MediaType       = ChannelMediaType.Video,
                        HomePageUrl     = video.Url,
                        OfficialRating  = video.Ratings.ToString(),
                        OriginalTitle   = video.Title,
                        Id = video.VideoId
                    });
                    result.TotalRecordCount++;
                }
            }

            memoryCache.Set("pornhub-" + CategoryName, result, DateTimeOffset.Now.AddHours(6));

            return(result);
        }
    public async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, Func <MyRecordingInfo, bool> filter, CancellationToken cancellationToken)
    {
        var service = GetService();

        if (_useCachedRecordings == false)
        {
            _allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            await service.GetChannelsAsync(cancellationToken).ConfigureAwait(false);

            _useCachedRecordings = true;
        }

        List <ChannelItemInfo> pluginItems = new List <ChannelItemInfo>();

        pluginItems.AddRange(_allRecordings.Where(filter).Select(ConvertToChannelItem));
        var result = new ChannelItemResult()
        {
            Items = pluginItems
        };

        return(result);
    }
Esempio n. 17
0
        public async Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            _logger.Debug("In GetChannelItems");
            if (Plugin.Instance.Configuration.AppID == "app-id-goes-here" || Plugin.Instance.Configuration.AppKey == "app-key-goes-here")
            {
                _logger.Warn("The Application has not been set up correctly in the configuration screen.");
                _logger.Info("Cannot populate channel data due to configuration issue.");
                ChannelItemResult channelItemResult = new ChannelItemResult();
                channelItemResult.Items            = new List <ChannelItemInfo>();
                channelItemResult.TotalRecordCount = 0;
                return(channelItemResult);
            }

            var downloader = new TwitNetworkDownloader(_logger, _jsonSerializer, _httpClient);
            var cacheOk    = await downloader.PopulateNetworkCache(
                _twitNetworkCache,
                Plugin.Instance.Configuration.LimitCollectionInDays,
                Plugin.Instance.Configuration.LimitRequestsPerMinute,
                cancellationToken).ConfigureAwait(false);

            _logger.Debug("Downloader cache result: {0}", cacheOk);

            ChannelItemResult result;

            _logger.Debug("Show ID: " + query.FolderId);

            if (query.FolderId == null)
            {
                result = ParseChannelsInternal(query);
            }
            else
            {
                result = ParseChannelItemsInternal(query);
            }

            return(result);
        }
Esempio n. 18
0
        private async Task <ChannelItemResult> GetRecordingGroups(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            var service = GetService();

            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>()
            };

            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);
        }
Esempio n. 19
0
        private async Task <ChannelItemResult> GetRecordingGroups(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            var service = GetService();

            var allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>(),
            };

            //var latest = allRecordings.OrderByDescending(i => i.StartDate).Take(10);
            //if (latest != null)
            //{
            //    result.Items.AddRange(latest.Select(ConvertToChannelItem));
            //}

            var series = allRecordings.FirstOrDefault(i => i.IsSeries);

            if (series != null)
            {
                result.Items.Add(new ChannelItemInfo
                {
                    Name       = "TV Shows",
                    FolderType = ChannelFolderType.Container,
                    Id         = "tvshows",
                    Type       = ChannelItemType.Folder,
                    ImageUrl   = ChannelFolderImage("TV Shows")
                });
            }

            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   = ChannelFolderImage("Movies")
                });
            }

            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   = ChannelFolderImage("Kids")
                });
            }

            var news = allRecordings.FirstOrDefault(i => i.IsNews);

            if (news != null)
            {
                result.Items.Add(new ChannelItemInfo
                {
                    Name       = "News & Documentary",
                    FolderType = ChannelFolderType.Container,
                    Id         = "news",
                    Type       = ChannelItemType.Folder,
                    ImageUrl   = ChannelFolderImage("News & Documentary")
                });
            }

            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   = ChannelFolderImage("Sports")
                });
            }

            var live = allRecordings.FirstOrDefault(i => i.IsLive);

            if (live != null)
            {
                result.Items.Add(new ChannelItemInfo
                {
                    Name       = "Live Shows",
                    FolderType = ChannelFolderType.Container,
                    Id         = "live",
                    Type       = ChannelItemType.Folder,
                    ImageUrl   = ChannelFolderImage("Live Shows")
                });
            }

            var other = allRecordings.FirstOrDefault(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries);

            if (other != null && result.Items.Count > 0)
            {
                result.Items.Add(new ChannelItemInfo
                {
                    Name       = "Other Shows",
                    FolderType = ChannelFolderType.Container,
                    Id         = "others",
                    Type       = ChannelItemType.Folder,
                    ImageUrl   = ChannelFolderImage("Other Shows")
                });
            }

            return(result);
        }
Esempio n. 20
0
        public Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(query.FolderId))
            {
                var recordingGroups = GetRecordingGroups(query, cancellationToken);

                if (recordingGroups.Result.Items.Count == 0)
                {
                    return(GetRecordingNameGroups(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken));
                }

                return(recordingGroups);
            }

            if (string.Equals(query.FolderId, "tvshows", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingSeriesGroups(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));
            }

            //// Optional Season Folders ////
            //if (query.FolderId.StartsWith("series_", StringComparison.OrdinalIgnoreCase))
            //{
            //    var hash = query.FolderId.Split('_')[1];
            //    return GetRecordingSeasonGroups(query, i => i.IsSeries && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken);
            //}

            //if (query.FolderId.StartsWith("season_", StringComparison.OrdinalIgnoreCase))
            //{
            //    Plugin.Logger.Info("QUERY FOLDER ID SEASON: {0}", query.FolderId);
            //    var name = query.FolderId.Split('_')[2];
            //    var hash = query.FolderId.Split('_')[1];

            //    var output = GetChannelItems(query, i => i.IsSeries && string.Equals(i.Name, name) && string.Equals(i.SeasonNumber.ToString().GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken);
            //    foreach (var item in output.Result.Items)
            //    {
            //        Plugin.Logger.Info("CHANNEL Name {0}; Episode {1}", item.SeriesName, item.Name);
            //    }

            //    return output;
            //}

            if (string.Equals(query.FolderId, "movies", StringComparison.OrdinalIgnoreCase))
            {
                return(GetChannelItems(query, i => i.IsMovie, cancellationToken));
            }

            if (string.Equals(query.FolderId, "kids", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsKids, cancellationToken));
            }

            if (string.Equals(query.FolderId, "news", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsNews, cancellationToken));
            }

            if (string.Equals(query.FolderId, "sports", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsSports, cancellationToken));
            }

            if (string.Equals(query.FolderId, "live", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsLive, cancellationToken));
            }

            if (string.Equals(query.FolderId, "others", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken));
            }

            if (query.FolderId.StartsWith("name_", StringComparison.OrdinalIgnoreCase))
            {
                var hash = query.FolderId.Split('_')[1];
                return(GetChannelItems(query, i => i.Name != null && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken));
            }

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>()
            };

            return(Task.FromResult(result));
        }
Esempio n. 21
0
        private async Task <ChannelItemResult> GetChannelItemsInternal(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            List <ChannelItemInfo> items = new List <ChannelItemInfo>();

            foreach (TwitchChannel i in Plugin.Instance.Configuration.TwitchChannels)
            {
                ChannelMetadata channelMetadata = null;

                if (String.IsNullOrWhiteSpace(i.ChannelId))
                {
                    // get user id
                    UserMetadata userMetadata = await GetMetadataFromTwitchUserAsync(i.UserName);

                    if (userMetadata?.Users.Length > 0)
                    {
                        i.ChannelId = userMetadata.Users[0]._id.ToString();
                    }
                    else
                    {
                        i.ChannelId = string.Empty;
                    }

                    Plugin.Instance.SaveConfiguration(); // keep user id in db
                }

                if (!String.IsNullOrWhiteSpace(i.ChannelId))
                {
                    channelMetadata = await GetMetadataFromTwitchChannelAsync(i.ChannelId);
                }

                string imageUrl = String.Empty;
                string overview = "No description";

                if (channelMetadata != null)
                {
                    overview = channelMetadata.description;

                    if (!string.IsNullOrWhiteSpace(channelMetadata.profile_banner))
                    {
                        imageUrl = channelMetadata.profile_banner;
                    }

                    if (string.IsNullOrWhiteSpace(imageUrl) && !string.IsNullOrWhiteSpace(channelMetadata.video_banner)) // Profile banner has priority
                    {
                        imageUrl = channelMetadata.video_banner;
                    }
                }

                items.Add(new ChannelItemInfo
                {
                    ContentType  = ChannelMediaContentType.Clip,
                    ImageUrl     = imageUrl,
                    IsLiveStream = true,
                    MediaType    = ChannelMediaType.Video,
                    MediaSources = (List <MediaSourceInfo>) await GetMediaSources(i.UserName, cancellationToken),
                    Name         = i.Name,
                    Id           = i.UserName.ToLowerInvariant(),
                    ExtraType    = ExtraType.Clip,
                    HomePageUrl  = channelMetadata.url ?? $"https://twitch.tv/{i.UserName.ToLowerInvariant()}",
                    Overview     = overview,
                    Type         = ChannelItemType.Media,
                    DateModified = DateTime.Now,
                    DateCreated  = DateTime.Now
                });

                _logger.Debug($"[TWITCH.TV] {i.UserName} channel added to list");
            }

            ChannelItemResult channelItemResult = new ChannelItemResult
            {
                Items            = items,
                TotalRecordCount = items.Count
            };

            return(await Task.FromResult(channelItemResult));
        }
Esempio n. 22
0
        public static async Task <ChannelItemResult> GetCategoryItemsAsync(InternalChannelItemQuery query, ILogger logger, IMemoryCache memoryCache)
        {
            if (memoryCache.TryGetValue("nrk-categories-" + query.FolderId, out ChannelItemResult cachedValue))
            {
                logger.LogInformation("Function={function} FolderId={folderId} Cache Hit", nameof(GetCategoryItemsAsync), query.FolderId);
                return(cachedValue);
            }
            else
            {
                logger.LogInformation("Function={function} FolderId={folderId} web download", nameof(GetCategoryItemsAsync), query.FolderId);
                HttpClient        httpClient = new HttpClient();
                string            json       = new StreamReader(await httpClient.GetStreamAsync(query.FolderId)).ReadToEnd();
                var               root       = Newtonsoft.Json.JsonConvert.DeserializeObject <CategoryItems.root>(json);
                ChannelItemResult result     = new ChannelItemResult();
                foreach (var v in root.Sections)
                {
                    foreach (var p in v.Included.Plugs)
                    {
                        try

                        {
                            string mainurl = string.Empty;
                            if (p.TargetType == "series")
                            {
                                result.Items.Add(new ChannelItemInfo
                                {
                                    Id          = "https://psapi.nrk.no/tv/catalog" + p.Series.Links.Self.Href,
                                    Name        = p.DisplayContractContent.ContentTitle,
                                    ImageUrl    = p.DisplayContractContent.DisplayContractImage.WebImages[0].Uri ?? p.DisplayContractContent.DisplayContractImage.WebImages[1].Uri,
                                    FolderType  = ChannelFolderType.Container,
                                    Type        = ChannelItemType.Folder,
                                    SeriesName  = p.DisplayContractContent.ContentTitle,
                                    MediaType   = ChannelMediaType.Video,
                                    HomePageUrl = "htps://tv.nrk.no" + p.Series.Links.Self.Href,
                                    Overview    = p.DisplayContractContent.Description,
                                });
                                result.TotalRecordCount++;
                            }
                            else if (p.TargetType == "standaloneProgram")
                            {
                                result.Items.Add(new ChannelItemInfo
                                {
                                    Id          = "https://psapi.nrk.no" + p.StandaloneProgram.Links.Playback.Href,
                                    Name        = p.DisplayContractContent.ContentTitle,
                                    ImageUrl    = p.DisplayContractContent.DisplayContractImage.WebImages[0].Uri ?? p.DisplayContractContent.DisplayContractImage.WebImages[1].Uri,
                                    FolderType  = ChannelFolderType.Container,
                                    Type        = ChannelItemType.Media,
                                    Overview    = p.DisplayContractContent.Description,
                                    MediaType   = ChannelMediaType.Video,
                                    HomePageUrl = "htps://tv.nrk.no" + p.StandaloneProgram.Links.Self.Href,
                                });
                                result.TotalRecordCount++;
                            }
                            else if (p.TargetType == "episode")
                            {
                                result.Items.Add(new ChannelItemInfo
                                {
                                    Id          = "https://psapi.nrk.no" + p.Episode.Links.Playback.Href,
                                    Name        = p.DisplayContractContent.ContentTitle,
                                    ImageUrl    = p.DisplayContractContent.DisplayContractImage.WebImages[0].Uri ?? p.DisplayContractContent.DisplayContractImage.WebImages[1].Uri ?? p.DisplayContractContent.FallbackImage.WebImages[0].Uri,
                                    FolderType  = ChannelFolderType.Container,
                                    Type        = ChannelItemType.Media,
                                    Overview    = p.DisplayContractContent.Description,
                                    MediaType   = ChannelMediaType.Video,
                                    HomePageUrl = "htps://tv.nrk.no" + p.Episode.Links.Self.Href,
                                });
                                result.TotalRecordCount++;
                            }
                        }
                        catch (Exception e)
                        {
                            logger.LogError("Error trying to parse all category items from the nrk web tv channel");
                            logger.LogError(e.Message);
                        }
                    }
                }
                memoryCache.Set("nrk-categories-" + query.FolderId, result, DateTimeOffset.Now.AddDays(7));
                return(result);
            }
        }
Esempio n. 23
0
        public async Task <ChannelItemResult> GetChannelItems(
            InternalChannelItemQuery query,
            CancellationToken cancellationToken)
        {
            this._logger.Info("GetChannelItems");

            var result = new ChannelItemResult {
                Items = new List <ChannelItemInfo>()
            };

            try
            {
                var databaseFileName = "/config/data/smart-inbox-recommendations.db";
                if (File.Exists(databaseFileName))
                {
                    var baseItem           = this._libraryManager.RootFolder.GetRecursiveChildren()[1];
                    var internalItemsQuery = new InternalItemsQuery {
                        MediaTypes = new[] { MediaType.Video }
                    };

                    var moviesEnumeration             = this._libraryManager.GetItemList(internalItemsQuery, new[] { baseItem }).OfType <Movie>();
                    Dictionary <string, Movie> movies = new Dictionary <string, Movie>();
                    foreach (var movie in moviesEnumeration)
                    {
                        var key = string.Empty;
                        foreach (var currentItemProviderId in movie.ProviderIds.OrderBy(pair => pair.Key))
                        {
                            key += currentItemProviderId.Key + "=" + currentItemProviderId.Value + "|";
                        }

                        key = key.TrimEnd('|');

                        if (!string.IsNullOrEmpty(key) && !movies.TryGetValue(key, out _))
                        {
                            movies[key] = movie;
                        }
                    }

                    var sqLiteConnection    = new SQLiteConnection(new SQLitePlatformGeneric(), databaseFileName);
                    var sqLiteCommand       = sqLiteConnection.CreateCommand(@"SELECT * FROM [Recommendations] WHERE [Recommendation] = 1");
                    var sqLiteCommandResult = sqLiteCommand.ExecuteDeferredQuery();

                    foreach (var dataTableRow in sqLiteCommandResult.Data)
                    {
                        var id = (string)dataTableRow["Id"];
                        this._logger.Info($"Processing recommendation {id}");
                        if (movies.TryGetValue(id, out var currentItem))
                        {
                            this._logger.Info($"Found recommendation {id}");
                            var channelItemInfo = new ChannelItemInfo
                            {
                                Id           = currentItem.Id.ToString(),
                                ProviderIds  = currentItem.ProviderIds,
                                Type         = ChannelItemType.Media,
                                MediaSources =
                                    new List <MediaSourceInfo>
                                {
                                    new MediaSourceInfo
                                    {
                                        Path     = currentItem.Path,
                                        Protocol = MediaProtocol.File
                                    }
                                },
                                ContentType     = ChannelMediaContentType.Movie,
                                MediaType       = ChannelMediaType.Video,
                                Name            = currentItem.Name,
                                CommunityRating = currentItem.CommunityRating,
                                ImageUrl        = currentItem.PrimaryImagePath,
                                OriginalTitle   = currentItem.OriginalTitle
                            };
                            result.Items.Add(channelItemInfo);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                this._logger.ErrorException("Error updating channel content", e);
            }

            return(result);
        }
Esempio n. 24
0
        public async Task <ChannelItemResult> GetItems(bool inChannel, InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var config = await BlurNTasks.CheckIfResetDatabaseRequested(cancellationToken, _json, _appPaths, _fileSystem).ConfigureAwait(false);

            if (inChannel)
            {
                Plugin.DebugLogger("Entered BlurN channel list");
            }

            User user = query.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(query.UserId);

            Dictionary <string, BaseItem> libDict = (user == null) ? new Dictionary <string, BaseItem>() : Library.BuildLibraryDictionary(cancellationToken, _libraryManager, new InternalItemsQuery()
            {
                HasAnyProviderId = new[] { "Imdb" },
                User             = user,
                //SourceTypes = new SourceType[] { SourceType.Library }
            });

            Plugin.DebugLogger($"Found {libDict.Count} items in movies library");

            BlurNItems items    = new BlurNItems();
            string     dataPath = Path.Combine(_appPaths.PluginConfigurationsPath, "MediaBrowser.Channels.BlurN.Data.json");

            if (_fileSystem.FileExists(dataPath))
            {
                items.List = _json.DeserializeFromFile <List <BlurNItem> >(dataPath);
            }

            if (inChannel)
            {
                Plugin.DebugLogger("Retrieved items");
            }

            if (items == null)
            {
                if (inChannel)
                {
                    Plugin.DebugLogger("Items is null, set to new list");
                }
                items = new BlurNItems();
                Plugin.Instance.SaveConfiguration();
            }

            for (int i = 0; i < items.List.Count; i++)
            {
                BlurNItem blurNItem = items.List[i];

                BaseItem libraryItem;
                bool     foundInLibrary = libDict.TryGetValue(blurNItem.ImdbId, out libraryItem);
                if (foundInLibrary)
                {
                    if (config.HidePlayedMovies && user != null && libraryItem.IsPlayed(user))
                    {
                        items.List.RemoveAt(i);
                        i--;
                        if (inChannel)
                        {
                            Plugin.DebugLogger($"Hiding movie '{blurNItem.Title}' from BlurN channel list as watched by user");
                        }
                    }
                    else if (!config.AddItemsAlreadyInLibrary)
                    {
                        items.List.RemoveAt(i);
                        i--;
                        if (inChannel)
                        {
                            Plugin.DebugLogger($"Hiding movie '{blurNItem.Title}' from BlurN channel list as availabile in library");
                        }
                    }
                    else
                    {
                        blurNItem.LibraryItem = libraryItem;
                    }
                }
            }

            switch (query.SortBy)
            {
            case ChannelItemSortField.Name:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.Title);
                }
                else
                {
                    items.List.OrderBy(i => i.Title);
                }
                break;

            case ChannelItemSortField.DateCreated:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.BluRayReleaseDate);
                }
                else
                {
                    items.List.OrderBy(i => i.BluRayReleaseDate);
                }
                break;

            case ChannelItemSortField.CommunityRating:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.ImdbRating).ThenByDescending(i => i.ImdbVotes);
                }
                else
                {
                    items.List.OrderBy(i => i.ImdbRating).ThenBy(i => i.ImdbVotes);
                }
                break;

            case ChannelItemSortField.PremiereDate:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.Released);
                }
                else
                {
                    items.List.OrderBy(i => i.Released);
                }
                break;

            case ChannelItemSortField.Runtime:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.RuntimeTicks);
                }
                else
                {
                    items.List.OrderBy(i => i.RuntimeTicks);
                }
                break;

            default:
                if (query.SortDescending)
                {
                    items.List.Reverse();
                }
                break;
            }

            BlurNItems showList = new BlurNItems();

            if (query.StartIndex.HasValue && query.Limit.HasValue && query.Limit.Value > 0)
            {
                int index = query.StartIndex.Value;
                int limit = query.Limit.Value;

                if (items.List.Count < index + limit)
                {
                    limit = items.List.Count - index;
                }

                showList.List = items.List.GetRange(index, limit);
                if (inChannel)
                {
                    Plugin.DebugLogger($"Showing range with index {index} and limit {limit}");
                }
            }
            else
            {
                showList.List = items.List;
                if (inChannel)
                {
                    Plugin.DebugLogger("Showing full list");
                }
            }

            ChannelItemResult result = new ChannelItemResult()
            {
                TotalRecordCount = items.List.Count
            };

            for (int i = 0; i < showList.List.Count; i++)
            {
                BlurNItem blurNItem = showList.List[i];

                if (inChannel)
                {
                    Plugin.DebugLogger($"Showing movie '{blurNItem.Title}' to BlurN channel list");
                }

                var directors = CSVParse(blurNItem.Director);
                var writers   = CSVParse(blurNItem.Writer);
                var actors    = CSVParse(blurNItem.Actors);

                var people = new List <PersonInfo>();
                foreach (var director in directors)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = director, Role = "Director"
                    });
                }
                foreach (var writer in writers)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = writer, Role = "Writer"
                    });
                }
                foreach (string actor in actors)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = actor, Role = "Actor"
                    });
                }

                var genres = CSVParse(blurNItem.Genre).ToList();

                var cii = new ChannelItemInfo()
                {
                    Id              = $"{config.ChannelRefreshCount.ToString()}-{blurNItem.ImdbId}",
                    IndexNumber     = i,
                    CommunityRating = (float)blurNItem.ImdbRating,
                    ContentType     = ChannelMediaContentType.Movie,
                    DateCreated     = blurNItem.BluRayReleaseDate,
                    Genres          = genres,
                    ImageUrl        = (blurNItem.Poster == "N/A") ? null : blurNItem.Poster,
                    MediaType       = ChannelMediaType.Video,
                    Name            = blurNItem.Title,
                    OfficialRating  = (blurNItem.Rated == "N/A") ? null : blurNItem.Rated,
                    Overview        = (blurNItem.Plot == "N/A") ? null : blurNItem.Plot,
                    People          = people,
                    PremiereDate    = blurNItem.Released,
                    ProductionYear  = blurNItem.Released.Year,
                    RunTimeTicks    = blurNItem.RuntimeTicks,
                    Type            = ChannelItemType.Media,
                    DateModified    = blurNItem.BluRayReleaseDate,
                    IsLiveStream    = false
                };

                cii.SetProviderId(MetadataProviders.Imdb, blurNItem.ImdbId);
                if (blurNItem.TmdbId.HasValue)
                {
                    cii.SetProviderId(MetadataProviders.Tmdb, blurNItem.TmdbId.Value.ToString());
                }

                if (blurNItem.LibraryItem != null)
                {
                    var mediaStreams = _mediaSourceManager.GetMediaStreams(blurNItem.LibraryItem.InternalId).ToList();

                    var audioStream = mediaStreams.FirstOrDefault(ms => ms.Type == MediaStreamType.Audio && ms.IsDefault);
                    var videoStream = mediaStreams.FirstOrDefault(ms => ms.Type == MediaStreamType.Video && ms.IsDefault);

                    ChannelMediaInfo cmi = new ChannelMediaInfo()
                    {
                        Path               = _libraryManager.GetPathAfterNetworkSubstitution(blurNItem.LibraryItem.Path, blurNItem.LibraryItem),
                        Container          = blurNItem.LibraryItem.Container,
                        RunTimeTicks       = blurNItem.LibraryItem.RunTimeTicks,
                        SupportsDirectPlay = true,
                        Id       = blurNItem.LibraryItem.Id.ToString(),
                        Protocol = Model.MediaInfo.MediaProtocol.File
                    };

                    if (audioStream != null)
                    {
                        cmi.AudioBitrate    = audioStream.BitRate;
                        cmi.AudioChannels   = audioStream.Channels;
                        cmi.AudioCodec      = audioStream.Codec;
                        cmi.AudioSampleRate = audioStream.SampleRate;
                    }
                    if (videoStream != null)
                    {
                        cmi.Framerate    = videoStream.RealFrameRate;
                        cmi.Height       = videoStream.Height;
                        cmi.IsAnamorphic = videoStream.IsAnamorphic;
                        cmi.VideoBitrate = videoStream.BitRate;
                        cmi.VideoCodec   = videoStream.Codec;
                        if (videoStream.Level.HasValue)
                        {
                            cmi.VideoLevel = (float)videoStream.Level.Value;
                        }
                        cmi.VideoProfile = videoStream.Profile;
                        cmi.Width        = videoStream.Width;
                    }
                    Plugin.DebugLogger($"Linked movie {blurNItem.Title} to library. Path: {blurNItem.LibraryItem.Path}, Substituted Path: {cmi.Path}");
                    cii.MediaSources = new List <MediaSourceInfo>()
                    {
                        cmi.ToMediaSource()
                    };
                }

                result.Items.Add(cii);

                if (inChannel)
                {
                    Plugin.DebugLogger($"Added movie '{blurNItem.Title}' to BlurN channel list");
                }
            }

            if (inChannel)
            {
                Plugin.DebugLogger($"Set total record count ({(int)result.TotalRecordCount})");
            }

            return(result);
        }
    private async Task <ChannelItemResult> GetRecordingGroups(InternalChannelItemQuery query, CancellationToken cancellationToken)
    {
        List <ChannelItemInfo> pluginItems = new List <ChannelItemInfo>();
        var service = GetService();

        if (_useCachedRecordings == false)
        {
            _allRecordings = await service.GetAllRecordingsAsync(cancellationToken).ConfigureAwait(false);

            await service.GetChannelsAsync(cancellationToken).ConfigureAwait(false);

            _useCachedRecordings = true;
        }

        var series = _allRecordings
                     .Where(i => i.IsSeries)
                     .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase);

        pluginItems.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,
            DateCreated = i.Last().StartDate,
            ImageUrl    = i.Last().ImageUrl.Replace("=poster", "=landscape", StringComparison.OrdinalIgnoreCase)
        }));
        var kids = _allRecordings.FirstOrDefault(i => i.IsKids);

        if (kids != null)
        {
            pluginItems.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)
        {
            pluginItems.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)
        {
            pluginItems.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)
        {
            pluginItems.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)
        {
            pluginItems.Add(new ChannelItemInfo
            {
                Name       = "Others",
                FolderType = ChannelFolderType.Container,
                Id         = "others",
                Type       = ChannelItemType.Folder,
                ImageUrl   = other.ImageUrl
            });
        }

        var result = new ChannelItemResult()
        {
            Items = pluginItems
        };

        return(result);
    }
        //public async Task<IEnumerable<ChannelItemInfo>> GetLatestMedia(ChannelLatestMediaSearch request, CancellationToken cancellationToken)
        //{
        //    var result = await GetChannelItems(new InternalChannelItemQuery(), i => true, cancellationToken).ConfigureAwait(false);
        //    return result.Items.OrderByDescending(i => i.DateModified);
        //}

        public Task <ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(query.FolderId))
            {
                var recordingGroups = GetRecordingGroups(query, cancellationToken);

                if (recordingGroups.Result.Items.Count == 0)
                {
                    return(GetRecordingNameGroups(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken));
                }

                return(recordingGroups);
            }

            /// <summary>
            /// Optional Latest Folders
            /// </summary>
            ///
            /// if (string.Equals(query.FolderId, "latest", StringComparison.OrdinalIgnoreCase))
            /// {
            ///     var latestRecordings = GetChannelItems(query, i => true, cancellationToken).Result;
            ///
            ///     var latest = new ChannelItemResult()
            ///     {
            ///         Items = latestRecordings.Items.OrderByDescending(i => i.DateCreated).Take(25).ToList()
            ///     };
            ///
            ///     return Task.FromResult(latest);
            /// }

            if (string.Equals(query.FolderId, "tvshows", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingSeriesGroups(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 (query.FolderId.StartsWith("series_", StringComparison.OrdinalIgnoreCase))
            {
                var hash = query.FolderId.Split('_')[1];

                return(GetRecordingSeasonGroups(query, i => i.IsSeries && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken));
            }

            if (query.FolderId.Contains("_season_"))
            {
                var name = query.FolderId.Split('_')[0];
                var hash = query.FolderId.Split('_')[2];

                return(GetChannelItems(query, i => i.IsSeries && string.Equals(i.Name, name) && string.Equals(i.SeasonNumber.ToString().GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken));
            }

            if (string.Equals(query.FolderId, "movies", StringComparison.OrdinalIgnoreCase))
            {
                return(GetChannelItems(query, i => i.IsMovie, cancellationToken));
            }

            if (string.Equals(query.FolderId, "kids", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsKids, cancellationToken));
            }

            if (string.Equals(query.FolderId, "news", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsNews, cancellationToken));
            }

            if (string.Equals(query.FolderId, "sports", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsSports, cancellationToken));
            }

            if (string.Equals(query.FolderId, "live", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => i.IsLive, cancellationToken));
            }

            if (string.Equals(query.FolderId, "others", StringComparison.OrdinalIgnoreCase))
            {
                return(GetRecordingNameGroups(query, i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries, cancellationToken));
            }

            if (query.FolderId.StartsWith("name_", StringComparison.OrdinalIgnoreCase))
            {
                var hash = query.FolderId.Split('_')[1];
                return(GetChannelItems(query, i => i.Name != null && string.Equals(i.Name.GetMD5().ToString("N"), hash, StringComparison.Ordinal), cancellationToken));
            }

            var result = new ChannelItemResult()
            {
                Items = new List <ChannelItemInfo>()
            };

            return(Task.FromResult(result));
        }