diff options
Diffstat (limited to 'MediaBrowser.Providers/TV/ManualTvdbSeriesImageProvider.cs')
| -rw-r--r-- | MediaBrowser.Providers/TV/ManualTvdbSeriesImageProvider.cs | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/MediaBrowser.Providers/TV/ManualTvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/ManualTvdbSeriesImageProvider.cs new file mode 100644 index 000000000..fa09681e7 --- /dev/null +++ b/MediaBrowser.Providers/TV/ManualTvdbSeriesImageProvider.cs @@ -0,0 +1,312 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; + +namespace MediaBrowser.Providers.TV +{ + public class ManualTvdbSeriesImageProvider : IImageProvider + { + private readonly IServerConfigurationManager _config; + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + + public ManualTvdbSeriesImageProvider(IServerConfigurationManager config) + { + _config = config; + } + + public string Name + { + get { return ProviderName; } + } + + public static string ProviderName + { + get { return "TvDb"; } + } + + public bool Supports(BaseItem item) + { + return item is Series; + } + + public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken) + { + var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false); + + return images.Where(i => i.Type == imageType); + } + + public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken) + { + var seriesId = item.GetProviderId(MetadataProviders.Tvdb); + + if (!string.IsNullOrEmpty(seriesId)) + { + // Process images + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId); + + var path = Path.Combine(seriesDataPath, "banners.xml"); + + try + { + var result = GetImages(path, cancellationToken); + + return Task.FromResult(result); + } + catch (FileNotFoundException) + { + // No tvdb data yet. Don't blow up + } + } + + return Task.FromResult<IEnumerable<RemoteImageInfo>>(new RemoteImageInfo[] { }); + } + + private IEnumerable<RemoteImageInfo> GetImages(string xmlPath, CancellationToken cancellationToken) + { + var settings = new XmlReaderSettings + { + CheckCharacters = false, + IgnoreProcessingInstructions = true, + IgnoreComments = true, + ValidationType = ValidationType.None + }; + + var list = new List<RemoteImageInfo>(); + + using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8)) + { + // Use XmlReader for best performance + using (var reader = XmlReader.Create(streamReader, settings)) + { + reader.MoveToContent(); + + // Loop through each element + while (reader.Read()) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "Banner": + { + using (var subtree = reader.ReadSubtree()) + { + AddImage(subtree, list); + } + break; + } + default: + reader.Skip(); + break; + } + } + } + } + } + + var language = _config.Configuration.PreferredMetadataLanguage; + + var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); + + return list.OrderByDescending(i => + { + if (string.Equals(language, 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) + .ToList(); + } + + 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); + } + } + + } + + public int Priority + { + get { return 1; } + } + } +} |
