Example #1
0
        private void MapSeriesToResult(MetadataResult <Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)
        {
            Series series = result.Item;

            series.SetProviderId(MetadataProviders.Tvdb, tvdbSeries.Id.ToString());
            series.Name           = tvdbSeries.SeriesName;
            series.Overview       = (tvdbSeries.Overview ?? string.Empty).Trim();
            result.ResultLanguage = metadataLanguage;
            series.AirDays        = TVUtils.GetAirDays(tvdbSeries.AirsDayOfWeek);
            series.AirTime        = tvdbSeries.AirsTime;

            series.CommunityRating = (float?)tvdbSeries.SiteRating;
            series.SetProviderId(MetadataProviders.Imdb, tvdbSeries.ImdbId);
            series.SetProviderId(MetadataProviders.Zap2It, tvdbSeries.Zap2itId);
            if (Enum.TryParse(tvdbSeries.Status, true, out SeriesStatus seriesStatus))
            {
                series.Status = seriesStatus;
            }

            if (DateTime.TryParse(tvdbSeries.FirstAired, out var date))
            {
                // dates from tvdb are UTC but without offset or Z
                series.PremiereDate   = date;
                series.ProductionYear = date.Year;
            }

            series.RunTimeTicks = TimeSpan.FromMinutes(Convert.ToDouble(tvdbSeries.Runtime)).Ticks;
            foreach (var genre in tvdbSeries.Genre)
            {
                series.AddGenre(genre);
            }

            series.AddStudio(tvdbSeries.Network);

            if (result.Item.Status.HasValue && result.Item.Status.Value == SeriesStatus.Ended)
            {
                try
                {
                    var episodeSummary = _tvDbClientManager
                                         .GetSeriesEpisodeSummaryAsync(tvdbSeries.Id, metadataLanguage, CancellationToken.None).Result.Data;
                    var maxSeasonNumber = episodeSummary.AiredSeasons.Select(s => Convert.ToInt32(s)).Max();
                    var episodeQuery    = new EpisodeQuery
                    {
                        AiredSeason = maxSeasonNumber
                    };
                    var episodesPage =
                        _tvDbClientManager.GetEpisodesPageAsync(tvdbSeries.Id, episodeQuery, metadataLanguage, CancellationToken.None).Result.Data;
                    result.Item.EndDate = episodesPage.Select(e =>
                    {
                        DateTime.TryParse(e.FirstAired, out var firstAired);
                        return(firstAired);
                    }).Max();
                }
                catch (TvDbServerException e)
                {
                    _logger.LogError(e, "Failed to find series end date for series {TvdbId}", tvdbSeries.Id);
                }
            }
        }
Example #2
0
        private void FetchDataFromSeriesNode(Series item, XmlReader reader, CancellationToken cancellationToken)
        {
            reader.MoveToContent();

            // Loop through each element
            while (reader.Read())
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    case "SeriesName":
                    {
                        item.Name = (reader.ReadElementContentAsString() ?? string.Empty).Trim();
                        break;
                    }

                    case "Overview":
                    {
                        item.Overview = (reader.ReadElementContentAsString() ?? string.Empty).Trim();
                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.AirDays = TVUtils.GetAirDays(val);
                        }
                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.AirTime = val;
                        }
                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.OfficialRating = val;
                        }
                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            // Only fill this if it doesn't already have a value, since we get it from imdb which has better data
                            if (!item.CommunityRating.HasValue || string.IsNullOrWhiteSpace(item.GetProviderId(MetadataProviders.Imdb)))
                            {
                                float rval;

                                // float.TryParse is local aware, so it can be probamatic, force us culture
                                if (float.TryParse(val, NumberStyles.AllowDecimalPoint, _usCulture, out rval))
                                {
                                    item.CommunityRating = rval;
                                }
                            }
                        }
                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            int rval;

                            // int.TryParse is local aware, so it can be probamatic, force us culture
                            if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
                            {
                                item.VoteCount = rval;
                            }
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.SetProviderId(MetadataProviders.Imdb, val);
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.SetProviderId(MetadataProviders.Zap2It, val);
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            SeriesStatus seriesStatus;

                            if (Enum.TryParse(val, true, out seriesStatus))
                            {
                                item.Status = seriesStatus;
                            }
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            DateTime date;
                            if (DateTime.TryParse(val, out date))
                            {
                                date = date.ToUniversalTime();

                                item.PremiereDate   = date;
                                item.ProductionYear = date.Year;
                            }
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            int rval;

                            // int.TryParse is local aware, so it can be probamatic, force us culture
                            if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
                            {
                                item.RunTimeTicks = TimeSpan.FromMinutes(rval).Ticks;
                            }
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            var vals = val
                                       .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(i => i.Trim())
                                       .Where(i => !string.IsNullOrWhiteSpace(i))
                                       .ToList();

                            if (vals.Count > 0)
                            {
                                item.Genres.Clear();

                                foreach (var genre in vals)
                                {
                                    item.AddGenre(genre);
                                }
                            }
                        }

                        break;
                    }

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

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            var vals = val
                                       .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(i => i.Trim())
                                       .Where(i => !string.IsNullOrWhiteSpace(i))
                                       .ToList();

                            if (vals.Count > 0)
                            {
                                item.Studios.Clear();

                                foreach (var genre in vals)
                                {
                                    item.AddStudio(genre);
                                }
                            }
                        }

                        break;
                    }

                    default:
                        reader.Skip();
                        break;
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="itemResult">The item result.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult <Series> itemResult)
        {
            var item = itemResult.Item;

            switch (reader.Name)
            {
            case "id":
            {
                string imdbId = reader.GetAttribute("IMDB");
                string tmdbId = reader.GetAttribute("TMDB");
                string tvdbId = reader.GetAttribute("TVDB");

                if (string.IsNullOrWhiteSpace(tvdbId))
                {
                    tvdbId = reader.ReadElementContentAsString();
                }
                if (!string.IsNullOrWhiteSpace(imdbId))
                {
                    item.SetProviderId(MetadataProviders.Imdb, imdbId);
                }
                if (!string.IsNullOrWhiteSpace(tmdbId))
                {
                    item.SetProviderId(MetadataProviders.Tmdb, tmdbId);
                }
                if (!string.IsNullOrWhiteSpace(tvdbId))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, tvdbId);
                }
                break;
            }

            case "airs_dayofweek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

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

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

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

                if (!string.IsNullOrWhiteSpace(status))
                {
                    if (Enum.TryParse(status, true, out SeriesStatus seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.LogInformation("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, itemResult);
                break;
            }
        }
        /// <summary>
        /// Fetches the main info.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="doc">The doc.</param>
        private void FetchMainInfo(Series series, XmlDocument doc)
        {
            if (!series.LockedFields.Contains(MetadataFields.Name))
            {
                series.Name = doc.SafeGetString("//SeriesName");
            }
            if (!series.LockedFields.Contains(MetadataFields.Overview))
            {
                series.Overview = doc.SafeGetString("//Overview");
            }
            series.CommunityRating = doc.SafeGetSingle("//Rating", 0, 10);
            series.AirDays         = TVUtils.GetAirDays(doc.SafeGetString("//Airs_DayOfWeek"));
            series.AirTime         = doc.SafeGetString("//Airs_Time");
            SeriesStatus seriesStatus;

            if (Enum.TryParse(doc.SafeGetString("//Status"), true, out seriesStatus))
            {
                series.Status = seriesStatus;
            }
            series.PremiereDate = doc.SafeGetDateTime("//FirstAired");
            if (series.PremiereDate.HasValue)
            {
                series.ProductionYear = series.PremiereDate.Value.Year;
            }

            series.RunTimeTicks = TimeSpan.FromMinutes(doc.SafeGetInt32("//Runtime")).Ticks;

            if (!series.LockedFields.Contains(MetadataFields.Studios))
            {
                string s = doc.SafeGetString("//Network");

                if (!string.IsNullOrWhiteSpace(s))
                {
                    series.Studios.Clear();

                    foreach (var studio in s.Trim().Split('|'))
                    {
                        series.AddStudio(studio);
                    }
                }
            }
            series.OfficialRating = doc.SafeGetString("//ContentRating");
            if (!series.LockedFields.Contains(MetadataFields.Genres))
            {
                string g = doc.SafeGetString("//Genre");

                if (g != null)
                {
                    string[] genres = g.Trim('|').Split('|');
                    if (g.Length > 0)
                    {
                        series.Genres.Clear();

                        foreach (var genre in genres)
                        {
                            series.AddGenre(genre);
                        }
                    }
                }
            }
            if (series.Status == SeriesStatus.Ended)
            {
                var document = XDocument.Load(new XmlNodeReader(doc));
                var dates    = document.Descendants("Episode").Where(x => {
                    var seasonNumber = x.Element("SeasonNumber");
                    var firstAired   = x.Element("FirstAired");
                    return(firstAired != null && seasonNumber != null && (!string.IsNullOrEmpty(seasonNumber.Value) && seasonNumber.Value != "0") && !string.IsNullOrEmpty(firstAired.Value));
                }).Select(x => {
                    DateTime?date = null;
                    DateTime tempDate;
                    var firstAired = x.Element("FirstAired");
                    if (firstAired != null && DateTime.TryParse(firstAired.Value, out tempDate))
                    {
                        date = tempDate;
                    }
                    return(date);
                }).ToList();
                if (dates.Any(x => x.HasValue))
                {
                    series.EndDate = dates.Where(x => x.HasValue).Max();
                }
            }
        }
Example #5
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="result">The result.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult <Series> result)
        {
            var item = result.Item;

            switch (reader.Name)
            {
            case "Series":
                //MB generated metadata is within a "Series" node
                using (var subTree = reader.ReadSubtree())
                {
                    subTree.MoveToContent();

                    // Loop through each element
                    while (subTree.Read())
                    {
                        if (subTree.NodeType == XmlNodeType.Element)
                        {
                            FetchDataFromXmlNode(subTree, result);
                        }
                    }
                }
                break;

            case "id":
                string id = reader.ReadElementContentAsString();
                if (!string.IsNullOrWhiteSpace(id))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, id);
                }
                break;

            case "Airs_DayOfWeek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

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

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

            case "AnimeSeriesIndex":
            {
                var number = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(number))
                {
                    int num;

                    if (int.TryParse(number, out num))
                    {
                        item.AnimeSeriesIndex = num;
                    }
                }
                break;
            }

            case "Status":
            {
                var status = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(status))
                {
                    SeriesStatus seriesStatus;
                    if (Enum.TryParse(status, true, out seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.Info("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, result);
                break;
            }
        }
Example #6
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="item">The item.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, Series item)
        {
            switch (reader.Name)
            {
            case "id":
                string id = reader.ReadElementContentAsString();
                if (!string.IsNullOrWhiteSpace(id))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, id);
                }
                break;

            case "airs_dayofweek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

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

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

            case "animeseriesindex":
            {
                var number = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(number))
                {
                    int num;

                    if (int.TryParse(number, out num))
                    {
                        item.AnimeSeriesIndex = num;
                    }
                }
                break;
            }

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

                if (!string.IsNullOrWhiteSpace(status))
                {
                    SeriesStatus seriesStatus;
                    if (Enum.TryParse(status, true, out seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.Info("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, item);
                break;
            }
        }
Example #7
0
        /// <summary>
        /// Fetches the series data.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="seriesId">The series id.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        private async Task <bool> FetchSeriesData(Series series, string seriesId, CancellationToken cancellationToken)
        {
            var success = false;

            var name = series.Name;

            Logger.Debug("TvDbProvider: Fetching series data: " + name);

            if (!string.IsNullOrEmpty(seriesId))
            {
                string url = string.Format(seriesGet, TVUtils.TVDBApiKey, seriesId, ConfigurationManager.Configuration.PreferredMetadataLanguage);
                var    doc = new XmlDocument();

                try
                {
                    using (var xml = await HttpClient.Get(url, TvDbResourcePool, cancellationToken).ConfigureAwait(false))
                    {
                        doc.Load(xml);
                    }
                }
                catch (HttpException)
                {
                }

                if (doc.HasChildNodes)
                {
                    //kick off the actor and image fetch simultaneously
                    var actorTask = FetchActors(series, seriesId, doc, cancellationToken);
                    var imageTask = FetchImages(series, seriesId, cancellationToken);

                    success = true;

                    series.Name            = doc.SafeGetString("//SeriesName");
                    series.Overview        = doc.SafeGetString("//Overview");
                    series.CommunityRating = doc.SafeGetSingle("//Rating", 0, 10);
                    series.AirDays         = TVUtils.GetAirDays(doc.SafeGetString("//Airs_DayOfWeek"));
                    series.AirTime         = doc.SafeGetString("//Airs_Time");

                    string n = doc.SafeGetString("//banner");
                    if (!string.IsNullOrWhiteSpace(n))
                    {
                        series.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n, "banner" + Path.GetExtension(n), TvDbResourcePool, cancellationToken).ConfigureAwait(false));
                    }

                    string s = doc.SafeGetString("//Network");
                    if (!string.IsNullOrWhiteSpace(s))
                    {
                        series.AddStudios(new List <string>(s.Trim().Split('|')));
                    }

                    series.OfficialRating = doc.SafeGetString("//ContentRating");

                    string g = doc.SafeGetString("//Genre");

                    if (g != null)
                    {
                        string[] genres = g.Trim('|').Split('|');
                        if (g.Length > 0)
                        {
                            series.AddGenres(genres);
                        }
                    }

                    //wait for other tasks
                    await Task.WhenAll(actorTask, imageTask).ConfigureAwait(false);

                    if (ConfigurationManager.Configuration.SaveLocalMeta)
                    {
                        var ms = new MemoryStream();
                        doc.Save(ms);

                        await _providerManager.SaveToLibraryFilesystem(series, Path.Combine(series.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false);
                    }
                }
            }



            return(success);
        }