< Summary - Jellyfin

Information
Class: MediaBrowser.XbmcMetadata.Parsers.EpisodeNfoParser
Assembly: MediaBrowser.XbmcMetadata
File(s): /srv/git/jellyfin/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs
Line coverage
97%
Covered lines: 70
Uncovered lines: 2
Coverable lines: 72
Total lines: 202
Line coverage: 97.2%
Branch coverage
97%
Covered branches: 74
Total branches: 76
Branch coverage: 97.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Fetch(...)100%14.041494.28%
FetchDataFromXmlNode(...)96.42%5656100%
ReadEpisodeDetailsFromXml(...)100%66100%

File(s)

/srv/git/jellyfin/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using System.Text;
 4using System.Threading;
 5using System.Xml;
 6using MediaBrowser.Common.Configuration;
 7using MediaBrowser.Controller.Entities.TV;
 8using MediaBrowser.Controller.Extensions;
 9using MediaBrowser.Controller.Library;
 10using MediaBrowser.Controller.Providers;
 11using Microsoft.Extensions.Logging;
 12
 13namespace MediaBrowser.XbmcMetadata.Parsers
 14{
 15    /// <summary>
 16    /// Nfo parser for episodes.
 17    /// </summary>
 18    public class EpisodeNfoParser : BaseNfoParser<Episode>
 19    {
 20        /// <summary>
 21        /// Initializes a new instance of the <see cref="EpisodeNfoParser"/> class.
 22        /// </summary>
 23        /// <param name="logger">Instance of the <see cref="ILogger{BaseNfoParser}"/> interface.</param>
 24        /// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
 25        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 26        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
 27        /// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
 28        /// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
 29        public EpisodeNfoParser(
 30            ILogger logger,
 31            IConfigurationManager config,
 32            IProviderManager providerManager,
 33            IUserManager userManager,
 34            IUserDataManager userDataManager,
 35            IDirectoryService directoryService)
 636            : base(logger, config, providerManager, userManager, userDataManager, directoryService)
 37        {
 638        }
 39
 40        /// <inheritdoc />
 41        protected override void Fetch(MetadataResult<Episode> item, string metadataFile, XmlReaderSettings settings, Can
 42        {
 443            item.ResetPeople();
 44
 445            var xmlFile = File.ReadAllText(metadataFile);
 46
 447            var srch = "</episodedetails>";
 448            var index = xmlFile.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
 49
 450            var xml = xmlFile;
 51
 452            if (index != -1)
 53            {
 454                xml = xmlFile.Substring(0, index + srch.Length);
 455                xmlFile = xmlFile.Substring(index + srch.Length);
 56            }
 57
 58            // These are not going to be valid xml so no sense in causing the provider to fail and spamming the log with
 59            try
 60            {
 61                // Extract episode details from the first episodedetails block
 462                ReadEpisodeDetailsFromXml(item, xml, settings, cancellationToken);
 63
 64                // Extract the last episode number from nfo
 65                // Retrieves all additional episodedetails blocks from the rest of the nfo and concatenates the name, or
 66                // This is needed because XBMC metadata uses multiple episodedetails blocks instead of episodenumberend 
 467                var name = new StringBuilder(item.Item.Name);
 468                var originalTitle = new StringBuilder(item.Item.OriginalTitle);
 469                var overview = new StringBuilder(item.Item.Overview);
 870                while ((index = xmlFile.IndexOf(srch, StringComparison.OrdinalIgnoreCase)) != -1)
 71                {
 472                    xml = xmlFile.Substring(0, index + srch.Length);
 473                    xmlFile = xmlFile.Substring(index + srch.Length);
 74
 475                    var additionalEpisode = new MetadataResult<Episode>()
 476                    {
 477                        Item = new Episode()
 478                    };
 79
 80                    // Extract episode details from additional episodedetails block
 481                    ReadEpisodeDetailsFromXml(additionalEpisode, xml, settings, cancellationToken);
 82
 483                    if (!string.IsNullOrEmpty(additionalEpisode.Item.Name))
 84                    {
 385                        name.Append(" / ").Append(additionalEpisode.Item.Name);
 86                    }
 87
 488                    if (!string.IsNullOrEmpty(additionalEpisode.Item.Overview))
 89                    {
 190                        overview.Append(" / ").Append(additionalEpisode.Item.Overview);
 91                    }
 92
 493                    if (!string.IsNullOrEmpty(additionalEpisode.Item.OriginalTitle))
 94                    {
 395                        originalTitle.Append(" / ").Append(additionalEpisode.Item.OriginalTitle);
 96                    }
 97
 498                    if (additionalEpisode.Item.IndexNumber != null)
 99                    {
 4100                        item.Item.IndexNumberEnd = Math.Max((int)additionalEpisode.Item.IndexNumber, item.Item.IndexNumb
 101                    }
 102                }
 103
 4104                item.Item.Name = name.ToString();
 4105                item.Item.OriginalTitle = originalTitle.ToString();
 4106                item.Item.Overview = overview.ToString();
 4107            }
 0108            catch (XmlException)
 109            {
 0110            }
 4111        }
 112
 113        /// <inheritdoc />
 114        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Episode> itemResult)
 115        {
 119116            var item = itemResult.Item;
 117
 119118            switch (reader.Name)
 119            {
 120                case "season":
 8121                    if (reader.TryReadInt(out var seasonNumber))
 122                    {
 8123                        item.ParentIndexNumber = seasonNumber;
 124                    }
 125
 8126                    break;
 127                case "episode":
 8128                    if (reader.TryReadInt(out var episodeNumber))
 129                    {
 8130                        item.IndexNumber = episodeNumber;
 131                    }
 132
 8133                    break;
 134                case "episodenumberend":
 1135                    if (reader.TryReadInt(out var episodeNumberEnd))
 136                    {
 1137                        item.IndexNumberEnd = episodeNumberEnd;
 138                    }
 139
 1140                    break;
 141                case "airsbefore_episode":
 142                case "displayepisode":
 2143                    if (reader.TryReadInt(out var airsBeforeEpisode))
 144                    {
 2145                        item.AirsBeforeEpisodeNumber = airsBeforeEpisode;
 146                    }
 147
 2148                    break;
 149                case "airsafter_season":
 150                case "displayafterseason":
 1151                    if (reader.TryReadInt(out var airsAfterSeason))
 152                    {
 1153                        item.AirsAfterSeasonNumber = airsAfterSeason;
 154                    }
 155
 1156                    break;
 157                case "airsbefore_season":
 158                case "displayseason":
 2159                    if (reader.TryReadInt(out var airsBeforeSeason))
 160                    {
 2161                        item.AirsBeforeSeasonNumber = airsBeforeSeason;
 162                    }
 163
 2164                    break;
 165                case "showtitle":
 1166                    item.SeriesName = reader.ReadNormalizedString();
 1167                    break;
 168                default:
 96169                    base.FetchDataFromXmlNode(reader, itemResult);
 170                    break;
 171            }
 96172        }
 173
 174        /// <summary>
 175        /// Reads the episode details from the given xml and saves the result in the provided result item.
 176        /// </summary>
 177        private void ReadEpisodeDetailsFromXml(MetadataResult<Episode> item, string xml, XmlReaderSettings settings, Can
 178        {
 8179            using (var stringReader = new StringReader(xml))
 8180            using (var reader = XmlReader.Create(stringReader, settings))
 181            {
 8182                reader.MoveToContent();
 8183                reader.Read();
 184
 185                // Loop through each element
 287186                while (!reader.EOF && reader.ReadState == ReadState.Interactive)
 187                {
 279188                    cancellationToken.ThrowIfCancellationRequested();
 189
 279190                    if (reader.NodeType == XmlNodeType.Element)
 191                    {
 119192                        FetchDataFromXmlNode(reader, item);
 193                    }
 194                    else
 195                    {
 160196                        reader.Read();
 197                    }
 198                }
 8199            }
 8200        }
 201    }
 202}