Ejemplo n.º 1
0
        // ReSharper disable once InconsistentNaming
        public async void GetEpisodesAsync_With_Query_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const int    Id    = 42;
            const int    Page  = 2;
            const string Route = "/series/42/episodes/query?page=2&airedSeason=1&imdbId=tt0118480";

            var query = new EpisodeQuery
            {
                ImdbId      = "tt0118480",
                AiredSeason = 1
            };

            var expectedData = new TvDbResponse <BasicEpisode[]>();

            jsonClient.GetJsonAsync <TvDbResponse <BasicEpisode[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetEpisodesAsync(Id, Page, query, CancellationToken.None);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <BasicEpisode[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 2
0
        public Task GetAllAsync_IgnoresLanguagesWithNullValues()
        {
            ApiResponse response = new ApiResponse
            {
                Body =
                    "{\"data\":[" +
                    "{\"id\":null,\"abbreviation\":\"yue\",\"name\":\"广东话\",\"englishName\":\"Chinese - Cantonese\"}," +
                    "{\"id\":101,\"abbreviation\":\"aa\",\"name\":\"Afaraf\",\"englishName\":\"Afar\"}" +
                    "]}",
                StatusCode = 200
            };
            TvDbResponse <Language[]> originalResponse = new Parser().Parse <TvDbResponse <Language[]> >(response, ErrorMessages.Languages.GetAllAsync);
            TvDbResponse <Language[]> expectedResponse = new TvDbResponse <Language[]>();

            expectedResponse.Data = new Language[2];
            Array.Copy(originalResponse.Data, 0, expectedResponse.Data, 0, originalResponse.Data.Length);
            return(CreateClient(response)
                   .WithErrorMap(ErrorMessages.Languages.GetAllAsync)
                   .WhenCallingAMethod((impl, token) => impl.GetAllAsync(token))
                   .ShouldRequest("GET", "/languages")
                   .AssertReturnValue((actualResponse) =>
            {
                Assert.Equal(expectedResponse, actualResponse);
            })
                   .SetResultObject(expectedResponse).RunAsync());
        }
Ejemplo n.º 3
0
        // ReSharper disable once InconsistentNaming
        public async Task PopulateActorsAsync_should_add_existing_actors()
        {
            var repository = Substitute.For<IActorsRepository>();
            var client = Substitute.For<ISeriesClient>();

            var response = new TvDbResponse<ActorData[]>();

            var data = new List<ActorData>();

            for (int i = 0; i < 5; i++)
            {
                data.Add(new ActorData
                {
                    Id = i,
                    Name = $"Actor {i}",
                    LastUpdated = $"0001-02-0{i + 1}",
                    Image = $"Image {i}"
                });
            }

            response.Data = data.ToArray();

            var show = new Show
            {
                TheTvDbId = 42
            };

            var actors = response.Data.Select(x => new Actor
                                 {
                                     TheTvDbId = x.Id
                                 }).ToArray();

            RigRepository(repository, actors);
            RigClient(client, show.TheTvDbId, response);

            var fetcher = new ActorFetcher(repository, client);

            await fetcher.PopulateActorsAsync(show);

            var relationships = show.ShowsActors.ToArray();

            Assert.Equal(response.Data.Length, relationships.Length);

            for (int i = 0; i < response.Data.Length; i++)
            {
                Assert.Equal(actors[i], relationships[i].Actor);
                Assert.Equal(response.Data[i].Role, relationships[i].Role);

                Assert.Equal(response.Data[i].Id, actors[i].TheTvDbId);
                Assert.Equal(response.Data[i].Name, actors[i].Name);
                Assert.Equal(response.Data[i].Image, actors[i].Image);
                Assert.Equal(response.Data[i].LastUpdated, actors[i].LastUpdated.ToString("yyyy-MM-dd"));
            }
        }
Ejemplo n.º 4
0
        public tvShows(TvDbResponse <SeriesSearchResult[]> results, string searchString)
        {
            //lstTvShow = new List<tvShow>();

            foreach (var series in results.Data)
            {
                tvShow show = ConvertTvDbSeriesToTvShow(series.Id, series.SeriesName, series.Overview, series.FirstAired, searchString);
                base.Add(show);
            }
            base.Sort((x, y) => x.distance.CompareTo(y.distance));
        }
Ejemplo n.º 5
0
        public async Task <TvDbResponse <Language[]> > GetAllAsync(CancellationToken cancellationToken)
        {
            var request  = new ApiRequest("GET", "/languages");
            var response = await this.ApiClient.SendRequestAsync(request, cancellationToken).ConfigureAwait(false);

            TvDbResponse <Language[]> parsedResponse = this.Parser.Parse <TvDbResponse <Language[]> >(response, ErrorMessages.Languages.GetAllAsync);

            if (parsedResponse.Data != null)
            {
                parsedResponse.Data = Array.FindAll(parsedResponse.Data, language => language.Id != null);
            }
            return(parsedResponse);
        }
Ejemplo n.º 6
0
        // ReSharper disable once InconsistentNaming
        public async void GetAllAsync_Without_CancellationToken_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const string Route = "/languages";

            var expectedData = new TvDbResponse <Language[]>();

            jsonClient.GetJsonAsync <TvDbResponse <Language[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetAllAsync();

            await jsonClient.Received().GetJsonAsync <TvDbResponse <Language[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 7
0
        // ReSharper disable once InconsistentNaming
        public async void GetActorsAsync_With_CancellationToken_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const int    Id    = 42;
            const string Route = "/series/42/actors";

            var expectedData = new TvDbResponse <Actor[]>();

            jsonClient.GetJsonAsync <TvDbResponse <Actor[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetActorsAsync(Id);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <Actor[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 8
0
        // ReSharper disable once InconsistentNaming
        public async void GetEpisodesSummaryAsync_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const int    Id    = 42;
            const string Route = "/series/42/episodes/summary";

            var expectedData = new TvDbResponse <EpisodesSummary>();

            jsonClient.GetJsonAsync <TvDbResponse <EpisodesSummary> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetEpisodesSummaryAsync(Id, CancellationToken.None);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <EpisodesSummary> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 9
0
        // ReSharper disable once InconsistentNaming
        public async void GetAsync_Without_CancellationToken_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const string Route = "/updated/query?fromTime=1475280000";
            DateTime     from  = new DateTime(2016, 10, 1);

            var expectedData = new TvDbResponse <Update[]>();

            jsonClient.GetJsonAsync <TvDbResponse <Update[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetAsync(from);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <Update[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 10
0
        // ReSharper disable once InconsistentNaming
        public async void GetAsync_With_Filter_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const int          Id     = 42;
            const string       Route  = "/series/42/filter?keys=added,id";
            const SeriesFilter Filter = SeriesFilter.Id | SeriesFilter.Added;

            var expectedData = new TvDbResponse <Series>();

            jsonClient.GetJsonAsync <TvDbResponse <Series> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetAsync(Id, Filter, CancellationToken.None);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <Series> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 11
0
        // ReSharper disable once InconsistentNaming
        public async void SearchSeriesByNameAsync_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const string Name = "Doctor Who";

            const string Route = "/search/series?name=Doctor Who";

            var expectedData = new TvDbResponse <SeriesSearchResult[]>();

            jsonClient.GetJsonAsync <TvDbResponse <SeriesSearchResult[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.SearchSeriesByNameAsync(Name, CancellationToken.None);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <SeriesSearchResult[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 12
0
        // ReSharper disable once InconsistentNaming
        public async void SearchSeriesByZap2itIdAsync_Without_CancellationToken_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const string Zap2ItId = "SH007501780000";

            const string Route = "/search/series?zap2itId=SH007501780000";

            var expectedData = new TvDbResponse <SeriesSearchResult[]>();

            jsonClient.GetJsonAsync <TvDbResponse <SeriesSearchResult[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.SearchSeriesByZap2ItIdAsync(Zap2ItId);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <SeriesSearchResult[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
Ejemplo n.º 13
0
        private async Task <string> GetSeriesByRemoteId(string id, string idType, string language, CancellationToken cancellationToken)
        {
            TvDbResponse <SeriesSearchResult[]> result = null;

            try
            {
                if (string.Equals(idType, MetadataProvider.Zap2It.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    result = await _tvdbClientManager.GetSeriesByZap2ItIdAsync(id, language, cancellationToken)
                             .ConfigureAwait(false);
                }
                else
                {
                    result = await _tvdbClientManager.GetSeriesByImdbIdAsync(id, language, cancellationToken)
                             .ConfigureAwait(false);
                }
            }
            catch (TvDbServerException e)
            {
                _logger.LogError(e, "Failed to retrieve series with remote id {RemoteId}", id);
            }

            return(result?.Data.First().Id.ToString());
        }
Ejemplo n.º 14
0
        // ReSharper disable once InconsistentNaming
        public async void GetImagesSummaryAsync_With_CancellationToken_Makes_The_Right_Request()
        {
            var jsonClient = CreateJsonClient();
            var client     = this.CreateClient(jsonClient);

            const int    Id    = 42;
            const string Route = "/series/42/images/query?keyType=Fanart&resolution=1280x720";

            var query = new ImagesQuery
            {
                KeyType    = KeyType.Fanart,
                Resolution = "1280x720"
            };

            var expectedData = new TvDbResponse <Image[]>();

            jsonClient.GetJsonAsync <TvDbResponse <Image[]> >(Route, CancellationToken.None).Returns(expectedData);

            var responseData = await client.GetImagesAsync(Id, query);

            await jsonClient.Received().GetJsonAsync <TvDbResponse <Image[]> >(Route, CancellationToken.None);

            Assert.Equal(expectedData, responseData);
        }
        private Either <FailedRequest, Response <TResponseData> > ParseResponse <TResponseType, TResponseData>(TvDbResponse <TResponseType> response)
        {
            if (response.Data == null && response.Errors?.InvalidFilters?.Any() == true || response.Errors?.InvalidLanguage?.Any() == true || response.Errors?.InvalidQueryParams?.Any() == true)
            {
                return(new FailedRequest(HttpStatusCode.OK, response.ToString()));
            }

            // Perform mapping
            var data = this.dataMapper.Map <TResponseType, TResponseData>(response.Data);

            return(new Response <TResponseData>(data));
        }
Ejemplo n.º 16
0
        // ReSharper disable once InconsistentNaming
        public async Task PopulateEpisodeAsync_should_map_the_episode()
        {
            var episodesClient = Substitute.For<IEpisodesClient>();

            var fetcher = new EpisodeFetcher(episodesClient, Substitute.For<IAdvancedEpisodeClient>(),
                Substitute.For<IAdvancedSeriesClient>());

            var episode = new Episode
            {
                TheTvDbId = 42
            };

            var response = new TvDbResponse<EpisodeRecord>
            {
                Data = new EpisodeRecord
                {
                    Id = 42,
                    EpisodeName = "Rose",
                    Overview = "Rose Tyler stumbles across a man called The Doctor...",
                    ImdbId = "tt0562992",
                    AiredEpisodeNumber = 1,
                    AiredSeason = 1,
                    FirstAired = "2005-03-26",
                    LastUpdated = 1477941112
                }
            };

            episodesClient.GetAsync(episode.TheTvDbId).Returns(response);

            await fetcher.PopulateEpisodeAsync(episode);

            var record = response.Data;

            Assert.Equal(record.EpisodeName, episode.Title);
            Assert.Equal(record.Overview, episode.Description);
            Assert.Equal(record.ImdbId, episode.ImdbId);
            Assert.Equal(record.AiredEpisodeNumber, episode.Number);
            Assert.Equal(record.AiredSeason, episode.SeasonNumber);

            Assert.Equal(new DateTime(2005, 3, 26), episode.FirstAired);

            Assert.Equal(new DateTime(2016, 10, 31, 19, 11, 52), episode.LastUpdated);
        }
Ejemplo n.º 17
0
        // ReSharper disable once InconsistentNaming
        public async Task PopulateEpisodeAsync_should_call_the_client()
        {
            var episodesClient = Substitute.For<IEpisodesClient>();

            var fetcher = new EpisodeFetcher(episodesClient, Substitute.For<IAdvancedEpisodeClient>(),
                Substitute.For<IAdvancedSeriesClient>());

            var episode = new Episode
            {
                TheTvDbId = 42
            };

            var response = new TvDbResponse<EpisodeRecord>
            {
                Data = new EpisodeRecord
                {
                    Id = 42,
                    AiredSeason = 1,
                    AiredEpisodeNumber = 1
                }
            };

            episodesClient.GetAsync(episode.TheTvDbId).Returns(response);

            await fetcher.PopulateEpisodeAsync(episode);

            await episodesClient.Received().GetAsync(episode.TheTvDbId);
        }
Ejemplo n.º 18
0
 private static void RigClient(ISeriesClient client, int theTvDbId, TvDbResponse<ActorData[]> actorResponse)
 {
     client.GetActorsAsync(theTvDbId).Returns(actorResponse);
 }
Ejemplo n.º 19
0
        // ReSharper disable once InconsistentNaming
        public async Task PopulateActorsAsync_should_update_role_on_existing_actor()
        {
            var repository = Substitute.For<IActorsRepository>();
            var client = Substitute.For<ISeriesClient>();

            var response = new TvDbResponse<ActorData[]>
            {
                Data = new[]
                {
                    new ActorData
                    {
                        Id = 1,
                        Name = "Actor 1",
                        LastUpdated = "0001-02-01",
                        Image = "Image 1",
                        Role = "Role 1"
                    }
                }
            };

            var actor = new Actor
            {
                TheTvDbId = 1
            };

            var show = new Show
            {
                TheTvDbId = 42,
                ShowsActors = {
                    new ShowsActors
                    {
                        Actor = actor
                    }
                }
            };

            var actors = new List<Actor>
            {
                actor
            };

            RigRepository(repository, actors.ToArray());
            RigClient(client, show.TheTvDbId, response);

            var fetcher = new ActorFetcher(repository, client);

            await fetcher.PopulateActorsAsync(show);

            Assert.Equal(response.Data.First().Role, show.ShowsActors.First().Role);
        }
Ejemplo n.º 20
0
        // ReSharper disable once InconsistentNaming
        public async Task PopulateActorsAsync_should_query_actors_from_the_repository()
        {
            var repository = Substitute.For<IActorsRepository>();
            var client = Substitute.For<ISeriesClient>();

            var expectedIds = new[]
            {
                1,
                2,
                3
            };

            var actors = new Actor[0];

            var show = new Show
            {
                TheTvDbId = 42
            };

            var actorsResponse = new TvDbResponse<ActorData[]>
            {
                Data = new[]
                {
                    new ActorData
                    {
                        Id = 1,
                        LastUpdated = DefaultLastUpdated
                    },
                    new ActorData
                    {
                        Id = 2,
                        LastUpdated = DefaultLastUpdated
                    },
                    new ActorData
                    {
                        Id = 3,
                        LastUpdated = DefaultLastUpdated
                    }
                }
            };

            RigRepository(repository, actors, expectedIds);
            RigClient(client, show.TheTvDbId, actorsResponse);

            var fetcher = new ActorFetcher(repository, client);
            await fetcher.PopulateActorsAsync(show);

            await repository.Received().GetActorsByTheTvDbIdsAsync(Arg.Is<int[]>(x => x.All(expectedIds.Contains)));
        }
Ejemplo n.º 21
0
        public async Task <bool> process(
            string filePath,
            Action <string> setPath,
            Action <string, MessageType> setStatus,
            Func <List <Tuple <string, string> >, int> selectResult,
            AutoTagConfig config
            )
        {
            if (tvdb.Authentication.Token == null)
            {
                await tvdb.Authentication.AuthenticateAsync(apiKey);
            }

            FileMetadata result = new FileMetadata(FileMetadata.Types.TV);

            #region Filename parsing
            FileMetadata episodeData;

            if (string.IsNullOrEmpty(config.parsePattern))
            {
                try {
                    episodeData = EpisodeParser.ParseEpisodeInfo(Path.GetFileName(filePath)); // Parse info from filename
                } catch (FormatException ex) {
                    setStatus($"Error: {ex.Message}", MessageType.Error);
                    return(false);
                }
            }
            else
            {
                try {
                    var match = Regex.Match(Path.GetFullPath(filePath), config.parsePattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

                    episodeData            = new FileMetadata(FileMetadata.Types.TV);
                    episodeData.SeriesName = match.Groups["SeriesName"].Value;
                    episodeData.Season     = int.Parse(match.Groups["Season"].Value);
                    episodeData.Episode    = int.Parse(match.Groups["Episode"].Value);
                } catch (FormatException ex) {
                    if (config.verbose)
                    {
                        setStatus($"Error: Unable to parse required information from filename ({ex.GetType().Name}: {ex.Message})", MessageType.Error);
                    }
                    else
                    {
                        setStatus($"Error: Unable to parse required information from filename", MessageType.Error);
                    }
                    return(false);
                }
            }

            result.Season  = episodeData.Season;
            result.Episode = episodeData.Episode;

            setStatus($"Parsed file as {episodeData}", MessageType.Information);
            #endregion

            #region TVDB API searching
            if (!seriesResultCache.ContainsKey(episodeData.SeriesName))   // if not already searched for series
            {
                TvDbResponse <SeriesSearchResult[]> seriesIdResponse;
                try {
                    seriesIdResponse = await tvdb.Search.SearchSeriesByNameAsync(episodeData.SeriesName);
                } catch (TvDbServerException ex) {
                    if (config.verbose)
                    {
                        setStatus($"Error: Cannot find series {episodeData.SeriesName} ({ex.GetType().Name}: {ex.Message})", MessageType.Error);
                    }
                    else
                    {
                        setStatus($"Error: Cannot find series {episodeData.SeriesName} on TheTVDB", MessageType.Error);
                    }
                    return(false);
                }

                // sort results by similarity to parsed series name
                List <SeriesSearchResult> seriesResults = seriesIdResponse.Data
                                                          .OrderByDescending(seriesResult => SeriesNameSimilarity(episodeData.SeriesName, seriesResult.SeriesName))
                                                          .ToList();

                if (config.manualMode && seriesResults.Count > 1)
                {
                    int chosen = selectResult(seriesResults.Select(
                                                  r => new Tuple <string, string>(r.SeriesName, r.FirstAired ?? "Unknown")
                                                  ).ToList()
                                              );

                    // add only the chosen series to cache if in manual mode
                    seriesResultCache.Add(episodeData.SeriesName, new List <SeriesSearchResult> {
                        seriesResults[chosen]
                    });
                }
                else
                {
                    seriesResultCache.Add(episodeData.SeriesName, seriesResults);
                }
            }

            // try searching for each series search result
            foreach (var series in seriesResultCache[episodeData.SeriesName])
            {
                result.Id         = series.Id;
                result.SeriesName = series.SeriesName;

                try {
                    TvDbResponse <EpisodeRecord[]> episodeResponse = await tvdb.Series.GetEpisodesAsync(series.Id, 1,
                                                                                                        new EpisodeQuery {
                        AiredSeason  = episodeData.Season,
                        AiredEpisode = episodeData.Episode
                    }
                                                                                                        );

                    result.Title    = episodeResponse.Data[0].EpisodeName;
                    result.Overview = episodeResponse.Data[0].Overview;

                    break;
                } catch (TvDbServerException ex) {
                    if (series.Id == seriesResultCache[episodeData.SeriesName].Last().Id)
                    {
                        if (config.verbose)
                        {
                            setStatus($"Error: Cannot find {episodeData} ({ex.GetType().Name}: {ex.Message})", MessageType.Error);
                        }
                        else
                        {
                            setStatus($"Error: Cannot find {episodeData} on TheTVDB", MessageType.Error);
                        }
                        return(false);
                    }
                }
            }

            setStatus($"Found {episodeData} ({result.Title}) on TheTVDB", MessageType.Information);

            TvDbResponse <TvDbSharper.Dto.Image[]> imagesResponse = null;

            if (config.addCoverArt)
            {
                try {
                    imagesResponse = await tvdb.Series.GetImagesAsync(result.Id, new ImagesQuery {
                        KeyType = KeyType.Season,
                        SubKey  = episodeData.Season.ToString()
                    });
                } catch (TvDbServerException) {
                    try {
                        // use a series image if a season-specific image is not available
                        imagesResponse = await tvdb.Series.GetImagesAsync(result.Id, new ImagesQuery {
                            KeyType = KeyType.Series
                        });
                    } catch (TvDbServerException ex) {
                        if (config.verbose)
                        {
                            setStatus($"Error: Failed to find episode cover ({ex.GetType().Name}: {ex.Message})", MessageType.Error);
                        }
                        else
                        {
                            setStatus("Error: Failed to find episode cover", MessageType.Error);
                        }
                        result.Complete = false;
                    }
                }
            }

            string imageFilename = "";
            if (imagesResponse != null)
            {
                imageFilename = imagesResponse.Data
                                .OrderByDescending(img => img.RatingsInfo.Average)
                                .First().FileName; // Find highest rated image
            }
            #endregion

            result.CoverURL = (String.IsNullOrEmpty(imageFilename)) ? null : $"https://artworks.thetvdb.com/banners/{imageFilename}";

            result.CoverFilename = imageFilename.Split('/').Last();

            bool taggingSuccess = FileWriter.write(filePath, result, setPath, setStatus, config);

            return(taggingSuccess && result.Success && result.Complete);
        }
Ejemplo n.º 22
0
        public tvShows(TvDbResponse <TvDbSharper.Dto.Series> tvshow)
        {
            tvShow show = ConvertTvDbSeriesToTvShow(Convert.ToInt32(tvshow.Data.SeriesId), tvshow.Data.SeriesName, tvshow.Data.Overview, tvshow.Data.FirstAired, null);

            base.Add(show);
        }
Ejemplo n.º 23
0
        private async void GetEpisodes()
        {
            if (TvShows != null)
            {
                //Load Episode Data from TvShows and write back to TvShows;
                var client = new TvDbClient();
                await client.Authentication.AuthenticateAsync(Data.ApiKey, Data.UserName, Data.UserKey);

                client.AcceptedLanguage = Data.prefLang;

                var    tasks    = new List <Task <TvDbResponse <TvDbSharper.Dto.EpisodeRecord[]> > >();
                var    response = new TvDbResponse <EpisodeRecord[]>();
                tvShow show     = TvShows.Find(i => i.tvdbID == actualTvDbID);
                if (show.Count > 1)
                {
                    foreach (showEpisode ep in TvShows.Where(i => i.tvdbID == actualTvDbID))
                    {
                        response = await client.Series.GetEpisodesAsync(ep.tvdbID, 1);

                        for (int i = 2; i <= response.Links.Last; i++)
                        {
                            tasks.Add(client.Series.GetEpisodesAsync(ep.tvdbID, i));
                        }
                    }
                }
                else
                {
                    EpisodeQuery q = new EpisodeQuery();
                    q.AiredSeason  = TvShows[0][0].seasonNr;
                    q.AiredEpisode = TvShows[0][0].episodeNr;
                    response       = await client.Series.GetEpisodesAsync(show.tvdbID, 1, q);
                }

                var results = await Task.WhenAll(tasks);


                //var eps = response.Data.Concat(results.SelectMany(x => x.Data));
                foreach (EpisodeRecord er in response.Data.Concat(results.SelectMany(x => x.Data)))
                {
                    foreach (showEpisode ep in TvShows.Where(i => i.tvdbID == actualTvDbID))
                    {
                        if (er.AiredSeason == ep.seasonNr && er.AiredEpisodeNumber == ep.episodeNr)
                        {
                            //DateTime dt = DateTime.Parse(ep.FirstAired);

                            if (er.EpisodeName == null) //Backup if no German
                            {
                                client.AcceptedLanguage = "en";
                                TvDbResponse <EpisodeRecord> er1 = await client.Episodes.GetAsync(er.Id);

                                ep.episodeName = er1.Data.EpisodeName;
                                ep.description = er1.Data.Overview;
                            }
                            else
                            {
                                ep.episodeName = er.EpisodeName;
                                ep.description = er.Overview;
                            }
                            ep.tvDbEpisodeId = er.Id;
                            if (helper.isDateTime(er.FirstAired))
                            {
                                ep.episodeAirDate = DateTime.Parse(er.FirstAired);
                            }
                            if (ep.episodeName != null && ep.episodeNumbering != null)
                            {
                                ep.newFilename = GetCorrectedFileName(ep.episodeName, ep.episodeNumbering);
                            }
                        }
                    }
                }
                //Episode not found in Episode List
            }
        }