private void PopulateImages(List <RemoteImageInfo> list, List <Image> images, ImageType type, int width, int height)
        {
            if (images == null)
            {
                return;
            }

            list.AddRange(images.Select(i =>
            {
                var url = i.url;

                if (!string.IsNullOrEmpty(url))
                {
                    var likesString = i.likes;

                    var info = new RemoteImageInfo
                    {
                        RatingType   = RatingType.Likes,
                        Type         = type,
                        Width        = width,
                        Height       = height,
                        ProviderName = Name,
                        Url          = url,
                        Language     = i.lang
                    };

                    if (!string.IsNullOrEmpty(likesString) &&
                        int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
                    {
                        info.CommunityRating = likes;
                    }

                    return(info);
                }

                return(null);
            }).Where(i => i != null));
        }
Esempio n. 2
0
        private void PopulateImages(List <RemoteImageInfo> list, List <Image> images, ImageType type, int width, int height)
        {
            if (images == null)
            {
                return;
            }

            list.AddRange(images.Select(i =>
            {
                var url = i.url;

                if (!string.IsNullOrEmpty(url))
                {
                    var likesString = i.likes;
                    int likes;

                    var info = new RemoteImageInfo
                    {
                        RatingType   = RatingType.Likes,
                        Type         = type,
                        Width        = width,
                        Height       = height,
                        ProviderName = Name,
                        Url          = url.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase),
                        Language     = i.lang
                    };

                    if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
                    {
                        info.CommunityRating = likes;
                    }

                    return(info);
                }

                return(null);
            }).Where(i => i != null));
        }
Esempio n. 3
0
        /// <summary>
        /// Adds the image.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="reader">The reader.</param>
        /// <param name="type">The type.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        private void AddImage(List <RemoteImageInfo> list, XmlReader reader, ImageType type, int width, int height)
        {
            var url = reader.GetAttribute("url");

            var size = reader.GetAttribute("size");

            if (!String.IsNullOrEmpty(size))
            {
                int sizeNum;
                if (Int32.TryParse(size, NumberStyles.Any, _usCulture, out sizeNum))
                {
                    width  = sizeNum;
                    height = sizeNum;
                }
            }

            var likesString = reader.GetAttribute("likes");
            int likes;

            var info = new RemoteImageInfo
            {
                RatingType   = RatingType.Likes,
                Type         = type,
                Width        = width,
                Height       = height,
                ProviderName = Name,
                Url          = url,
                Language     = reader.GetAttribute("lang")
            };

            if (!String.IsNullOrEmpty(likesString) && Int32.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
            {
                info.CommunityRating = likes;
            }

            list.Add(info);
        }
Esempio n. 4
0
        private void AddImage(XmlReader reader, List <RemoteImageInfo> images)
        {
            reader.MoveToContent();

            string bannerType   = null;
            string url          = null;
            int?   bannerSeason = null;
            int?   width        = null;
            int?   height       = null;
            string language     = null;
            double?rating       = null;
            int?   voteCount    = null;
            string thumbnailUrl = null;

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    case "Rating":
                    {
                        var val = reader.ReadElementContentAsString() ?? string.Empty;

                        double rval;

                        if (double.TryParse(val, NumberStyles.Any, _usCulture, out rval))
                        {
                            rating = rval;
                        }

                        break;
                    }

                    case "RatingCount":
                    {
                        var val = reader.ReadElementContentAsString() ?? string.Empty;

                        int rval;

                        if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
                        {
                            voteCount = rval;
                        }

                        break;
                    }

                    case "Language":
                    {
                        language = reader.ReadElementContentAsString() ?? string.Empty;
                        break;
                    }

                    case "ThumbnailPath":
                    {
                        thumbnailUrl = reader.ReadElementContentAsString() ?? string.Empty;
                        break;
                    }

                    case "BannerType":
                    {
                        bannerType = reader.ReadElementContentAsString() ?? string.Empty;

                        break;
                    }

                    case "BannerPath":
                    {
                        url = reader.ReadElementContentAsString() ?? string.Empty;
                        break;
                    }

                    case "BannerType2":
                    {
                        var bannerType2 = reader.ReadElementContentAsString() ?? string.Empty;

                        // Sometimes the resolution is stuffed in here
                        var resolutionParts = bannerType2.Split('x');

                        if (resolutionParts.Length == 2)
                        {
                            int rval;

                            if (int.TryParse(resolutionParts[0], NumberStyles.Integer, _usCulture, out rval))
                            {
                                width = rval;
                            }

                            if (int.TryParse(resolutionParts[1], NumberStyles.Integer, _usCulture, out rval))
                            {
                                height = rval;
                            }
                        }

                        break;
                    }

                    case "Season":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            bannerSeason = int.Parse(val);
                        }
                        break;
                    }


                    default:
                        reader.Skip();
                        break;
                    }
                }
            }

            if (!string.IsNullOrEmpty(url) && !bannerSeason.HasValue)
            {
                var imageInfo = new RemoteImageInfo
                {
                    RatingType      = RatingType.Score,
                    CommunityRating = rating,
                    VoteCount       = voteCount,
                    Url             = TVUtils.BannerUrl + url,
                    ProviderName    = Name,
                    Language        = language,
                    Width           = width,
                    Height          = height
                };

                if (!string.IsNullOrEmpty(thumbnailUrl))
                {
                    imageInfo.ThumbnailUrl = TVUtils.BannerUrl + thumbnailUrl;
                }

                if (string.Equals(bannerType, "poster", StringComparison.OrdinalIgnoreCase))
                {
                    imageInfo.Type = ImageType.Primary;
                    images.Add(imageInfo);
                }
                else if (string.Equals(bannerType, "series", StringComparison.OrdinalIgnoreCase))
                {
                    imageInfo.Type = ImageType.Banner;
                    images.Add(imageInfo);
                }
                else if (string.Equals(bannerType, "fanart", StringComparison.OrdinalIgnoreCase))
                {
                    imageInfo.Type = ImageType.Backdrop;
                    images.Add(imageInfo);
                }
            }
        }
Esempio n. 5
0
        [InlineData(ImageType.Backdrop, 1, true)]  // populated item, forced to download
        public async void RefreshImages_NonStubItemPopulatedProviderRemote_DownloadsIfNecessary(ImageType imageType, int initialImageCount, bool fullRefresh)
        {
            var targetImageCount = 1;

            // Set path and media source manager so images will be downloaded (EnableImageStub will return false)
            var item = GetItemWithImages(imageType, initialImageCount, false);

            item.Path = "non-empty path";
            BaseItem.MediaSourceManager = Mock.Of <IMediaSourceManager>();

            // seek 2 so it won't short-circuit out of downloading when populated
            var libraryOptions = GetLibraryOptions(item, imageType, 2);

            const string Content        = "Content";
            var          remoteProvider = new Mock <IRemoteImageProvider>(MockBehavior.Strict);

            remoteProvider.Setup(rp => rp.Name).Returns("MockRemoteProvider");
            remoteProvider.Setup(rp => rp.GetSupportedImages(item))
            .Returns(new[] { imageType });
            remoteProvider.Setup(rp => rp.GetImageResponse(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((string url, CancellationToken _) => new HttpResponseMessage
            {
                ReasonPhrase = url,
                StatusCode   = HttpStatusCode.OK,
                Content      = new StringContent(Content, Encoding.UTF8, "image/jpeg")
            });

            var refreshOptions = fullRefresh
                ? new ImageRefreshOptions(Mock.Of <IDirectoryService>())
            {
                ImageRefreshMode = MetadataRefreshMode.FullRefresh,
                ReplaceAllImages = true
            }
                : new ImageRefreshOptions(Mock.Of <IDirectoryService>());

            var remoteInfo = new RemoteImageInfo[targetImageCount];

            for (int i = 0; i < targetImageCount; i++)
            {
                remoteInfo[i] = new RemoteImageInfo
                {
                    Type = imageType,
                    Url  = "image url " + i
                };
            }

            var providerManager = new Mock <IProviderManager>(MockBehavior.Strict);

            providerManager.Setup(pm => pm.GetAvailableRemoteImages(It.IsAny <BaseItem>(), It.IsAny <RemoteImageQuery>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(remoteInfo);
            providerManager.Setup(pm => pm.SaveImage(item, It.IsAny <Stream>(), It.IsAny <string>(), imageType, null, It.IsAny <CancellationToken>()))
            .Callback <BaseItem, Stream, string, ImageType, int?, CancellationToken>((callbackItem, _, _, callbackType, _, _) =>
                                                                                     callbackItem.SetImagePath(callbackType, callbackItem.AllowsMultipleImages(callbackType) ? callbackItem.GetImages(callbackType).Count() : 0, new FileSystemMetadata()))
            .Returns(Task.CompletedTask);
            var fileSystem = new Mock <IFileSystem>();

            // match reported file size to image content length - condition for skipping already downloaded multi-images
            fileSystem.Setup(fs => fs.GetFileInfo(It.IsAny <string>()))
            .Returns(new FileSystemMetadata {
                Length = Content.Length
            });
            var itemImageProvider = GetItemImageProvider(providerManager.Object, fileSystem);
            var result            = await itemImageProvider.RefreshImages(item, libraryOptions, new List <IImageProvider> {
                remoteProvider.Object
            }, refreshOptions, CancellationToken.None);

            Assert.Equal(initialImageCount == 0 || fullRefresh, result.UpdateType.HasFlag(ItemUpdateType.ImageUpdate));
            Assert.Equal(targetImageCount, item.GetImages(imageType).Count());
        }
Esempio n. 6
0
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            _logger?.Info($"{Name}-{nameof(JavImageProvider)}-{nameof(GetImages)} name:{item.Name}");

            var           list  = new List <RemoteImageInfo>();
            JavVideoIndex index = null;

            if ((index = item.GetJavVideoIndex(_jsonSerializer)) == null)
            {
                _logger?.Info($"{Name}-{nameof(JavImageProvider)}-{nameof(GetImages)} name:{item.Name} JavVideoIndex not found.");
                return(list);
            }

            JavVideo m = null;

            try
            {
                var cachePath = Path.Combine(_appPaths.CachePath, Name, index.Provider, $"{index.Num}.json");
                m = _jsonSerializer.DeserializeFromFile <JavVideo>(cachePath);
            }
            catch
            {
                _logger?.Info($"{Name}-{nameof(JavImageProvider)}-{nameof(GetImages)} name:{item.Name} JavVideo not found.");
            }

            if (m == null)
            {
                return(list);
            }

            if (string.IsNullOrWhiteSpace(m.Cover) && m.Samples?.Any() == true)
            {
                m.Cover = m.Samples.FirstOrDefault();
            }

            if (string.IsNullOrWhiteSpace(m.Cover) == false)
            {
                async Task SaveImage(ImageType type)
                {
                    //有的就跳过了
                    if (item.ImageInfos?.Any(o => o.Type == type) == true)
                    {
                        return;
                    }
                    try
                    {
                        var url  = ImageProxyService.BuildUrl(m.Cover, type == ImageType.Primary ? 1 : 0);
                        var resp = await ImageProxyService.GetImageResponse(url, cancellationToken);

                        if (resp?.ContentLength > 0)
                        {
#if __JELLYFIN__
                            await providerManager.SaveImage(item, resp.Content, resp.ContentType, type, 0, cancellationToken);
#else
                            await providerManager.SaveImage(item, libraryOptions, resp.Content, resp.ContentType.ToArray(), type, 0, cancellationToken);
#endif
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger?.Warn($"Save image error: {type} {m.Cover} {ex.Message}");
                    }
                }

                await SaveImage(ImageType.Primary);
                await SaveImage(ImageType.Backdrop);

                //await SaveImage(ImageType.Art);

                var b = new RemoteImageInfo()
                {
                    ProviderName = Name,
                    Type         = ImageType.Backdrop,
                    Url          = Plugin.Instance.Configuration.BuildProxyUrl(m.Cover),
                };
                list.Add(b);
            }

            if (m.Samples?.Any() == true)
            {
                list.AddRange(m.Samples.Select(o => new RemoteImageInfo()
                {
                    ProviderName = Name,
                    Type         = ImageType.Art,
                    Url          = Plugin.Instance.Configuration.BuildProxyUrl(o),
                }));
            }

            return(list);
        }
        private IEnumerable <RemoteImageInfo> GetImages(Image[] images, string seasonNumber, string preferredLanguage)
        {
            var list = new List <RemoteImageInfo>();
            // any languages with null ids are ignored
            var languages = _tvdbClientManager.GetLanguagesAsync(CancellationToken.None).Result.Data.Where(x => x.Id.HasValue).ToArray();

            foreach (Image image in images)
            {
                // The API returns everything that contains the subkey eg. 2 matches 20, 21, 22, 23 etc.
                if (!string.Equals(image.SubKey, seasonNumber, StringComparison.Ordinal))
                {
                    continue;
                }

                var imageInfo = new RemoteImageInfo
                {
                    RatingType      = RatingType.Score,
                    CommunityRating = (double?)image.RatingsInfo.Average,
                    VoteCount       = image.RatingsInfo.Count,
                    Url             = TvdbUtils.BannerUrl + image.FileName,
                    ProviderName    = Name,
                    Language        = languages.FirstOrDefault(lang => lang.Id == image.LanguageId)?.Abbreviation,
                    ThumbnailUrl    = TvdbUtils.BannerUrl + image.Thumbnail
                };

                var resolution = image.Resolution.Split('x');
                if (resolution.Length == 2)
                {
                    imageInfo.Width  = Convert.ToInt32(resolution[0], CultureInfo.InvariantCulture);
                    imageInfo.Height = Convert.ToInt32(resolution[1], CultureInfo.InvariantCulture);
                }

                imageInfo.Type = TvdbUtils.GetImageTypeFromKeyType(image.KeyType);
                list.Add(imageInfo);
            }

            var isLanguageEn = string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase);

            return(list.OrderByDescending(i =>
            {
                if (string.Equals(preferredLanguage, i.Language, StringComparison.OrdinalIgnoreCase))
                {
                    return 3;
                }

                if (!isLanguageEn)
                {
                    if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
                    {
                        return 2;
                    }
                }

                if (string.IsNullOrEmpty(i.Language))
                {
                    return isLanguageEn ? 3 : 2;
                }

                return 0;
            })
                   .ThenByDescending(i => i.CommunityRating ?? 0)
                   .ThenByDescending(i => i.VoteCount ?? 0));
        }
Esempio n. 8
0
        private void PopulateImageCategory(List <RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, bool allowSeasonAll = false)
        {
            reader.MoveToContent();

            while (reader.Read())
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    case "hdtvlogo":
                    case "hdclearart":
                    case "clearlogo":
                    case "clearart":
                    case "showbackground":
                    case "seasonthumb":
                    case "tvthumb":
                    case "tvbanner":
                    case "tvposter":
                    {
                        var url    = reader.GetAttribute("url");
                        var season = reader.GetAttribute("season");

                        var isSeasonValid = string.IsNullOrEmpty(season) ||
                                            (allowSeasonAll && string.Equals(season, "all", StringComparison.OrdinalIgnoreCase));

                        if (!string.IsNullOrEmpty(url) && isSeasonValid)
                        {
                            var likesString = reader.GetAttribute("likes");
                            int likes;

                            var info = new RemoteImageInfo
                            {
                                RatingType   = RatingType.Likes,
                                Type         = type,
                                Width        = width,
                                Height       = height,
                                ProviderName = Name,
                                Url          = url,
                                Language     = reader.GetAttribute("lang")
                            };

                            if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
                            {
                                info.CommunityRating = likes;
                            }

                            list.Add(info);
                        }

                        break;
                    }

                    default:
                        reader.Skip();
                        break;
                    }
                }
            }
        }
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, CancellationToken cancellationToken)
        {
            var tmdbId = item.GetProviderId(MetadataProvider.Tmdb);

            if (string.IsNullOrEmpty(tmdbId))
            {
                return(null);
            }

            var language = item.GetPreferredMetadataLanguage();

            // TODO use image languages if All Languages isn't toggled, but there's currently no way to get that value in here
            var series = await _tmdbClientManager
                         .GetSeriesAsync(Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture), null, null, cancellationToken)
                         .ConfigureAwait(false);

            if (series?.Images == null)
            {
                return(Enumerable.Empty <RemoteImageInfo>());
            }

            var posters   = series.Images.Posters;
            var backdrops = series.Images.Backdrops;

            var remoteImages = new RemoteImageInfo[posters.Count + backdrops.Count];

            for (var i = 0; i < posters.Count; i++)
            {
                var poster = posters[i];
                remoteImages[i] = new RemoteImageInfo
                {
                    Url             = _tmdbClientManager.GetPosterUrl(poster.FilePath),
                    CommunityRating = poster.VoteAverage,
                    VoteCount       = poster.VoteCount,
                    Width           = poster.Width,
                    Height          = poster.Height,
                    Language        = TmdbUtils.AdjustImageLanguage(poster.Iso_639_1, language),
                    ProviderName    = Name,
                    Type            = ImageType.Primary,
                    RatingType      = RatingType.Score
                };
            }

            for (var i = 0; i < backdrops.Count; i++)
            {
                var backdrop = series.Images.Backdrops[i];
                remoteImages[posters.Count + i] = new RemoteImageInfo
                {
                    Url             = _tmdbClientManager.GetBackdropUrl(backdrop.FilePath),
                    CommunityRating = backdrop.VoteAverage,
                    VoteCount       = backdrop.VoteCount,
                    Width           = backdrop.Width,
                    Height          = backdrop.Height,
                    ProviderName    = Name,
                    Type            = ImageType.Backdrop,
                    RatingType      = RatingType.Score
                };
            }

            return(remoteImages.OrderByLanguageDescending(language));
        }