< Summary - Jellyfin

Information
Class: Emby.Server.Implementations.Library.Resolvers.TV.EpisodeResolver
Assembly: Emby.Server.Implementations
File(s): /srv/git/jellyfin/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
Line coverage
88%
Covered lines: 30
Uncovered lines: 4
Coverable lines: 34
Total lines: 116
Line coverage: 88.2%
Branch coverage
53%
Covered branches: 15
Total branches: 28
Branch coverage: 53.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 2/13/2026 - 12:11:21 AM Line coverage: 82.6% (19/23) Branch coverage: 75% (21/28) Total lines: 905/7/2026 - 12:15:44 AM Line coverage: 88.2% (30/34) Branch coverage: 75% (21/28) Total lines: 1165/20/2026 - 12:15:44 AM Line coverage: 88.2% (30/34) Branch coverage: 53.5% (15/28) Total lines: 116 2/13/2026 - 12:11:21 AM Line coverage: 82.6% (19/23) Branch coverage: 75% (21/28) Total lines: 905/7/2026 - 12:15:44 AM Line coverage: 88.2% (30/34) Branch coverage: 75% (21/28) Total lines: 1165/20/2026 - 12:15:44 AM Line coverage: 88.2% (30/34) Branch coverage: 53.5% (15/28) Total lines: 116

Coverage delta

Coverage delta 22 -22

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Resolve(...)53.57%372877.27%
SetProviderIdFromPath(...)100%11100%

File(s)

/srv/git/jellyfin/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs

#LineLine coverage
 1#nullable disable
 2
 3using System;
 4using System.IO;
 5using System.Linq;
 6using Emby.Naming.Common;
 7using Emby.Server.Implementations.Library;
 8using Jellyfin.Data.Enums;
 9using MediaBrowser.Controller.Entities.TV;
 10using MediaBrowser.Controller.Library;
 11using MediaBrowser.Controller.Providers;
 12using MediaBrowser.Model.Entities;
 13using Microsoft.Extensions.Logging;
 14
 15namespace Emby.Server.Implementations.Library.Resolvers.TV
 16{
 17    /// <summary>
 18    /// Class EpisodeResolver.
 19    /// </summary>
 20    public class EpisodeResolver : BaseVideoResolver<Episode>
 21    {
 22        /// <summary>
 23        /// Initializes a new instance of the <see cref="EpisodeResolver"/> class.
 24        /// </summary>
 25        /// <param name="logger">The logger.</param>
 26        /// <param name="namingOptions">The naming options.</param>
 27        /// <param name="directoryService">The directory service.</param>
 28        public EpisodeResolver(ILogger<EpisodeResolver> logger, NamingOptions namingOptions, IDirectoryService directory
 3429            : base(logger, namingOptions, directoryService)
 30        {
 3431        }
 32
 33        /// <summary>
 34        /// Resolves the specified args.
 35        /// </summary>
 36        /// <param name="args">The args.</param>
 37        /// <returns>Episode.</returns>
 38        protected override Episode Resolve(ItemResolveArgs args)
 39        {
 2440            var parent = args.Parent;
 41
 2442            if (parent is null)
 43            {
 044                return null;
 45            }
 46
 47            // Just in case the user decided to nest episodes.
 48            // Not officially supported but in some cases we can handle it.
 49
 2450            var season = parent as Season ?? parent.GetParents().OfType<Season>().FirstOrDefault();
 51
 52            // If the parent is a Season or Series and the parent is not an extras folder, then this is an Episode if th
 53            // Also handle flat tv folders
 2454            if (season is not null
 2455                || args.GetCollectionType() == CollectionType.tvshows
 2456                || args.HasParent<Series>())
 57            {
 1358                var episode = ResolveVideo<Episode>(args, false);
 59
 60                // Ignore extras
 1361                if (episode is null || episode.ExtraType is not null)
 62                {
 163                    return null;
 64                }
 65
 1266                var series = parent as Series ?? parent.GetParents().OfType<Series>().FirstOrDefault();
 67
 1268                if (series is not null)
 69                {
 1270                    episode.SeriesId = series.Id;
 1271                    episode.SeriesName = series.Name;
 72                }
 73
 1274                if (season is not null)
 75                {
 076                    episode.SeasonId = season.Id;
 077                    episode.SeasonName = season.Name;
 78                }
 79
 80                // Assume season 1 if there's no season folder and a season number could not be determined
 1281                if (season is null && !episode.ParentIndexNumber.HasValue && (episode.IndexNumber.HasValue || episode.Pr
 82                {
 083                    episode.ParentIndexNumber = 1;
 84                }
 85
 1286                SetProviderIdFromPath(episode, args.Path);
 87
 1288                return episode;
 89            }
 90
 1191            return null;
 92        }
 93
 94        /// <summary>
 95        /// Sets provider ids from the episode file name.
 96        /// </summary>
 97        /// <param name="item">The episode.</param>
 98        /// <param name="path">The episode file path.</param>
 99        private static void SetProviderIdFromPath(Episode item, string path)
 100        {
 12101            var justName = Path.GetFileNameWithoutExtension(path.AsSpan());
 102
 12103            var imdbId = justName.GetAttributeValue("imdbid");
 12104            item.TrySetProviderId(MetadataProvider.Imdb, imdbId);
 105
 12106            var tvdbId = justName.GetAttributeValue("tvdbid");
 12107            item.TrySetProviderId(MetadataProvider.Tvdb, tvdbId);
 108
 12109            var tvmazeId = justName.GetAttributeValue("tvmazeid");
 12110            item.TrySetProviderId(MetadataProvider.TvMaze, tvmazeId);
 111
 12112            var tmdbId = justName.GetAttributeValue("tmdbid");
 12113            item.TrySetProviderId(MetadataProvider.Tmdb, tmdbId);
 12114        }
 115    }
 116}