Pārlūkot izejas kodu

Merge pull request #4992 from Bond-009/seriesnfo

Add tests for series nfo
Claus Vium 4 gadi atpakaļ
vecāks
revīzija
75a25de991

+ 25 - 19
MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs

@@ -63,14 +63,14 @@ namespace MediaBrowser.XbmcMetadata.Parsers
         /// <exception cref="ArgumentException"><c>metadataFile</c> is <c>null</c> or empty.</exception>
         /// <exception cref="ArgumentException"><c>metadataFile</c> is <c>null</c> or empty.</exception>
         public void Fetch(MetadataResult<T> item, string metadataFile, CancellationToken cancellationToken)
         public void Fetch(MetadataResult<T> item, string metadataFile, CancellationToken cancellationToken)
         {
         {
-            if (item == null)
+            if (item.Item == null)
             {
             {
-                throw new ArgumentNullException(nameof(item));
+                throw new ArgumentException("Item can't be null.", nameof(item));
             }
             }
 
 
             if (string.IsNullOrEmpty(metadataFile))
             if (string.IsNullOrEmpty(metadataFile))
             {
             {
-                throw new ArgumentException("The metadata file was empty or null.", nameof(metadataFile));
+                throw new ArgumentException("The metadata filepath was empty.", nameof(metadataFile));
             }
             }
 
 
             _validProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
             _validProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -270,17 +270,13 @@ namespace MediaBrowser.XbmcMetadata.Parsers
 
 
                         if (!string.IsNullOrWhiteSpace(val))
                         if (!string.IsNullOrWhiteSpace(val))
                         {
                         {
-                            if (DateTime.TryParseExact(val, BaseNfoSaver.DateAddedFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var added))
-                            {
-                                item.DateCreated = added.ToUniversalTime();
-                            }
-                            else if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out added))
+                            if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var added))
                             {
                             {
                                 item.DateCreated = added.ToUniversalTime();
                                 item.DateCreated = added.ToUniversalTime();
                             }
                             }
                             else
                             else
                             {
                             {
-                                Logger.LogWarning("Invalid Added value found: " + val);
+                                Logger.LogWarning("Invalid Added value found: {Value}", val);
                             }
                             }
                         }
                         }
 
 
@@ -384,16 +380,8 @@ namespace MediaBrowser.XbmcMetadata.Parsers
                     }
                     }
 
 
                 case "tagline":
                 case "tagline":
-                    {
-                        var val = reader.ReadElementContentAsString();
-
-                        if (!string.IsNullOrWhiteSpace(val))
-                        {
-                            item.Tagline = val;
-                        }
-
-                        break;
-                    }
+                    item.Tagline = reader.ReadElementContentAsString();
+                    break;
 
 
                 case "country":
                 case "country":
                     {
                     {
@@ -710,6 +698,24 @@ namespace MediaBrowser.XbmcMetadata.Parsers
                         break;
                         break;
                     }
                     }
 
 
+                case "uniqueid":
+                    {
+                        if (reader.IsEmptyElement)
+                        {
+                            reader.Read();
+                            break;
+                        }
+
+                        var provider = reader.GetAttribute("type");
+                        var id = reader.ReadElementContentAsString();
+                        if (!string.IsNullOrWhiteSpace(provider) && !string.IsNullOrWhiteSpace(id))
+                        {
+                            item.SetProviderId(provider, id);
+                        }
+
+                        break;
+                    }
+
                 default:
                 default:
                     string readerName = reader.Name;
                     string readerName = reader.Name;
                     if (_validProviderIds.TryGetValue(readerName, out string? providerIdValue))
                     if (_validProviderIds.TryGetValue(readerName, out string? providerIdValue))

+ 31 - 4
tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs

@@ -16,8 +16,9 @@ namespace Jellyfin.XbmcMetadata.Parsers.Tests
 {
 {
     public class MovieNfoParserTests
     public class MovieNfoParserTests
     {
     {
-        [Fact]
-        public void Fetch_Valid_Succes()
+        private readonly MovieNfoParser _parser;
+
+        public MovieNfoParserTests()
         {
         {
             var providerManager = new Mock<IProviderManager>();
             var providerManager = new Mock<IProviderManager>();
             providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
             providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
@@ -25,13 +26,18 @@ namespace Jellyfin.XbmcMetadata.Parsers.Tests
             var config = new Mock<IConfigurationManager>();
             var config = new Mock<IConfigurationManager>();
             config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
             config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
                 .Returns(new XbmcMetadataOptions());
                 .Returns(new XbmcMetadataOptions());
-            var parser = new MovieNfoParser(new NullLogger<MovieNfoParser>(), config.Object, providerManager.Object);
+            _parser = new MovieNfoParser(new NullLogger<MovieNfoParser>(), config.Object, providerManager.Object);
+        }
 
 
+        [Fact]
+        public void Fetch_Valid_Succes()
+        {
             var result = new MetadataResult<Video>()
             var result = new MetadataResult<Video>()
             {
             {
                 Item = new Video()
                 Item = new Video()
             };
             };
-            parser.Fetch(result, "Test Data/Justice League.nfo", CancellationToken.None);
+
+            _parser.Fetch(result, "Test Data/Justice League.nfo", CancellationToken.None);
             var item = result.Item;
             var item = result.Item;
 
 
             Assert.Equal("Justice League", item.OriginalTitle);
             Assert.Equal("Justice League", item.OriginalTitle);
@@ -75,6 +81,27 @@ namespace Jellyfin.XbmcMetadata.Parsers.Tests
             Assert.Equal("Jason Momoa", aquaman!.Name);
             Assert.Equal("Jason Momoa", aquaman!.Name);
             Assert.Equal(5, aquaman!.SortOrder);
             Assert.Equal(5, aquaman!.SortOrder);
             Assert.Equal("https://m.media-amazon.com/images/M/MV5BMTI5MTU5NjM1MV5BMl5BanBnXkFtZTcwODc4MDk0Mw@@._V1_SX1024_SY1024_.jpg", aquaman!.ImageUrl);
             Assert.Equal("https://m.media-amazon.com/images/M/MV5BMTI5MTU5NjM1MV5BMl5BanBnXkFtZTcwODc4MDk0Mw@@._V1_SX1024_SY1024_.jpg", aquaman!.ImageUrl);
+
+            Assert.Equal(new DateTime(2019, 8, 6, 9, 1, 18), item.DateCreated);
+        }
+
+        [Fact]
+        public void Fetch_WithNullItem_ThrowsArgumentException()
+        {
+            var result = new MetadataResult<Video>();
+
+            Assert.Throws<ArgumentException>(() => _parser.Fetch(result, "Test Data/Justice League.nfo", CancellationToken.None));
+        }
+
+        [Fact]
+        public void Fetch_NullResult_ThrowsArgumentException()
+        {
+            var result = new MetadataResult<Video>()
+            {
+                Item = new Video()
+            };
+
+            Assert.Throws<ArgumentException>(() => _parser.Fetch(result, string.Empty, CancellationToken.None));
         }
         }
     }
     }
 }
 }

+ 91 - 0
tests/Jellyfin.XbmcMetadata.Tests/Parsers/SeriesNfoParserTests.cs

@@ -0,0 +1,91 @@
+using System;
+using System.Linq;
+using System.Threading;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Providers;
+using MediaBrowser.XbmcMetadata.Parsers;
+using Microsoft.Extensions.Logging.Abstractions;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.XbmcMetadata.Parsers.Tests
+{
+    public class SeriesNfoParserTests
+    {
+        private readonly SeriesNfoParser _parser;
+
+        public SeriesNfoParserTests()
+        {
+            var providerManager = new Mock<IProviderManager>();
+            providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
+                .Returns(Enumerable.Empty<ExternalIdInfo>());
+            var config = new Mock<IConfigurationManager>();
+            config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
+                .Returns(new XbmcMetadataOptions());
+            _parser = new SeriesNfoParser(new NullLogger<SeriesNfoParser>(), config.Object, providerManager.Object);
+        }
+
+        [Fact]
+        public void Fetch_Valid_Succes()
+        {
+            var result = new MetadataResult<Series>()
+            {
+                Item = new Series()
+            };
+
+            _parser.Fetch(result, "Test Data/American Gods.nfo", CancellationToken.None);
+            var item = result.Item;
+
+            Assert.Equal("American Gods", item.OriginalTitle);
+            Assert.Equal(string.Empty, item.Tagline);
+            Assert.Equal(0, item.RunTimeTicks);
+            Assert.Equal("46639", item.ProviderIds["tmdb"]);
+            Assert.Equal("253573", item.ProviderIds["tvdb"]);
+
+            Assert.Equal(3, item.Genres.Length);
+            Assert.Contains("Drama", item.Genres);
+            Assert.Contains("Mystery", item.Genres);
+            Assert.Contains("Sci-Fi & Fantasy", item.Genres);
+
+            Assert.Equal(new DateTime(2017, 4, 30), item.PremiereDate);
+            Assert.Single(item.Studios);
+            Assert.Contains("Starz", item.Studios);
+
+            Assert.Equal(6, result.People.Count);
+
+            Assert.True(result.People.All(x => x.Type == PersonType.Actor));
+
+            // Only test one actor
+            var sweeney = result.People.FirstOrDefault(x => x.Role.Equals("Mad Sweeney", StringComparison.Ordinal));
+            Assert.NotNull(sweeney);
+            Assert.Equal("Pablo Schreiber", sweeney!.Name);
+            Assert.Equal(3, sweeney!.SortOrder);
+            Assert.Equal("http://image.tmdb.org/t/p/original/uo8YljeePz3pbj7gvWXdB4gOOW4.jpg", sweeney!.ImageUrl);
+
+            Assert.Equal(new DateTime(2017, 10, 7, 14, 25, 47), item.DateCreated);
+        }
+
+        [Fact]
+        public void Fetch_WithNullItem_ThrowsArgumentException()
+        {
+            var result = new MetadataResult<Series>();
+
+            Assert.Throws<ArgumentException>(() => _parser.Fetch(result, "Test Data/American Gods.nfo", CancellationToken.None));
+        }
+
+        [Fact]
+        public void Fetch_NullResult_ThrowsArgumentException()
+        {
+            var result = new MetadataResult<Series>()
+            {
+                Item = new Series()
+            };
+
+            Assert.Throws<ArgumentException>(() => _parser.Fetch(result, string.Empty, CancellationToken.None));
+        }
+    }
+}

+ 185 - 0
tests/Jellyfin.XbmcMetadata.Tests/Test Data/American Gods.nfo

@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<tvshow>
+    <title>American Gods</title>
+    <originaltitle>American Gods</originaltitle>
+    <showtitle>American Gods</showtitle>
+    <sorttitle>American Gods</sorttitle>
+    <ratings>
+        <rating name="themoviedb" max="10" default="true">
+            <value>6.800000</value>
+            <votes>581</votes>
+        </rating>
+        <rating name="imdb" max="10" default="true">
+            <value>5.500000</value>
+            <votes>86352</votes>
+        </rating>
+        <rating name="metacritic" max="10">
+            <value>6.0</value>
+            <votes>22</votes>
+        </rating>
+		<rating name="tomatometerallcritics" max="10">
+			<value>7.6</value>
+			<votes>71</votes>
+		</rating>
+		<rating name="tomatometerallaudience" max="10">
+			<value>6.2</value>
+			<votes>119873</votes>
+		</rating>
+    </ratings>
+    <userrating>0</userrating>
+    <top250>0</top250>
+    <season>2</season>
+    <episode>16</episode>
+    <displayseason>-1</displayseason>
+    <displayepisode>-1</displayepisode>
+    <outline></outline>
+    <plot>An ex-con becomes the traveling partner of a conman who turns out to be one of the older gods trying to recruit troops to battle the upstart deities. Based on Neil Gaiman&apos;s fantasy novel.</plot>
+    <tagline></tagline>
+    <runtime>0</runtime>
+    <thumb aspect="poster" preview="https://assets.fanart.tv/preview/tv/253573/tvposter/american-gods-58b18cd8d667a.jpg">https://assets.fanart.tv/fanart/tv/253573/tvposter/american-gods-58b18cd8d667a.jpg</thumb>
+    <thumb aspect="poster" preview="https://assets.fanart.tv/preview/tv/253573/tvposter/american-gods-5c896dbee9d21.jpg">https://assets.fanart.tv/fanart/tv/253573/tvposter/american-gods-5c896dbee9d21.jpg</thumb>
+    <thumb aspect="poster" preview="https://assets.fanart.tv/preview/tv/253573/tvposter/american-gods-57dda913a44e0.jpg">https://assets.fanart.tv/fanart/tv/253573/tvposter/american-gods-57dda913a44e0.jpg</thumb>
+    <thumb aspect="poster" preview="https://assets.fanart.tv/preview/tv/253573/tvposter/american-gods-590c159dcbf3a.jpg">https://assets.fanart.tv/fanart/tv/253573/tvposter/american-gods-590c159dcbf3a.jpg</thumb>
+    <thumb aspect="banner" preview="https://assets.fanart.tv/preview/tv/253573/tvbanner/american-gods-5cbbdaa84298d.jpg">https://assets.fanart.tv/fanart/tv/253573/tvbanner/american-gods-5cbbdaa84298d.jpg</thumb>
+    <thumb aspect="banner" preview="https://assets.fanart.tv/preview/tv/253573/tvbanner/american-gods-5932b1ffb3522.jpg">https://assets.fanart.tv/fanart/tv/253573/tvbanner/american-gods-5932b1ffb3522.jpg</thumb>
+    <thumb aspect="banner" preview="https://assets.fanart.tv/preview/tv/253573/tvbanner/american-gods-5932b1ffb43e4.jpg">https://assets.fanart.tv/fanart/tv/253573/tvbanner/american-gods-5932b1ffb43e4.jpg</thumb>
+    <thumb aspect="landscape" preview="https://assets.fanart.tv/preview/tv/253573/tvthumb/american-gods-58db45dc886f5.jpg">https://assets.fanart.tv/fanart/tv/253573/tvthumb/american-gods-58db45dc886f5.jpg</thumb>
+    <thumb aspect="landscape" preview="https://assets.fanart.tv/preview/tv/253573/tvthumb/american-gods-5932aee79947a.jpg">https://assets.fanart.tv/fanart/tv/253573/tvthumb/american-gods-5932aee79947a.jpg</thumb>
+    <thumb aspect="landscape" preview="https://assets.fanart.tv/preview/tv/253573/tvthumb/american-gods-5932aee799e5a.jpg">https://assets.fanart.tv/fanart/tv/253573/tvthumb/american-gods-5932aee799e5a.jpg</thumb>
+    <thumb aspect="landscape" preview="https://assets.fanart.tv/preview/tv/253573/tvthumb/american-gods-5932aee79a2f2.jpg">https://assets.fanart.tv/fanart/tv/253573/tvthumb/american-gods-5932aee79a2f2.jpg</thumb>
+    <thumb aspect="landscape" preview="https://assets.fanart.tv/preview/tv/253573/tvthumb/american-gods-5932aee79a7c9.jpg">https://assets.fanart.tv/fanart/tv/253573/tvthumb/american-gods-5932aee79a7c9.jpg</thumb>
+    <thumb aspect="clearlogo" preview="https://assets.fanart.tv/preview/tv/253573/hdtvlogo/american-gods-58b04bdcecefd.png">https://assets.fanart.tv/fanart/tv/253573/hdtvlogo/american-gods-58b04bdcecefd.png</thumb>
+    <thumb aspect="clearlogo" preview="https://assets.fanart.tv/preview/tv/253573/hdtvlogo/american-gods-58b04d78a7ffc.png">https://assets.fanart.tv/fanart/tv/253573/hdtvlogo/american-gods-58b04d78a7ffc.png</thumb>
+    <thumb aspect="clearlogo" preview="https://assets.fanart.tv/preview/tv/253573/hdtvlogo/american-gods-59e6660cb7dbc.png">https://assets.fanart.tv/fanart/tv/253573/hdtvlogo/american-gods-59e6660cb7dbc.png</thumb>
+    <thumb aspect="clearlogo" preview="https://assets.fanart.tv/preview/tv/253573/hdtvlogo/american-gods-59e6660cc0716.png">https://assets.fanart.tv/fanart/tv/253573/hdtvlogo/american-gods-59e6660cc0716.png</thumb>
+    <thumb aspect="clearart" preview="https://assets.fanart.tv/preview/tv/253573/hdclearart/american-gods-59177740ba6cd.png">https://assets.fanart.tv/fanart/tv/253573/hdclearart/american-gods-59177740ba6cd.png</thumb>
+    <thumb aspect="clearart" preview="https://assets.fanart.tv/preview/tv/253573/hdclearart/american-gods-5913b6b2ce91d.png">https://assets.fanart.tv/fanart/tv/253573/hdclearart/american-gods-5913b6b2ce91d.png</thumb>
+    <thumb aspect="clearart" preview="https://assets.fanart.tv/preview/tv/253573/hdclearart/american-gods-5913b6b2cfa64.png">https://assets.fanart.tv/fanart/tv/253573/hdclearart/american-gods-5913b6b2cfa64.png</thumb>
+    <thumb aspect="clearart" preview="https://assets.fanart.tv/preview/tv/253573/hdclearart/american-gods-5913b6b2cf502.png">https://assets.fanart.tv/fanart/tv/253573/hdclearart/american-gods-5913b6b2cf502.png</thumb>
+    <thumb aspect="clearart" preview="https://assets.fanart.tv/preview/tv/253573/hdclearart/american-gods-5a4805be0619f.png">https://assets.fanart.tv/fanart/tv/253573/hdclearart/american-gods-5a4805be0619f.png</thumb>
+    <thumb aspect="characterart" preview="https://assets.fanart.tv/preview/tv/253573/characterart/american-gods-5a4805af07a04.png">https://assets.fanart.tv/fanart/tv/253573/characterart/american-gods-5a4805af07a04.png</thumb>
+    <thumb aspect="characterart" preview="https://assets.fanart.tv/preview/tv/253573/characterart/american-gods-59e6b1c71b65a.png">https://assets.fanart.tv/fanart/tv/253573/characterart/american-gods-59e6b1c71b65a.png</thumb>
+    <thumb aspect="poster" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5d1274a8c31cb.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5d1274a8c31cb.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-59fea294b565f.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-59fea294b565f.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5cacdf37068db.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5cacdf37068db.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5cacdf7783e04.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5cacdf7783e04.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5d1274a8c31cb.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5d1274a8c31cb.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-59fea294b565f.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-59fea294b565f.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5cacdf37068db.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5cacdf37068db.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonposter/american-gods-5cacdf7783e04.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonposter/american-gods-5cacdf7783e04.jpg</thumb>
+    <thumb aspect="banner" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonbanner/american-gods-5cc6b35699d26.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonbanner/american-gods-5cc6b35699d26.jpg</thumb>
+    <thumb aspect="banner" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonbanner/american-gods-5cc6b36965b54.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonbanner/american-gods-5cc6b36965b54.jpg</thumb>
+    <thumb aspect="banner" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonbanner/american-gods-5cc6b35699d26.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonbanner/american-gods-5cc6b35699d26.jpg</thumb>
+    <thumb aspect="banner" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonbanner/american-gods-5cc6b36965b54.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonbanner/american-gods-5cc6b36965b54.jpg</thumb>
+    <thumb aspect="landscape" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonthumb/american-gods-5cc6b380d6c56.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonthumb/american-gods-5cc6b380d6c56.jpg</thumb>
+    <thumb aspect="landscape" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonthumb/american-gods-59e6b5a03e7aa.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonthumb/american-gods-59e6b5a03e7aa.jpg</thumb>
+    <thumb aspect="landscape" type="season" season="2" preview="https://assets.fanart.tv/preview/tv/253573/seasonthumb/american-gods-5cc6b380d6c56.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonthumb/american-gods-5cc6b380d6c56.jpg</thumb>
+    <thumb aspect="landscape" type="season" season="1" preview="https://assets.fanart.tv/preview/tv/253573/seasonthumb/american-gods-59e6b5a03e7aa.jpg">https://assets.fanart.tv/fanart/tv/253573/seasonthumb/american-gods-59e6b5a03e7aa.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/m6qf6lq3yARgbZwspvDLbUFtASh.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/gevw5nZRYz2kWj1PqW9pz4sgeeZ.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/btwTe5cQbGWGOErBiRqnjNP9cJl.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/loJ4sfr4zp995qMoeCHiIIGaOg8.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/dHo8Lw7ruIaQTdTTDZPCMyZxwy5.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/zfAXP4bG2G17VuLNU9cqRcVU0xj.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/oxYUbNpG2st2zXWzYRvewehmvuj.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/mwoQ6zynu2DBxKCBYi30qoM236N.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/8XEoXAMzgcf7m1KiUDZ9N1UGh4o.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/rWsayJB1grML2LdPjjKDC3g0Brr.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/8qRsj8uJ4zPARQmQ9FvejTY1lnV.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/acjnZP0GrwWDxCxV6QejKizbzOy.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/hN1sI57QILGfdrEOqpUfo0NtHjW.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/hz2jNy3DfseYzRSybGRlUtz4pTi.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/hLDgNDdrkB0oWiuClpxN4E3XadJ.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/4FiqawHsVz1mYCRudPtXKbfmP4M.jpg</thumb>
+    <thumb aspect="poster">http://image.tmdb.org/t/p/original/sKR8Q36YBtyRc19y4yGYuD1xBgA.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/4l8Vnbb7e5QA6bAItMqQIHXLRgc.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/ni0thXw5Zi5dQKBY6Oj0vcfIS2n.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/v17HfCzWKQKOBrww9RxZmN5R9tF.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/2ffvlgYsxbXGiWkc3V6Q8tgpiBo.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1">http://image.tmdb.org/t/p/original/rASj7OUjWDhfhAeO2MaFOA3lJpQ.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1">http://image.tmdb.org/t/p/original/67exRijfvN5RRmBCqFtk1bhJ7Uh.jpg</thumb>
+    <thumb aspect="poster" type="season" season="1">http://image.tmdb.org/t/p/original/59iE3xxP7H8rAiXW6TDR2HSoUUm.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/4l8Vnbb7e5QA6bAItMqQIHXLRgc.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/ni0thXw5Zi5dQKBY6Oj0vcfIS2n.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/v17HfCzWKQKOBrww9RxZmN5R9tF.jpg</thumb>
+    <thumb aspect="poster" type="season" season="2">http://image.tmdb.org/t/p/original/2ffvlgYsxbXGiWkc3V6Q8tgpiBo.jpg</thumb>
+    <thumb aspect="banner">https://thetvdb.com/banners/graphical/253573-g3.jpg</thumb>
+    <thumb aspect="banner">https://thetvdb.com/banners/graphical/253573-g4.jpg</thumb>
+    <thumb aspect="banner">https://thetvdb.com/banners/graphical/253573-g2.jpg</thumb>
+    <thumb aspect="banner">https://thetvdb.com/banners/graphical/253573-g.jpg</thumb>
+    <thumb aspect="banner">https://thetvdb.com/banners/graphical/253573-g5.jpg</thumb>
+    <fanart>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5c8965c58e778.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5c8965c58e778.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-59e6a8a495c2a.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-59e6a8a495c2a.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-59e6b13827ba2.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-59e6b13827ba2.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e07ad.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e07ad.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e2913.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e2913.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e0000.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e0000.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e0d3a.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e0d3a.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e1395.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e1395.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e1952.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e1952.jpg</thumb>
+        <thumb preview="https://assets.fanart.tv/preview/tv/253573/showbackground/american-gods-5932b089e23ca.jpg">https://assets.fanart.tv/fanart/tv/253573/showbackground/american-gods-5932b089e23ca.jpg</thumb>
+    </fanart>
+    <mpaa>Australia:MA</mpaa>
+    <playcount>0</playcount>
+    <lastplayed></lastplayed>
+    <episodeguide>
+        <url cache="tmdb-46639-en.json">http://api.themoviedb.org/3/tv/46639?api_key=6a5be4999abf74eba1f9a8311294c267&amp;language=en</url>
+    </episodeguide>
+    <id>46639</id>
+    <uniqueid type="tmdb" default="true">46639</uniqueid>
+    <uniqueid type="tvdb">253573</uniqueid>
+    <genre>Drama</genre>
+    <genre>Mystery</genre>
+    <genre>Sci-Fi &amp; Fantasy</genre>
+    <premiered>2017-04-30</premiered>
+    <year>2017</year>
+    <status></status>
+    <code></code>
+    <aired></aired>
+    <studio>Starz</studio>
+    <trailer></trailer>
+    <actor>
+        <name>Ricky Whittle</name>
+        <role>Shadow Moon</role>
+        <order>0</order>
+        <thumb>http://image.tmdb.org/t/p/original/cjeDbVfBp6Qvb3C74Dfy7BKDTQN.jpg</thumb>
+    </actor>
+    <actor>
+        <name>Ian McShane</name>
+        <role>Mr. Wednesday</role>
+        <order>1</order>
+        <thumb>http://image.tmdb.org/t/p/original/pY9ud4BJwHekNiO4MMItPbgkdAy.jpg</thumb>
+    </actor>
+    <actor>
+        <name>Emily Browning</name>
+        <role>Laura Moon</role>
+        <order>2</order>
+        <thumb>http://image.tmdb.org/t/p/original/fa1Kyj02wxwcdS6EHb2i27TNXvU.jpg</thumb>
+    </actor>
+    <actor>
+        <name>Pablo Schreiber</name>
+        <role>Mad Sweeney</role>
+        <order>3</order>
+        <thumb>http://image.tmdb.org/t/p/original/uo8YljeePz3pbj7gvWXdB4gOOW4.jpg</thumb>
+    </actor>
+    <actor>
+        <name>Bruce Langley</name>
+        <role>Technical Boy</role>
+        <order>4</order>
+        <thumb>http://image.tmdb.org/t/p/original/f4EOWUmznLqboq8Ce7jnlkHVK3Y.jpg</thumb>
+    </actor>
+    <actor>
+        <name>Yetide Badaki</name>
+        <role>Bilquis</role>
+        <order>5</order>
+        <thumb>http://image.tmdb.org/t/p/original/qfzkREHuI1JvMxBteIAjKX8qMEr.jpg</thumb>
+    </actor>
+    <namedseason number="1">Season 1</namedseason>
+    <namedseason number="2">Season 2</namedseason>
+    <resume>
+        <position>0.000000</position>
+        <total>0.000000</total>
+    </resume>
+    <dateadded>2017-10-07 14:25:47</dateadded>
+</tvshow>