private void LoadCommentsList()
        {
            GUIUtils.SetProperty("#Trakt.Items", string.Empty);

            GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
            {
                switch (ShoutType)
                {
                case ShoutTypeEnum.movie:
                    if (MovieInfo == null)
                    {
                        return(null);
                    }
                    GUIUtils.SetProperty("#Trakt.Shout.CurrentItem", MovieInfo.Title);
                    return(GetMovieComments());

                case ShoutTypeEnum.show:
                    if (ShowInfo == null)
                    {
                        return(null);
                    }
                    GUIUtils.SetProperty("#Trakt.Shout.CurrentItem", ShowInfo.Title);
                    return(GetShowComments());

                case ShoutTypeEnum.season:
                    if (SeasonInfo == null)
                    {
                        return(null);
                    }
                    GUIUtils.SetProperty("#Trakt.Shout.CurrentItem", SeasonInfo.Title);
                    return(GetSeasonComments());

                case ShoutTypeEnum.episode:
                    if (EpisodeInfo == null)
                    {
                        return(null);
                    }
                    GUIUtils.SetProperty("#Trakt.Shout.CurrentItem", EpisodeInfo.ToString());
                    return(GetEpisodeComments());

                case ShoutTypeEnum.list:
                    if (ListInfo == null)
                    {
                        return(null);
                    }
                    GUIUtils.SetProperty("#Trakt.Shout.CurrentItem", ListInfo.Name);
                    return(GetListComments());

                default:
                    return(null);
                }
            },
                                                                      delegate(bool success, object result)
            {
                if (success)
                {
                    SendCommentsToFacade(result as IEnumerable <TraktComment>);
                }
            }, Translation.GettingShouts, true);
        }
Exemple #2
0
        public override async Task CollectFanArtAsync(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects)
        {
            IResourceLocator mediaItemLocator = null;

            if (!BaseInfo.IsVirtualResource(aspects))
            {
                mediaItemLocator = GetResourceLocator(aspects);
            }

            if (!aspects.ContainsKey(EpisodeAspect.ASPECT_ID) || mediaItemLocator == null)
            {
                return;
            }

            IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>();

            using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor())
            {
                EpisodeInfo episodeInfo = new EpisodeInfo();
                if (!episodeInfo.FromMetadata(aspects))
                {
                    return;
                }

                //Episode fanart
                if (AddToCache(mediaItemId))
                {
                    var existingThumbs = fanArtCache.GetFanArtFiles(mediaItemId, FanArtTypes.Thumbnail);
                    int?season         = episodeInfo.SeasonNumber;
                    int?episode        = episodeInfo.EpisodeNumbers != null && episodeInfo.EpisodeNumbers.Any() ? episodeInfo.EpisodeNumbers.First() : (int?)null;
                    if (!existingThumbs.Any()) //Only get thumb if needed for better performance
                    {
                        NfoSeriesEpisodeReader episodeReader = await SERIES_EXTRACTOR.TryGetNfoSeriesEpisodeReaderAsync(mediaItemAccessor, season, episode, true).ConfigureAwait(false);

                        if (episodeReader != null)
                        {
                            var stubs    = episodeReader.GetEpisodeStubs();
                            var mainStub = stubs?.FirstOrDefault();
                            if (mainStub?.Thumb != null)
                            {
                                await fanArtCache.TrySaveFanArt(mediaItemId, episodeInfo.ToString(), FanArtTypes.Thumbnail, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false);
                            }
                        }
                    }
                }

                //Series fanart
                if (RelationshipExtractorUtils.TryGetLinkedId(SeriesAspect.ROLE_SERIES, aspects, out Guid seriesMediaItemId))
                {
                    IList <Tuple <Guid, string> > actors = GetActors(aspects);
                    RelationshipExtractorUtils.TryGetLinkedId(SeasonAspect.ROLE_SEASON, aspects, out Guid seasonMediaItemId);

                    //Check if loading nfo is needed
                    if ((actors?.All(a => IsInCache(a.Item1)) ?? true) && IsInCache(seriesMediaItemId) && (seasonMediaItemId == Guid.Empty || IsInCache(seasonMediaItemId)))
                    {
                        return; //Everything was already saved
                    }
                    NfoSeriesReader seriesNfoReader = await SERIES_EXTRACTOR.TryGetNfoSeriesReaderAsync(mediaItemAccessor, true).ConfigureAwait(false);

                    if (seriesNfoReader != null)
                    {
                        var stubs    = seriesNfoReader.GetSeriesStubs();
                        var mainStub = stubs?.FirstOrDefault();
                        if (AddToCache(seriesMediaItemId))
                        {
                            var series = episodeInfo.CloneBasicInstance <SeriesInfo>();
                            if (mainStub?.Thumbs?.Count > 0)
                            {
                                await TrySaveThumbStubs(fanArtCache, mainStub.Thumbs, null, seriesMediaItemId, series.ToString());
                            }
                        }

                        if (seasonMediaItemId != Guid.Empty && episodeInfo.SeasonNumber.HasValue && AddToCache(seasonMediaItemId))
                        {
                            var season = episodeInfo.CloneBasicInstance <SeasonInfo>();
                            if (mainStub?.Thumbs?.Count > 0)
                            {
                                await TrySaveThumbStubs(fanArtCache, mainStub.Thumbs, episodeInfo.SeasonNumber, seasonMediaItemId, season.ToString());
                            }
                        }


                        //Actor fanart
                        //We only want the series actors because thumb loading is disabled on episode actors for performance reasons, so we might need to
                        //load the series nfo multiple time before we have all actors depending on what actors are in the episode
                        foreach (var actor in actors)
                        {
                            if (!IsInCache(actor.Item1))
                            {
                                var existingThumbs = fanArtCache.GetFanArtFiles(actor.Item1, FanArtTypes.Thumbnail);
                                var actorStub      = mainStub?.Actors?.FirstOrDefault(a => string.Equals(a?.Name, actor.Item2, StringComparison.InvariantCultureIgnoreCase));
                                if (actorStub != null || existingThumbs.Any()) //We have a thumb already or no thumb is available, so no need to check again
                                {
                                    AddToCache(actor.Item1);
                                }

                                if (actorStub?.Thumb != null)
                                {
                                    await fanArtCache.TrySaveFanArt(actor.Item1, actor.Item2, FanArtTypes.Thumbnail, p => TrySaveFileImage(actorStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #3
0
        private void SendCommentsToFacade(IEnumerable <TraktComment> comments)
        {
            // clear facade
            GUIControl.ClearControl(GetID, Facade.GetID);

            if (comments == null)
            {
                GUIUtils.ShowNotifyDialog(Translation.Error, Translation.ErrorGeneral);
                GUIWindowManager.ShowPreviousWindow();
                return;
            }

            // this should not happen for replies as we only enter if more than one
            if (comments.Count() == 0)
            {
                string title = string.Empty;
                switch (ShoutType)
                {
                case ShoutTypeEnum.movie:
                    title = MovieInfo.Title;
                    break;

                case ShoutTypeEnum.show:
                    title = ShowInfo.Title;
                    break;

                case ShoutTypeEnum.season:
                    title = string.Format("{0} - {1} {2}", SeasonInfo.Title, Translation.Season, SeasonInfo.SeasonIdx);
                    break;

                case ShoutTypeEnum.episode:
                    title = EpisodeInfo.ToString();
                    break;
                }
                ClearProperties();
                GUIUtils.ShowNotifyDialog(GUIUtils.PluginName(), string.Format(Translation.NoShoutsForItem, title));

                if (ExitIfNoShoutsFound)
                {
                    GUIWindowManager.ShowPreviousWindow();
                    return;
                }
            }

            // filter out the duplicates!
            var distinctComments = comments.Where(s => s.Text != null && s.User != null).Distinct(new ShoutComparer());

            GUIUtils.SetProperty("#itemcount", distinctComments.Count().ToString());
            GUIUtils.SetProperty("#Trakt.Items", string.Format("{0} {1}", distinctComments.Count(), distinctComments.Count() > 1 ? Translation.Comments : Translation.Shout));

            int selectedParentItem = 0;
            int selectedItemIndex  = 0;

            SelectedParentItems.TryGetValue(CurrentLevel, out selectedParentItem);

            int id         = 0;
            var userImages = new List <GUITraktImage>();

            // Add each user that shouted to the list
            foreach (var comment in distinctComments)
            {
                // add image to download
                var images = new GUITraktImage {
                    UserImages = comment.User.Images
                };
                userImages.Add(images);

                var shoutItem = new GUIUserListItem(comment.User.Username, (int)TraktGUIWindows.Shouts);

                shoutItem.Label2          = comment.CreatedAt.FromISO8601().ToShortDateString();
                shoutItem.Images          = images;
                shoutItem.TVTag           = comment;
                shoutItem.User            = comment.User;
                shoutItem.ItemId          = id++;
                shoutItem.IconImage       = "defaultTraktUser.png";
                shoutItem.IconImageBig    = "defaultTraktUserBig.png";
                shoutItem.ThumbnailImage  = "defaultTraktUserBig.png";
                shoutItem.OnItemSelected += OnCommentSelected;
                Utils.SetDefaultIcons(shoutItem);
                Facade.Add(shoutItem);

                // check if we should select this comment when returning from replies
                if (selectedParentItem == (int)comment.Id)
                {
                    selectedItemIndex = id - 1;
                }
            }

            // Enable / Disable GUI Controls
            EnableGUIButtons();

            // Set Facade Layout
            if (Facade.Count > 0)
            {
                Facade.SetCurrentLayout("List");
                GUIControl.FocusControl(GetID, Facade.GetID);

                Facade.SelectedListItemIndex = selectedItemIndex;
            }
            else
            {
                GUIControl.FocusControl(GetID, nextEpisodeButton.GetID);
            }

            // Download avatars Async and set to facade
            GUIUserListItem.GetImages(userImages);
        }
Exemple #4
0
        public override async Task <bool> UpdateFromOnlineSeriesEpisodeAsync(EpisodeInfo episode, string language, bool cacheOnly)
        {
            try
            {
                List <EpisodeInfo> episodeDetails = new List <EpisodeInfo>();
                TvMazeEpisode      episodeDetail  = null;
                TvMazeSeries       seriesDetail   = null;

                if (episode.SeasonNumber.HasValue && episode.EpisodeNumbers.Count > 0)
                {
                    if (episode.SeriesTvMazeId > 0)
                    {
                        seriesDetail = await _tvMazeHandler.GetSeriesAsync(episode.SeriesTvMazeId, cacheOnly).ConfigureAwait(false);
                    }
                    if (seriesDetail == null && !string.IsNullOrEmpty(episode.SeriesImdbId))
                    {
                        seriesDetail = await _tvMazeHandler.GetSeriesByImDbAsync(episode.SeriesImdbId, cacheOnly).ConfigureAwait(false);
                    }
                    if (seriesDetail == null && episode.SeriesTvdbId > 0)
                    {
                        seriesDetail = await _tvMazeHandler.GetSeriesByTvDbAsync(episode.SeriesTvdbId, cacheOnly).ConfigureAwait(false);
                    }
                    if (seriesDetail == null)
                    {
                        return(false);
                    }

                    foreach (int episodeNumber in episode.EpisodeNumbers)
                    {
                        episodeDetail = await _tvMazeHandler.GetSeriesEpisodeAsync(episode.SeriesTvMazeId, episode.SeasonNumber.Value, episodeNumber, cacheOnly).ConfigureAwait(false);

                        if (episodeDetail == null)
                        {
                            continue;
                        }
                        if (episodeDetail.EpisodeNumber <= 0)
                        {
                            continue;
                        }

                        EpisodeInfo info = new EpisodeInfo()
                        {
                            TvMazeId = episodeDetail.Id,

                            SeriesTvMazeId   = seriesDetail.Id,
                            SeriesImdbId     = seriesDetail.Externals.ImDbId,
                            SeriesTvdbId     = seriesDetail.Externals.TvDbId ?? 0,
                            SeriesTvRageId   = seriesDetail.Externals.TvRageId ?? 0,
                            SeriesName       = new SimpleTitle(seriesDetail.Name, true),
                            SeriesFirstAired = seriesDetail.Premiered,

                            SeasonNumber   = episodeDetail.SeasonNumber,
                            EpisodeNumbers = new List <int>(new int[] { episodeDetail.EpisodeNumber }),
                            FirstAired     = episodeDetail.AirDate,
                            EpisodeName    = new SimpleTitle(episodeDetail.Name, true),
                            Summary        = new SimpleTitle(episodeDetail.Summary, true),
                            Genres         = seriesDetail.Genres.Where(s => !string.IsNullOrEmpty(s?.Trim())).Select(s => new GenreInfo {
                                Name = s.Trim()
                            }).ToList(),
                            DataProviders = new List <string>()
                            {
                                _name
                            }
                        };

                        if (seriesDetail.Embedded != null && seriesDetail.Embedded.Cast != null)
                        {
                            info.Actors     = ConvertToPersons(seriesDetail.Embedded.Cast, PersonAspect.OCCUPATION_ACTOR, seriesDetail.Name);
                            info.Characters = ConvertToCharacters(seriesDetail.Embedded.Cast, seriesDetail.Name);
                        }

                        episodeDetails.Add(info);
                    }
                }
                if (!episode.DataProviders.Contains(_name))
                {
                    episode.DataProviders.Add(_name);
                }

                if (episodeDetails.Count > 1)
                {
                    SetMultiEpisodeDetails(episode, episodeDetails);
                    return(true);
                }
                else if (episodeDetails.Count > 0)
                {
                    SetEpisodeDetails(episode, episodeDetails[0]);
                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Debug("TvMazeWrapper: Exception while processing episode {0}", ex, episode.ToString());
                return(false);
            }
        }
        public override bool UpdateFromOnlineSeriesEpisode(EpisodeInfo episode, string language, bool cacheOnly)
        {
            try
            {
                List <EpisodeInfo> episodeDetails = new List <EpisodeInfo>();
                OmDbEpisode        episodeDetail  = null;

                if (!string.IsNullOrEmpty(episode.SeriesImdbId) && episode.SeasonNumber.HasValue && episode.EpisodeNumbers.Count > 0)
                {
                    OmDbSeason seasonDetail = _omDbHandler.GetSeriesSeason(episode.SeriesImdbId, 1, cacheOnly);

                    foreach (int episodeNumber in episode.EpisodeNumbers)
                    {
                        episodeDetail = _omDbHandler.GetSeriesEpisode(episode.SeriesImdbId, episode.SeasonNumber.Value, episodeNumber, cacheOnly);
                        if (episodeDetail == null)
                        {
                            continue;
                        }
                        if (episodeDetail.EpisodeNumber <= 0)
                        {
                            continue;
                        }

                        EpisodeInfo info = new EpisodeInfo()
                        {
                            ImdbId = episodeDetail.ImdbID,

                            SeriesImdbId     = episodeDetail.ImdbSeriesID,
                            SeriesName       = new SimpleTitle(seasonDetail.Title, true),
                            SeriesFirstAired = seasonDetail != null && seasonDetail.Episodes != null && seasonDetail.Episodes.Count > 0 ?
                                               seasonDetail.Episodes[0].Released : default(DateTime?),

                            SeasonNumber   = episodeDetail.SeasonNumber,
                            EpisodeNumbers = episodeDetail.EpisodeNumber.HasValue ? new List <int>(new int[] { episodeDetail.EpisodeNumber.Value }) : null,
                            FirstAired     = episodeDetail.Released,
                            EpisodeName    = new SimpleTitle(episodeDetail.Title, true),
                            Summary        = new SimpleTitle(episodeDetail.Plot, true),
                            Genres         = episodeDetail.Genres.Select(s => new GenreInfo {
                                Name = s
                            }).ToList(),
                        };

                        if (episodeDetail.ImdbRating.HasValue)
                        {
                            MetadataUpdater.SetOrUpdateRatings(ref info.Rating, new SimpleRating(episodeDetail.ImdbRating, episodeDetail.ImdbVotes));
                        }
                        if (episodeDetail.TomatoRating.HasValue)
                        {
                            MetadataUpdater.SetOrUpdateRatings(ref info.Rating, new SimpleRating(episodeDetail.TomatoRating, episodeDetail.TomatoTotalReviews));
                        }
                        if (episodeDetail.TomatoUserRating.HasValue)
                        {
                            MetadataUpdater.SetOrUpdateRatings(ref info.Rating, new SimpleRating(episodeDetail.TomatoUserRating, episodeDetail.TomatoUserTotalReviews));
                        }

                        //Only use these if absolutely necessary because there is no way to ID them
                        if (episode.Actors == null || episode.Actors.Count == 0)
                        {
                            info.Actors = ConvertToPersons(episodeDetail.Actors, PersonAspect.OCCUPATION_ARTIST, episodeDetail.Title, seasonDetail.Title);
                        }
                        if (episode.Directors == null || episode.Directors.Count == 0)
                        {
                            info.Directors = ConvertToPersons(episodeDetail.Writers, PersonAspect.OCCUPATION_DIRECTOR, episodeDetail.Title, seasonDetail.Title);
                        }
                        if (episode.Writers == null || episode.Writers.Count == 0)
                        {
                            info.Writers = ConvertToPersons(episodeDetail.Directors, PersonAspect.OCCUPATION_WRITER, episodeDetail.Title, seasonDetail.Title);
                        }

                        episodeDetails.Add(info);
                    }
                }
                if (episodeDetails.Count > 1)
                {
                    SetMultiEpisodeDetails(episode, episodeDetails);
                    return(true);
                }
                else if (episodeDetails.Count > 0)
                {
                    SetEpisodeDetails(episode, episodeDetails[0]);
                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Debug("OmDbWrapper: Exception while processing episode {0}", ex, episode.ToString());
                return(false);
            }
        }
Exemple #6
0
        public override async Task <bool> UpdateFromOnlineSeriesEpisodeAsync(EpisodeInfo episode, TvdbLanguage language, bool cacheOnly)
        {
            try
            {
                language = language ?? PreferredLanguage;

                List <EpisodeInfo> episodeDetails = new List <EpisodeInfo>();
                TvdbSeries         seriesDetail   = null;
                TvdbEpisode        episodeDetail  = null;

                if ((episode.SeriesTvdbId > 0 || !string.IsNullOrEmpty(episode.SeriesImdbId)) && episode.SeasonNumber.HasValue && episode.EpisodeNumbers.Count > 0)
                {
                    if (episode.SeriesTvdbId > 0)
                    {
                        seriesDetail = await _tvdbHandler.GetSeriesAsync(episode.SeriesTvdbId, language, true, true, true).ConfigureAwait(false);
                    }
                    if (seriesDetail == null && !cacheOnly && !string.IsNullOrEmpty(episode.SeriesImdbId))
                    {
                        TvdbSearchResult foundSeries = await _tvdbHandler.GetSeriesByRemoteIdAsync(ExternalId.ImdbId, episode.SeriesImdbId).ConfigureAwait(false);

                        if (foundSeries != null)
                        {
                            seriesDetail = await _tvdbHandler.GetSeriesAsync(foundSeries.Id, language, true, true, true).ConfigureAwait(false);
                        }
                    }
                    if (seriesDetail == null)
                    {
                        return(false);
                    }

                    bool isFirstEpisode = true;
                    foreach (int episodeNumber in episode.EpisodeNumbers)
                    {
                        episodeDetail = seriesDetail.Episodes.Where(e => e.EpisodeNumber == episodeNumber &&
                                                                    e.SeasonNumber == episode.SeasonNumber.Value).OrderByDescending(e => e.Id).FirstOrDefault();
                        if (episodeDetail == null)
                        {
                            continue;
                        }

                        EpisodeInfo info = new EpisodeInfo()
                        {
                            TvdbId = episodeDetail.Id,

                            SeriesTvdbId     = seriesDetail.Id,
                            SeriesImdbId     = seriesDetail.ImdbId,
                            SeriesName       = new SimpleTitle(seriesDetail.SeriesName, false),
                            SeriesFirstAired = seriesDetail.FirstAired,

                            ImdbId         = episodeDetail.ImdbId,
                            SeasonNumber   = episodeDetail.SeasonNumber,
                            EpisodeNumbers = new List <int>(new int[] { episodeDetail.EpisodeNumber }),
                            FirstAired     = episodeDetail.FirstAired,
                            EpisodeName    = new SimpleTitle(episodeDetail.EpisodeName, false),
                            Summary        = new SimpleTitle(episodeDetail.Overview, false),
                            Genres         = seriesDetail.Genre.Where(s => !string.IsNullOrEmpty(s?.Trim())).Select(s => new GenreInfo {
                                Name = s.Trim()
                            }).ToList(),
                            Rating = new SimpleRating(episodeDetail.Rating, episodeDetail.RatingCount),
                        };

                        if (episodeDetail.DvdEpisodeNumber > 0)
                        {
                            info.DvdEpisodeNumbers = new List <double>(new double[] { episodeDetail.DvdEpisodeNumber });
                        }

                        info.Actors = ConvertToPersons(seriesDetail.TvdbActors, PersonAspect.OCCUPATION_ACTOR, episodeDetail.EpisodeName, seriesDetail.SeriesName);
                        //info.Actors.AddRange(ConvertToPersons(episodeDetail.GuestStars, PersonAspect.OCCUPATION_ACTOR, info.Actors.Count));
                        info.Characters = ConvertToCharacters(seriesDetail.TvdbActors, episodeDetail.EpisodeName, seriesDetail.SeriesName);
                        info.Directors  = ConvertToPersons(episodeDetail.Directors, PersonAspect.OCCUPATION_DIRECTOR, 0, episodeDetail.EpisodeName, seriesDetail.SeriesName);
                        info.Writers    = ConvertToPersons(episodeDetail.Writer, PersonAspect.OCCUPATION_WRITER, 0, episodeDetail.EpisodeName, seriesDetail.SeriesName);
                        info.Languages.Add(episodeDetail.Language.Abbriviation);

                        if (isFirstEpisode && !episode.HasThumbnail && episodeDetail.Banner != null)
                        {
                            info.Thumbnail = await episodeDetail.Banner.LoadImageDataAsync().ConfigureAwait(false);
                        }

                        episodeDetails.Add(info);
                        isFirstEpisode = false;
                    }
                }

                if (episodeDetails.Count > 1)
                {
                    SetMultiEpisodeDetails(episode, episodeDetails);
                    return(true);
                }
                else if (episodeDetails.Count > 0)
                {
                    SetEpisodeDetails(episode, episodeDetails[0]);
                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Debug("TvDbWrapper: Exception while processing episode {0}", ex, episode.ToString());
                return(false);
            }
        }
Exemple #7
0
        private void SendShoutsToFacade(IEnumerable <TraktShout> shouts)
        {
            // clear facade
            GUIControl.ClearControl(GetID, Facade.GetID);

            if (shouts == null || shouts.Count() == 0)
            {
                if (shouts != null)
                {
                    string title = string.Empty;
                    switch (ShoutType)
                    {
                    case ShoutTypeEnum.movie:
                        title = MovieInfo.Title;
                        break;

                    case ShoutTypeEnum.show:
                        title = ShowInfo.Title;
                        break;

                    case ShoutTypeEnum.episode:
                        title = string.Format(EpisodeInfo.ToString());
                        break;
                    }
                    ClearProperties();
                    GUIUtils.ShowNotifyDialog(GUIUtils.PluginName(), string.Format(Translation.NoShoutsForItem, title));
                }
                if (ExitIfNoShoutsFound)
                {
                    GUIWindowManager.ShowPreviousWindow();
                    return;
                }
            }

            GUIUtils.SetProperty("#itemcount", shouts.Count().ToString());
            GUIUtils.SetProperty("#Trakt.Items", string.Format("{0} {1}", shouts.Count(), shouts.Count() > 1 ? Translation.Shouts : Translation.Shout));

            int id = 0;
            List <TraktUser> users = new List <TraktUser>();

            // Add each user that shouted to the list
            foreach (var shout in shouts)
            {
                GUITraktShoutListItem shoutItem = new GUITraktShoutListItem(shout.User.Username);

                shoutItem.Label2          = shout.InsertedDate.FromEpoch().ToShortDateString();
                shoutItem.Item            = shout.User;
                shoutItem.TVTag           = shout;
                shoutItem.ItemId          = id++;
                shoutItem.IconImage       = "defaultTraktUser.png";
                shoutItem.IconImageBig    = "defaultTraktUserBig.png";
                shoutItem.ThumbnailImage  = "defaultTraktUserBig.png";
                shoutItem.OnItemSelected += OnShoutSelected;
                Utils.SetDefaultIcons(shoutItem);
                Facade.Add(shoutItem);

                users.Add(shout.User);
            }

            // Enable / Disable GUI Controls
            EnableGUIButtons();

            // Set Facade Layout
            if (Facade.Count > 0)
            {
                Facade.SetCurrentLayout("List");
                GUIControl.FocusControl(GetID, Facade.GetID);

                Facade.SelectedListItemIndex = 0;
            }
            else
            {
                GUIControl.FocusControl(GetID, nextEpisodeButton.GetID);
            }

            // Download avatars Async and set to facade
            GetImages(users);
        }
        private void ExtractFolderImages(IResourceLocator mediaItemLocater, Guid?episodeMediaItemId, Guid?seriesMediaItemId, Guid?seasonMediaItemId, EpisodeInfo episode, SeriesInfo series, SeasonInfo season, IDictionary <Guid, string> actorMediaItems)
        {
            string fileSystemPath = string.Empty;

            // File based access
            try
            {
                if (mediaItemLocater != null)
                {
                    fileSystemPath = mediaItemLocater.NativeResourcePath.FileName;
                    var mediaItemPath                = mediaItemLocater.NativeResourcePath;
                    var mediaItemFileName            = ResourcePathHelper.GetFileNameWithoutExtension(mediaItemPath.ToString()).ToLowerInvariant();
                    var seasonMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../");
                    var seriesMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../../");

                    //Series fanart
                    var fanArtPaths   = new List <ResourcePath>();
                    var posterPaths   = new List <ResourcePath>();
                    var bannerPaths   = new List <ResourcePath>();
                    var logoPaths     = new List <ResourcePath>();
                    var clearArtPaths = new List <ResourcePath>();
                    var discArtPaths  = new List <ResourcePath>();
                    if (seriesMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seriesMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                if (actorMediaItems.Count > 0)
                                {
                                    //Get Actor thumbs
                                    IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                                    if (actorMediaItemDirectory != null)
                                    {
                                        foreach (var actor in actorMediaItems)
                                        {
                                            var potentialArtistFanArtFiles = GetPotentialFanArtFiles(actorMediaItemDirectory);

                                            foreach (ResourcePath thumbPath in
                                                     from potentialFanArtFile in potentialArtistFanArtFiles
                                                     let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                                   where potentialFanArtFileNameWithoutExtension.StartsWith(actor.Value.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                                   select potentialFanArtFile)
                                            {
                                                SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, actor.Key, actor.Value);
                                            }
                                        }
                                    }
                                }

                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                posterPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "poster" || potentialFanArtFileNameWithoutExtension == "folder" || potentialFanArtFileNameWithoutExtension == "cover"
                                                                                  select potentialFanArtFile);

                                logoPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "logo"
                                                                                  select potentialFanArtFile);

                                clearArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "clearart"
                                                                                  select potentialFanArtFile);

                                discArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "discart" || potentialFanArtFileNameWithoutExtension == "disc"
                                                                                  select potentialFanArtFile);

                                bannerPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "banner"
                                                                                  select potentialFanArtFile);

                                fanArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "backdrop" || potentialFanArtFileNameWithoutExtension == "fanart"
                                                                                  select potentialFanArtFile);

                                if (directoryFsra.ResourceExists("ExtraFanArt/"))
                                {
                                    using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                        fanArtPaths.AddRange(GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                                }
                            }
                        }
                        foreach (ResourcePath posterPath in posterPaths)
                        {
                            SaveFolderFile(mediaItemLocater, posterPath, FanArtTypes.Poster, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath logoPath in logoPaths)
                        {
                            SaveFolderFile(mediaItemLocater, logoPath, FanArtTypes.Logo, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath clearArtPath in clearArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, clearArtPath, FanArtTypes.ClearArt, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath discArtPath in discArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, discArtPath, FanArtTypes.DiscArt, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath bannerPath in bannerPaths)
                        {
                            SaveFolderFile(mediaItemLocater, bannerPath, FanArtTypes.Banner, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath fanartPath in fanArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, fanartPath, FanArtTypes.FanArt, seriesMediaItemId.Value, series.ToString());
                        }
                    }

                    //Season fanart
                    fanArtPaths.Clear();
                    posterPaths.Clear();
                    bannerPaths.Clear();
                    logoPaths.Clear();
                    clearArtPaths.Clear();
                    discArtPaths.Clear();
                    if (seasonMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seasonMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                if (actorMediaItems.Count > 0)
                                {
                                    //Get Actor thumbs
                                    IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                                    if (actorMediaItemDirectory != null)
                                    {
                                        foreach (var actor in actorMediaItems)
                                        {
                                            var potentialArtistFanArtFiles = GetPotentialFanArtFiles(actorMediaItemDirectory);

                                            foreach (ResourcePath thumbPath in
                                                     from potentialFanArtFile in potentialArtistFanArtFiles
                                                     let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                                   where potentialFanArtFileNameWithoutExtension.StartsWith(actor.Value.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                                   select potentialFanArtFile)
                                            {
                                                SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, actor.Key, actor.Value);
                                            }
                                        }
                                    }
                                }

                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                posterPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "poster" || potentialFanArtFileNameWithoutExtension == "folder" || potentialFanArtFileNameWithoutExtension == "cover"
                                                                                  select potentialFanArtFile);

                                bannerPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "banner"
                                                                                  select potentialFanArtFile);

                                fanArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "backdrop" || potentialFanArtFileNameWithoutExtension == "fanart"
                                                                                  select potentialFanArtFile);

                                if (directoryFsra.ResourceExists("ExtraFanArt/"))
                                {
                                    using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                        fanArtPaths.AddRange(GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                                }
                            }
                        }
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seriesMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null && season.SeasonNumber.HasValue)
                            {
                                var           potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);
                                List <string> prefixes             = new List <string>();
                                prefixes.Add(string.Format("season{0:00}-", season.SeasonNumber.Value));
                                if (season.SeasonNumber.Value == 0)
                                {
                                    prefixes.Add("season-specials-");
                                }
                                else
                                {
                                    prefixes.Add("season-all-");
                                }

                                foreach (string prefix in prefixes)
                                {
                                    if (posterPaths.Count == 0)
                                    {
                                        posterPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "poster"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (logoPaths.Count == 0)
                                    {
                                        logoPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "logo"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (clearArtPaths.Count == 0)
                                    {
                                        clearArtPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "clearart"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (bannerPaths.Count == 0)
                                    {
                                        bannerPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "banner"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (fanArtPaths.Count == 0)
                                    {
                                        fanArtPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "fanart"
                                                                                          select potentialFanArtFile);
                                    }
                                }
                            }
                        }
                        foreach (ResourcePath posterPath in posterPaths)
                        {
                            SaveFolderFile(mediaItemLocater, posterPath, FanArtTypes.Poster, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath logoPath in logoPaths)
                        {
                            SaveFolderFile(mediaItemLocater, logoPath, FanArtTypes.Logo, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath clearArtPath in clearArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, clearArtPath, FanArtTypes.ClearArt, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath bannerPath in bannerPaths)
                        {
                            SaveFolderFile(mediaItemLocater, bannerPath, FanArtTypes.Banner, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath fanartPath in fanArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, fanartPath, FanArtTypes.FanArt, seasonMediaItemId.Value, season.ToString());
                        }
                    }

                    //Episode fanart
                    //Also saved by the video MDE but saved here again in case of the offline option being different
                    var thumbPaths = new List <ResourcePath>();
                    if (episodeMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seasonMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                thumbPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension.StartsWith(mediaItemFileName + "-thumb") || potentialFanArtFileNameWithoutExtension == "thumb"
                                                                                  select potentialFanArtFile);
                            }
                        }
                        foreach (ResourcePath thumbPath in thumbPaths)
                        {
                            SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, episodeMediaItemId.Value, episode.ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("SeriesFanArtHandler: Exception while reading folder images for '{0}'", ex, fileSystemPath);
            }
        }
        protected async Task ExtractEpisodeFanArt(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects)
        {
            bool             shouldCacheLocal = false;
            IResourceLocator mediaItemLocator = null;

            if (!BaseInfo.IsVirtualResource(aspects))
            {
                mediaItemLocator = GetResourceLocator(aspects);

                //Whether local fanart should be stored in the fanart cache
                shouldCacheLocal = ShouldCacheLocalFanArt(mediaItemLocator.NativeResourcePath,
                                                          SeriesMetadataExtractor.CacheLocalFanArt, SeriesMetadataExtractor.CacheOfflineFanArt);
            }

            if (mediaItemLocator == null)
            {
                return;
            }

            if (!shouldCacheLocal && SeriesMetadataExtractor.SkipFanArtDownload)
            {
                return; //Nothing to do
            }
            EpisodeInfo episodeInfo = new EpisodeInfo();

            episodeInfo.FromMetadata(aspects);

            //Episode fanart
            if (AddToCache(mediaItemId))
            {
                if (shouldCacheLocal)
                {
                    await ExtractEpisodeFolderFanArt(mediaItemLocator, mediaItemId, episodeInfo.ToString()).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(mediaItemId, episodeInfo).ConfigureAwait(false);
                }
            }

            //Actor fanart may be stored in the season or series directory, so get the actors now
            IList <Tuple <Guid, string> > actors = null;

            if (MediaItemAspect.TryGetAspect(aspects, VideoAspect.Metadata, out SingleMediaItemAspect videoAspect))
            {
                var actorNames = videoAspect.GetCollectionAttribute <string>(VideoAspect.ATTR_ACTORS);
                if (actorNames != null)
                {
                    RelationshipExtractorUtils.TryGetMappedLinkedIds(PersonAspect.ROLE_ACTOR, aspects, actorNames.ToList(), out actors);
                }
            }

            //Take advantage of the audio language being known and download season and series too

            //Season fanart
            if (RelationshipExtractorUtils.TryGetLinkedId(SeasonAspect.ROLE_SEASON, aspects, out Guid seasonMediaItemId) &&
                AddToCache(seasonMediaItemId))
            {
                SeasonInfo seasonInfo = episodeInfo.CloneBasicInstance <SeasonInfo>();
                if (shouldCacheLocal)
                {
                    await ExtractSeasonFolderFanArt(mediaItemLocator, seasonMediaItemId, seasonInfo.ToString(), seasonInfo.SeasonNumber, actors).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(seasonMediaItemId, seasonInfo).ConfigureAwait(false);
                }
            }

            //Series fanart
            if (RelationshipExtractorUtils.TryGetLinkedId(SeriesAspect.ROLE_SERIES, aspects, out Guid seriesMediaItemId) &&
                AddToCache(seriesMediaItemId))
            {
                SeriesInfo seriesInfo = episodeInfo.CloneBasicInstance <SeriesInfo>();
                if (shouldCacheLocal)
                {
                    await ExtractSeriesFolderFanArt(mediaItemLocator, seriesMediaItemId, seriesInfo.ToString(), episodeInfo.SeasonNumber, actors).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(seriesMediaItemId, seriesInfo).ConfigureAwait(false);
                }
            }

            //Find central actor information folder
            var          seriesDirectory        = ResourcePathHelper.Combine(mediaItemLocator.NativeResourcePath, "../../");
            ResourcePath centralActorFolderPath = LocalFanartHelper.GetCentralPersonFolder(seriesDirectory, CentralPersonFolderType.SeriesActors);

            if (shouldCacheLocal && centralActorFolderPath != null && actors != null)
            {
                foreach (var actor in actors)
                {
                    // Check if we already processed this actor
                    if (!AddToCache(actor.Item1))
                    {
                        continue;
                    }

                    // First get the ResourcePath of the central directory
                    var artistFolderPath = ResourcePathHelper.Combine(centralActorFolderPath, $"{LocalFanartHelper.GetSafePersonFolderName(actor.Item2)}/");
                    using (IResourceAccessor accessor = new ResourceLocator(mediaItemLocator.NativeSystemId, artistFolderPath).CreateAccessor())
                    {
                        if (accessor is IFileSystemResourceAccessor directoryAccessor)
                        {
                            FanArtPathCollection paths = new FanArtPathCollection();
                            List <ResourcePath>  potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(directoryAccessor);
                            ExtractAllFanArtImages(potentialFanArtFiles, paths);
                            await SaveFolderImagesToCache(mediaItemLocator.NativeSystemId, paths, actor.Item1, actor.Item2).ConfigureAwait(false);
                        }
                    }
                }
            }
        }
        protected async Task ExtractEpisodeFanArt(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects)
        {
            if (BaseInfo.IsVirtualResource(aspects))
            {
                return;
            }

            IResourceLocator mediaItemLocator = GetResourceLocator(aspects);

            if (mediaItemLocator == null)
            {
                return;
            }

            //Whether local fanart should be stored in the fanart cache
            bool shouldCacheLocal = ShouldCacheLocalFanArt(mediaItemLocator.NativeResourcePath,
                                                           SeriesMetadataExtractor.CacheLocalFanArt, SeriesMetadataExtractor.CacheOfflineFanArt);

            if (!shouldCacheLocal && SeriesMetadataExtractor.SkipFanArtDownload)
            {
                return; //Nothing to do
            }
            EpisodeInfo episodeInfo = new EpisodeInfo();

            episodeInfo.FromMetadata(aspects);

            //Episode fanart
            if (AddToCache(mediaItemId))
            {
                if (shouldCacheLocal)
                {
                    await ExtractEpisodeFolderFanArt(mediaItemLocator, mediaItemId, episodeInfo.ToString()).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(mediaItemId, episodeInfo).ConfigureAwait(false);
                }
            }

            //Actor fanart may be stored in the season or series directory, so get the actors now
            IList <Tuple <Guid, string> > actors = null;

            if (MediaItemAspect.TryGetAspect(aspects, VideoAspect.Metadata, out SingleMediaItemAspect videoAspect))
            {
                var actorNames = videoAspect.GetCollectionAttribute <string>(VideoAspect.ATTR_ACTORS);
                if (actorNames != null)
                {
                    RelationshipExtractorUtils.TryGetMappedLinkedIds(PersonAspect.ROLE_ACTOR, aspects, actorNames.ToList(), out actors);
                }
            }

            //Take advantage of the audio language being known and download season and series too

            //Season fanart
            if (RelationshipExtractorUtils.TryGetLinkedId(SeasonAspect.ROLE_SEASON, aspects, out Guid seasonMediaItemId) &&
                AddToCache(seasonMediaItemId))
            {
                SeasonInfo seasonInfo = episodeInfo.CloneBasicInstance <SeasonInfo>();
                if (shouldCacheLocal)
                {
                    await ExtractSeasonFolderFanArt(mediaItemLocator, seasonMediaItemId, seasonInfo.ToString(), seasonInfo.SeasonNumber, actors).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(seasonMediaItemId, seasonInfo).ConfigureAwait(false);
                }
            }

            //Series fanart
            if (RelationshipExtractorUtils.TryGetLinkedId(SeriesAspect.ROLE_SERIES, aspects, out Guid seriesMediaItemId) &&
                AddToCache(seriesMediaItemId))
            {
                SeriesInfo seriesInfo = episodeInfo.CloneBasicInstance <SeriesInfo>();
                if (shouldCacheLocal)
                {
                    await ExtractSeriesFolderFanArt(mediaItemLocator, seriesMediaItemId, seriesInfo.ToString(), actors).ConfigureAwait(false);
                }
                if (!SeriesMetadataExtractor.SkipFanArtDownload)
                {
                    await OnlineMatcherService.Instance.DownloadSeriesFanArtAsync(seriesMediaItemId, seriesInfo).ConfigureAwait(false);
                }
            }
        }