public async Task Execute(CancellationToken cancellationToken, IProgress <double> progress)
        {
            cancellationToken.ThrowIfCancellationRequested();

            await Tracking.Track(_httpClient, _appHost, _serverConfigurationManager, "start", "refresh", cancellationToken).ConfigureAwait(false);

            progress.Report(2d);

            var items = (await GetBluRayReleaseItems(cancellationToken).ConfigureAwait(false)).List;

            progress.Report(6d);

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

            progress.Report(8d);

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

            ConvertPostersFromW640ToOriginal(config, dataPath);

            Plugin.DebugLogger($"Found {items.Count} items in feed");

            DateTime lastPublishDate = config.LastPublishDate;
            DateTime minAge          = DateTime.Today.AddDays(0 - config.Age);
            DateTime newPublishDate  = items[0].PublishDate;
            Dictionary <string, BaseItem> libDict = (config.AddItemsAlreadyInLibrary) ? Library.BuildLibraryDictionary(cancellationToken, _libraryManager, new InternalItemsQuery()
            {
                HasAnyProviderId = new[] { "Imdb" },
                //SourceTypes = new SourceType[] { SourceType.Library }
            }) : new Dictionary <string, BaseItem>();

            cancellationToken.ThrowIfCancellationRequested();

            var insertList   = new BlurNItems();
            var failedList   = new FailedBlurNList();
            var existingData = new List <BlurNItem>();

            //var finalItems = items.Where(i => i.PublishDate > lastPublishDate).GroupBy(x => new { x.Title, x.PublishDate }).Select(g => g.First()).Reverse().ToList();
            var finalItems = items.GroupBy(x => new { x.Title, x.PublishDate }).Select(g => g.First()).Reverse().ToList();

            string failedDataPath = AddPreviouslyFailedItemsToFinalItems(finalItems);

            Plugin.DebugLogger($"Checking {finalItems.Count} new items");

            var genreExcludeList = GetGenreExcludeList(config);

            progress.Report(10d);

            bool itemAdded = false;

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

                if (config.ChannelRefreshCount < 6)
                {
                    if (config.ChannelRefreshCount < 4)
                    {
                        existingData = existingData.GroupBy(p => p.ImdbId).Select(g => g.First()).ToList();
                    }
                    config.ChannelRefreshCount = 6;
                    Plugin.Instance.SaveConfiguration();
                }
            }

            for (int i = 0; i < finalItems.Count(); i++)
            {
                cancellationToken.ThrowIfCancellationRequested();
                progress.Report(10d + (86d * (Convert.ToDouble(i + 1) / Convert.ToDouble(finalItems.Count()))));

                Item item = finalItems[i];
                int  year = 0;

                if (item.Link == "Failed")  // previously failed item
                {
                    year = Convert.ToInt32(item.Content);
                }
                else // new item
                {
                    Regex           rgx     = new Regex(@"\| (\d{4}) \|", RegexOptions.IgnoreCase);
                    MatchCollection matches = rgx.Matches(item.Content);
                    if (matches.Count > 0)
                    {
                        Match match = matches[matches.Count - 1];
                        Group group = match.Groups[match.Groups.Count - 1];
                        year = Convert.ToInt32(group.Value);
                    }
                }

                string url;
                url = BuildOMDbApiUrl(item, year, false);
                BlurNItem blurNItem = await ParseOMDB(url, item.PublishDate, cancellationToken).ConfigureAwait(false);

                if (blurNItem != null && string.IsNullOrEmpty(blurNItem.ImdbId) && (item.Title.EndsWith(" 3D") || item.Title.EndsWith(" 4K")) && year > 0)
                {
                    url       = BuildOMDbApiUrl(item, year, true);
                    blurNItem = await ParseOMDB(url, item.PublishDate, cancellationToken).ConfigureAwait(false);
                }

                if (blurNItem == null)
                {
                    Plugin.DebugLogger($"Adding {item.Title} ({year}) to failed list");
                    failedList.List.Add(new FailedBlurNItem()
                    {
                        Title = item.Title, Year = year
                    });
                }
                else if (!string.IsNullOrEmpty(blurNItem.ImdbId) && (insertList.List.Any(x => x.ImdbId == blurNItem.ImdbId) || existingData.Select(d => d.ImdbId).Contains(blurNItem.ImdbId)))
                {
                    Plugin.DebugLogger($"{blurNItem.ImdbId} is a duplicate, skipped.");
                }
                else if (!string.IsNullOrEmpty(blurNItem.ImdbId) && !config.AddItemsAlreadyInLibrary && libDict.ContainsKey(blurNItem.ImdbId))
                {
                    Plugin.DebugLogger($"{blurNItem.ImdbId} is already in the library, skipped.");
                }
                else if (!string.IsNullOrEmpty(blurNItem.ImdbId) && config.HidePlayedMovies && libDict.ContainsKey(blurNItem.ImdbId) && _userManager.Users.All(x => libDict[blurNItem.ImdbId].IsPlayed(x)))
                {
                    Plugin.DebugLogger($"{blurNItem.ImdbId} is played by all users, skipped.");
                }
                else if (blurNItem.Type != "movie")
                {
                    Plugin.DebugLogger($"{blurNItem.Title} is not of type 'movie', skipped.");
                }
                else if (genreExcludeList.Contains(blurNItem.FirstGenre))
                {
                    Plugin.DebugLogger($"{blurNItem.Title} has first genre '{blurNItem.FirstGenre}' which is not whitelisted, skipped.");
                }
                else if (blurNItem.ImdbRating < config.MinimumIMDBRating)
                {
                    Plugin.DebugLogger($"{blurNItem.Title} has an IMDb rating of {blurNItem.ImdbRating} which is lower than the minimum setting of {config.MinimumIMDBRating}, skipped.");
                }
                else if (blurNItem.ImdbVotes < config.MinimumIMDBVotes)
                {
                    Plugin.DebugLogger($"{blurNItem.Title} has a total of {blurNItem.ImdbVotes} IMDb votes which is lower than the minimum setting of {config.MinimumIMDBVotes} votes, skipped.");
                }
                else if (blurNItem.Released < minAge)
                {
                    Plugin.DebugLogger($"{blurNItem.Title} was released on {blurNItem.Released.ToString("yyyy-MM-dd")} which is older than the setting of {config.Age} days, skipped.");
                }
                else // passed all filters, adding
                {
                    await UpdateContentWithTmdbData(cancellationToken, blurNItem).ConfigureAwait(false);

                    insertList.List.Add(blurNItem);

                    await Plugin.NotificationManager.SendNotification(new NotificationRequest()
                    {
                        Date             = DateTime.Now,
                        Level            = NotificationLevel.Normal,
                        NotificationType = BlurNNotificationType.NewRelease,
                        Url         = blurNItem.ImdbUrl,
                        Name        = string.Format("[BlurN] New movie released: {0}", blurNItem.Title),
                        Description = string.Format("Year: {0}, IMDb Rating: {1} ({2} votes)", blurNItem.Year, blurNItem.ImdbRating, blurNItem.ImdbVotes.ToString("#,##0"))
                    }, cancellationToken).ConfigureAwait(false);

                    Plugin.DebugLogger($"Adding {blurNItem.Title} to the BlurN channel.");

                    itemAdded = true;
                }
            }

            if (existingData != null)
            {
                //insertList.List = insertList.List.Where(x => !existingData.Select(d => d.ImdbId).Contains(x.ImdbId)).ToList();

                foreach (BlurNItem blurNItem in existingData.Where(o => !o.TmdbId.HasValue))
                {
                    await UpdateContentWithTmdbData(cancellationToken, blurNItem).ConfigureAwait(false);
                }

                insertList.List.AddRange(existingData);
            }

            insertList.List = insertList.List.OrderByDescending(i => i.BluRayReleaseDate).ThenByDescending(i => i.ImdbRating).ThenByDescending(i => i.ImdbVotes).ThenByDescending(i => i.Metascore).ThenBy(i => i.Title).ToList();

            config.LastPublishDate = newPublishDate;
            if (config.DataVersion == "0" || itemAdded)
            {
                config.DataVersion = DateTime.Now.ToString("yyyyMMddHHmmss");
            }

            Plugin.Instance.SaveConfiguration();

            Plugin.DebugLogger($"Configuration saved. MediaBrowser.Channels.BlurN.Data.json path is {dataPath}");

            progress.Report(97d);

            _json.SerializeToFile(insertList.List, dataPath);
            _json.SerializeToFile(failedList.List, failedDataPath);

            Plugin.DebugLogger($"JSON files saved to {dataPath}");

            progress.Report(98d);

            await Tracking.Track(_httpClient, _appHost, _serverConfigurationManager, "end", "refresh", cancellationToken).ConfigureAwait(false);

            progress.Report(100);
            return;
        }
예제 #2
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);
        }