Example #1
0
        public List <ImportDecision> GetImportDecisions(List <string> videoFiles, Series series, DownloadClientItem downloadClientItem, ParsedEpisodeInfo folderInfo, bool sceneSource)
        {
            var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series);

            _logger.Debug("Analyzing {0}/{1} files.", newFiles.Count, videoFiles.Count());

            ParsedEpisodeInfo downloadClientItemInfo = null;

            if (downloadClientItem != null)
            {
                downloadClientItemInfo = Parser.Parser.ParseTitle(downloadClientItem.Title);
            }

            var nonSampleVideoFileCount = GetNonSampleVideoFileCount(newFiles, series, downloadClientItemInfo, folderInfo);

            var decisions = new List <ImportDecision>();

            foreach (var file in newFiles)
            {
                var localEpisode = new LocalEpisode
                {
                    Series = series,
                    DownloadClientEpisodeInfo = downloadClientItemInfo,
                    FolderEpisodeInfo         = folderInfo,
                    Path         = file,
                    SceneSource  = sceneSource,
                    ExistingFile = series.Path.IsParentPath(file)
                };

                decisions.AddIfNotNull(GetDecision(localEpisode, downloadClientItem, nonSampleVideoFileCount > 1));
            }

            return(decisions);
        }
Example #2
0
        public void Setup()
        {
            _series = Builder <Series> .CreateNew()
                      .With(s => s.Title      = "30 Stone")
                      .With(s => s.CleanTitle = "stone")
                      .Build();

            _episodes = Builder <Episode> .CreateListOfSize(1)
                        .All()
                        .With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
                        .Build()
                        .ToList();

            _parsedEpisodeInfo = new ParsedEpisodeInfo
            {
                SeriesTitle            = _series.Title,
                SeasonNumber           = 1,
                EpisodeNumbers         = new[] { 1 },
                AbsoluteEpisodeNumbers = new int[0]
            };

            _singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
            {
                Series        = _series,
                EpisodeNumber = _episodes.First().EpisodeNumber,
                SeasonNumber  = _episodes.First().SeasonNumber,
                Episodes      = _episodes
            };

            Mocker.GetMock <ISeriesService>()
            .Setup(s => s.FindByTitle(It.IsAny <string>()))
            .Returns(_series);
        }
        private CachedSeedConfiguration FetchIndexer(string infoHash)
        {
            var historyItem = _downloadHistoryService.GetLatestGrab(infoHash);

            if (historyItem == null)
            {
                _logger.Debug("No download history item for infohash {0}, unable to provide seed configuration", infoHash);
                return(null);
            }

            ParsedEpisodeInfo parsedEpisodeInfo = null;

            if (historyItem.Release != null)
            {
                parsedEpisodeInfo = Parser.Parser.ParseTitle(historyItem.Release.Title);
            }

            if (parsedEpisodeInfo == null)
            {
                _logger.Debug("No parsed title in download history item for infohash {0}, unable to provide seed configuration", infoHash);
                return(null);
            }

            return(new CachedSeedConfiguration
            {
                IndexerId = historyItem.IndexerId,
                FullSeason = parsedEpisodeInfo.FullSeason
            });
        }
Example #4
0
        private ParsedEpisodeInfo ParseSpecialEpisodeTitle(string releaseTitle, Series series)
        {
            // find special episode in series season 0
            var episode = _episodeService.FindEpisodeByTitle(series.Id, 0, releaseTitle);

            if (episode != null)
            {
                // create parsed info from tv episode
                var info = new ParsedEpisodeInfo
                {
                    ReleaseTitle    = releaseTitle,
                    SeriesTitle     = series.Title,
                    SeriesTitleInfo = new SeriesTitleInfo
                    {
                        Title = series.Title
                    },
                    SeasonNumber   = episode.SeasonNumber,
                    EpisodeNumbers = new int[1] {
                        episode.EpisodeNumber
                    },
                    FullSeason   = false,
                    Quality      = QualityParser.ParseQuality(releaseTitle),
                    ReleaseGroup = Parser.ParseReleaseGroup(releaseTitle),
                    Language     = LanguageParser.ParseLanguage(releaseTitle),
                    Special      = true
                };

                _logger.Debug("Found special episode {0} for title '{1}'", info, releaseTitle);
                return(info);
            }

            return(null);
        }
Example #5
0
        private bool ShouldUseFolderName(List <string> videoFiles, Series series, ParsedEpisodeInfo folderInfo)
        {
            if (folderInfo == null)
            {
                return(false);
            }

            if (folderInfo.FullSeason)
            {
                return(false);
            }

            return(videoFiles.Count(file =>
            {
                var sample = _detectSample.IsSample(series, file, folderInfo.IsPossibleSpecialEpisode);

                if (sample == DetectSampleResult.Sample)
                {
                    return false;
                }

                if (SceneChecker.IsSceneTitle(Path.GetFileName(file)))
                {
                    return false;
                }

                return true;
            }) == 1);
        }
Example #6
0
        private List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, int mappedSeasonNumber, bool sceneSource, SearchCriteriaBase searchCriteria)
        {
            if (parsedEpisodeInfo.FullSeason)
            {
                return _episodeService.GetEpisodesBySeason(series.Id, mappedSeasonNumber);
            }

            if (parsedEpisodeInfo.IsDaily)
            {
                var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, parsedEpisodeInfo.DailyPart, searchCriteria);

                if (episodeInfo != null)
                {
                    return new List<Episode> { episodeInfo };
                }

                return new List<Episode>();
            }

            if (parsedEpisodeInfo.IsAbsoluteNumbering)
            {
                return GetAnimeEpisodes(series, parsedEpisodeInfo, mappedSeasonNumber, sceneSource, searchCriteria);
            }

            return GetStandardEpisodes(series, parsedEpisodeInfo, mappedSeasonNumber, sceneSource, searchCriteria);
        }
Example #7
0
        public void Setup()
        {
            _series = Builder <Series> .CreateNew()
                      .With(s => s.Title      = "30 Rock")
                      .With(s => s.CleanTitle = "rock")
                      .Build();

            _episodes = Builder <Episode> .CreateListOfSize(1)
                        .All()
                        .With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
                        .Build()
                        .ToList();

            _parsedEpisodeInfo = new ParsedEpisodeInfo
            {
                SeriesTitle     = _series.Title,
                SeriesTitleInfo = new SeriesTitleInfo(),
                SeasonNumber    = 1,
                EpisodeNumbers  = new[] { 1 }
            };

            _singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
            {
                Series        = _series,
                EpisodeNumber = _episodes.First().EpisodeNumber,
                SeasonNumber  = _episodes.First().SeasonNumber,
                Episodes      = _episodes
            };

            Mocker.GetMock <ISceneMappingService>()
            .Setup(v => v.GetTvdbSeasonNumber(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>()))
            .Returns <string, string, int>((s, r, i) => i);
        }
Example #8
0
        private List <Episode> GetAnimeEpisodes(Series series, ParsedEpisodeInfo parsedEpisodeInfo, bool sceneSource)
        {
            var result = new List <Episode>();

            var sceneSeasonNumber = _sceneMappingService.GetSceneSeasonNumber(parsedEpisodeInfo.SeriesTitle);

            foreach (var absoluteEpisodeNumber in parsedEpisodeInfo.AbsoluteEpisodeNumbers)
            {
                Episode episode = null;

                if (parsedEpisodeInfo.Special)
                {
                    episode = _episodeService.FindEpisode(series.Id, 0, absoluteEpisodeNumber);
                }

                else if (sceneSource)
                {
                    // Is there a reason why we excluded season 1 from this handling before?
                    // Might have something to do with the scene name to season number check
                    // If this needs to be reverted tests will need to be added
                    if (sceneSeasonNumber.HasValue)
                    {
                        var episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);

                        if (episodes.Count == 1)
                        {
                            episode = episodes.First();
                        }

                        if (episode == null)
                        {
                            episode = _episodeService.FindEpisode(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
                        }
                    }

                    else
                    {
                        episode = _episodeService.FindEpisodeBySceneNumbering(series.Id, absoluteEpisodeNumber);
                    }
                }

                if (episode == null)
                {
                    episode = _episodeService.FindEpisode(series.Id, absoluteEpisodeNumber);
                }

                if (episode != null)
                {
                    _logger.Debug("Using absolute episode number {0} for: {1} - TVDB: {2}x{3:00}",
                                  absoluteEpisodeNumber,
                                  series.Title,
                                  episode.SeasonNumber,
                                  episode.EpisodeNumber);

                    result.Add(episode);
                }
            }

            return(result);
        }
Example #9
0
        public void Setup()
        {
            _series = Builder <Series> .CreateNew()
                      .With(s => s.Title      = "30 Rock")
                      .With(s => s.CleanTitle = "rock")
                      .Build();

            _episodes = Builder <Episode> .CreateListOfSize(1)
                        .All()
                        .With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
                        .Build()
                        .ToList();

            _parsedEpisodeInfo = new ParsedEpisodeInfo
            {
                SeriesTitle     = _series.Title,
                SeriesTitleInfo = new SeriesTitleInfo(),
                SeasonNumber    = 1,
                EpisodeNumbers  = new[] { 1 }
            };

            _singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
            {
                Series        = _series,
                EpisodeNumber = _episodes.First().EpisodeNumber,
                SeasonNumber  = _episodes.First().SeasonNumber,
                Episodes      = _episodes
            };
        }
Example #10
0
        public List <Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null)
        {
            if (parsedEpisodeInfo.FullSeason)
            {
                return(_episodeService.GetEpisodesBySeason(series.Id, parsedEpisodeInfo.SeasonNumber));
            }

            if (parsedEpisodeInfo.IsDaily)
            {
                if (series.SeriesType == SeriesTypes.Standard)
                {
                    _logger.Warn("Found daily-style episode for non-daily series: {0}.", series);
                    return(new List <Episode>());
                }

                var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, searchCriteria);

                if (episodeInfo != null)
                {
                    return(new List <Episode> {
                        episodeInfo
                    });
                }

                return(new List <Episode>());
            }

            if (parsedEpisodeInfo.IsAbsoluteNumbering)
            {
                return(GetAnimeEpisodes(series, parsedEpisodeInfo, sceneSource));
            }

            return(GetStandardEpisodes(series, parsedEpisodeInfo, sceneSource, searchCriteria));
        }
Example #11
0
        private ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, Series series)
        {
            // find special episode in series season 0
            var episode = _episodeService.FindEpisodeByTitle(series.Id, 0, title);

            if (episode != null)
            {
                // create parsed info from tv episode
                var info = new ParsedEpisodeInfo();
                info.SeriesTitle           = series.Title;
                info.SeriesTitleInfo       = new SeriesTitleInfo();
                info.SeriesTitleInfo.Title = info.SeriesTitle;
                info.SeasonNumber          = episode.SeasonNumber;
                info.EpisodeNumbers        = new int[1] {
                    episode.EpisodeNumber
                };
                info.FullSeason   = false;
                info.Quality      = QualityParser.ParseQuality(title);
                info.ReleaseGroup = Parser.ParseReleaseGroup(title);
                info.Language     = Parser.ParseLanguage(title);
                info.Special      = true;

                _logger.Info("Found special episode {0} for title '{1}'", info, title);
                return(info);
            }

            return(null);
        }
Example #12
0
        private ParsedEpisodeInfo GetSpecialEpisodeInfo(LocalEpisode localEpisode, ParsedEpisodeInfo parsedEpisodeInfo)
        {
            var title = Path.GetFileNameWithoutExtension(localEpisode.Path);
            var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, title, localEpisode.Series);

            return(specialEpisodeInfo);
        }
Example #13
0
        private bool ShouldUseFolderName(List <string> videoFiles, Series series, ParsedEpisodeInfo folderInfo)
        {
            if (folderInfo == null)
            {
                return(false);
            }

            if (folderInfo.FullSeason)
            {
                return(false);
            }

            return(videoFiles.Count(file =>
            {
                var size = _diskProvider.GetFileSize(file);
                var fileQuality = QualityParser.ParseQuality(file);
                var sample = _detectSample.IsSample(series, GetQuality(folderInfo, fileQuality, series), file, size, folderInfo.SeasonNumber);

                if (sample)
                {
                    return false;
                }

                if (SceneChecker.IsSceneTitle(Path.GetFileName(file)))
                {
                    return false;
                }

                return true;
            }) == 1);
        }
Example #14
0
        public List <Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null)
        {
            if (parsedEpisodeInfo.FullSeason)
            {
                return(_episodeService.GetEpisodesBySeason(series.Id, parsedEpisodeInfo.SeasonNumber));
            }

            if (parsedEpisodeInfo.IsDaily)
            {
                var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, parsedEpisodeInfo.DailyPart, searchCriteria);

                if (episodeInfo != null)
                {
                    return(new List <Episode> {
                        episodeInfo
                    });
                }

                return(new List <Episode>());
            }

            if (parsedEpisodeInfo.IsAbsoluteNumbering)
            {
                return(GetAnimeEpisodes(series, parsedEpisodeInfo, sceneSource));
            }

            return(GetStandardEpisodes(series, parsedEpisodeInfo, sceneSource, searchCriteria));
        }
Example #15
0
        public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null)
        {
            var remoteEpisode = new RemoteEpisode
            {
                ParsedEpisodeInfo = parsedEpisodeInfo,
            };

            var series = GetSeries(parsedEpisodeInfo, tvdbId, tvRageId, searchCriteria);

            if (series == null)
            {
                return(remoteEpisode);
            }

            remoteEpisode.Series = series;

            if (ValidateParsedEpisodeInfo.ValidateForSeriesType(parsedEpisodeInfo, series))
            {
                remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series, true, searchCriteria);
            }
            else
            {
                remoteEpisode.Episodes = new List <Episode>();
            }

            return(remoteEpisode);
        }
Example #16
0
        private Series GetSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvRageId, SearchCriteriaBase searchCriteria)
        {
            var tvdbId = _sceneMappingService.FindTvDbId(parsedEpisodeInfo.SeriesTitle);

            if (tvdbId.HasValue)
            {
                if (searchCriteria.Series.TvdbId == tvdbId)
                {
                    return(searchCriteria.Series);
                }
            }

            if (parsedEpisodeInfo.SeriesTitle.CleanSeriesTitle() == searchCriteria.Series.CleanTitle)
            {
                return(searchCriteria.Series);
            }

            if (tvRageId > 0 && tvRageId == searchCriteria.Series.TvRageId)
            {
                //TODO: If series is found by TvRageId, we should report it as a scene naming exception, since it will fail to import
                return(searchCriteria.Series);
            }

            return(GetSeries(parsedEpisodeInfo, tvRageId));
        }
Example #17
0
        private Language GetLanguage(ParsedEpisodeInfo parsedEpisodeInfo, List <Episode> episodes)
        {
            if (parsedEpisodeInfo == null)
            {
                return(Language.English);
            }

            var normalizedReleaseTitle = Parser.Parser.NormalizeEpisodeTitle(parsedEpisodeInfo.ReleaseTitle);

            foreach (var episode in episodes)
            {
                var episodeTitleLanguage = LanguageParser.ParseLanguage(episode.Title, false);

                if (episodeTitleLanguage != Language.Unknown && episodeTitleLanguage == parsedEpisodeInfo.Language)
                {
                    // Release title contains the episode title, return english instead of the parsed language.

                    if (normalizedReleaseTitle.ContainsIgnoreCase(Parser.Parser.NormalizeEpisodeTitle(episode.Title)))
                    {
                        return(Language.English);
                    }
                }
            }

            return(parsedEpisodeInfo.Language);
        }
Example #18
0
 public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable <int> episodeIds)
 {
     return(new RemoteEpisode
     {
         ParsedEpisodeInfo = parsedEpisodeInfo,
         Series = _seriesService.GetSeries(seriesId),
         Episodes = _episodeService.GetEpisodes(episodeIds)
     });
 }
        private string GetReleaseGroup(ParsedEpisodeInfo episodeInfo, bool skipFullSeason)
        {
            if (episodeInfo == null || episodeInfo.FullSeason && skipFullSeason)
            {
                return(null);
            }

            return(episodeInfo.ReleaseGroup);
        }
Example #20
0
        private ImportDecision GetDecision(string file, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource, bool shouldUseFolderName)
        {
            ImportDecision decision = null;

            try
            {
                var localEpisode = _parsingService.GetLocalEpisode(file, series, shouldUseFolderName ? folderInfo : null, sceneSource);

                if (localEpisode != null)
                {
                    localEpisode.Quality = GetQuality(folderInfo, localEpisode.Quality, series);
                    localEpisode.Size    = _diskProvider.GetFileSize(file);

                    _logger.Debug("Size: {0}", localEpisode.Size);

                    //TODO: make it so media info doesn't ruin the import process of a new series
                    if (sceneSource)
                    {
                        localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file);
                    }

                    if (localEpisode.Episodes.Empty())
                    {
                        decision = new ImportDecision(localEpisode, new Rejection("Invalid season or episode"));
                    }
                    else
                    {
                        decision = GetDecision(localEpisode);
                    }
                }

                else
                {
                    localEpisode      = new LocalEpisode();
                    localEpisode.Path = file;

                    decision = new ImportDecision(localEpisode, new Rejection("Unable to parse file"));
                }
            }
            catch (Exception e)
            {
                _logger.Error(e, "Couldn't import file. " + file);

                var localEpisode = new LocalEpisode {
                    Path = file
                };
                decision = new ImportDecision(localEpisode, new Rejection("Unexpected error processing file"));
            }

            if (decision == null)
            {
                _logger.Error("Unable to make a decision on {0}", file);
            }

            return(decision);
        }
Example #21
0
        private RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, Series series, SearchCriteriaBase searchCriteria)
        {
            var sceneMapping = _sceneMappingService.FindSceneMapping(parsedEpisodeInfo.SeriesTitle, parsedEpisodeInfo.ReleaseTitle, parsedEpisodeInfo.SeasonNumber);

            var remoteEpisode = new RemoteEpisode
            {
                ParsedEpisodeInfo  = parsedEpisodeInfo,
                SceneMapping       = sceneMapping,
                MappedSeasonNumber = parsedEpisodeInfo.SeasonNumber
            };

            // For now we just detect tvdb vs scene, but we can do multiple 'origins' in the future.
            var sceneSource = true;

            if (sceneMapping != null)
            {
                if (sceneMapping.SeasonNumber.HasValue && sceneMapping.SeasonNumber.Value >= 0 &&
                    sceneMapping.SceneSeasonNumber <= parsedEpisodeInfo.SeasonNumber)
                {
                    remoteEpisode.MappedSeasonNumber += sceneMapping.SeasonNumber.Value - sceneMapping.SceneSeasonNumber.Value;
                }

                if (sceneMapping.SceneOrigin == "tvdb")
                {
                    sceneSource = false;
                }
            }

            if (series == null)
            {
                series = GetSeries(parsedEpisodeInfo, tvdbId, tvRageId, sceneMapping, searchCriteria);
            }

            if (series != null)
            {
                remoteEpisode.Series = series;

                if (ValidateParsedEpisodeInfo.ValidateForSeriesType(parsedEpisodeInfo, series))
                {
                    remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series, remoteEpisode.MappedSeasonNumber, sceneSource, searchCriteria);
                }
            }

            if (remoteEpisode.Episodes == null)
            {
                remoteEpisode.Episodes = new List <Episode>();
            }

            if (searchCriteria != null)
            {
                var requestedEpisodes = searchCriteria.Episodes.ToDictionaryIgnoreDuplicates(v => v.Id);
                remoteEpisode.EpisodeRequested = remoteEpisode.Episodes.Any(v => requestedEpisodes.ContainsKey(v.Id));
            }

            return(remoteEpisode);
        }
Example #22
0
        private QualityModel GetQuality(ParsedEpisodeInfo folderInfo, QualityModel fileQuality, Series series)
        {
            if (UseFolderQuality(folderInfo, fileQuality, series))
            {
                _logger.Debug("Using quality from folder: {0}", folderInfo.Quality);
                return(folderInfo.Quality);
            }

            return(fileQuality);
        }
Example #23
0
        private bool ValidateSeasonAndEpisodeNumbers(List <Episode> episodes, ParsedEpisodeInfo parsedEpisodeInfo)
        {
            if (parsedEpisodeInfo.SeasonNumber != episodes.First().SeasonNumber ||
                !parsedEpisodeInfo.EpisodeNumbers.OrderBy(e => e).SequenceEqual(episodes.Select(e => e.EpisodeNumber).OrderBy(e => e)))
            {
                return(false);
            }

            return(true);
        }
        public void should_return_true_when_episode_numbers_is_empty()
        {
            var parsedEpisodeInfo = new ParsedEpisodeInfo
            {
                SeasonNumber = 1,
                SeriesTitle  = ""
            };

            parsedEpisodeInfo.IsPossibleSpecialEpisode.Should().BeTrue();
        }
        public void Setup()
        {
            _parsedEpisodeInfo = Builder <ParsedEpisodeInfo> .CreateNew()
                                 .With(p => p.AirDate = null)
                                 .Build();

            _series = Builder <Series> .CreateNew()
                      .With(s => s.SeriesType = SeriesTypes.Standard)
                      .Build();
        }
        private QualityModel GetQuality(ParsedEpisodeInfo folderInfo, QualityModel fileQuality, Series series)
        {
            if (folderInfo != null && folderInfo.Quality.Quality != Quality.Unknown && fileQuality.QualitySource == QualitySource.Extension)
            {
                _logger.Debug("Using quality from folder: {0}", folderInfo.Quality);
                return folderInfo.Quality;
            }

            return fileQuality;
        }
Example #27
0
        private Language GetLanguage(ParsedEpisodeInfo parsedEpisodeInfo)
        {
            if (parsedEpisodeInfo == null)
            {
                // English is the default language when otherwise unknown

                return(Language.English);
            }

            return(parsedEpisodeInfo.Language);
        }
Example #28
0
        public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, Int32 seriesId, IEnumerable <Int32> episodeIds)
        {
            var remoteEpisode = new RemoteEpisode
            {
                ParsedEpisodeInfo = parsedEpisodeInfo,
                Series            = _seriesService.GetSeries(seriesId),
                Episodes          = _episodeService.GetEpisodes(episodeIds)
            };

            return(remoteEpisode);
        }
        public List <Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null)
        {
            if (sceneSource)
            {
                var remoteEpisode = Map(parsedEpisodeInfo, 0, 0, series, searchCriteria);

                return(remoteEpisode.Episodes);
            }

            return(GetEpisodes(parsedEpisodeInfo, series, parsedEpisodeInfo.SeasonNumber, sceneSource, searchCriteria));
        }
        public void should_not_treat_files_without_a_series_title_as_a_special()
        {
            var parsedEpisodeInfo = new ParsedEpisodeInfo
            {
                EpisodeNumbers = new[] { 7 },
                SeasonNumber   = 1,
                SeriesTitle    = ""
            };

            parsedEpisodeInfo.IsPossibleSpecialEpisode.Should().BeFalse();
        }