Esempio n. 1
0
        public void Setup()
        {
            _series = Builder <Series>
                      .CreateNew()
                      .With(s => s.Title = "South Park")
                      .Build();


            _namingConfig = NamingConfig.Default;
            _namingConfig.RenameEpisodes = true;


            Mocker.GetMock <INamingConfigService>()
            .Setup(c => c.GetConfig()).Returns(_namingConfig);

            _episode1 = Builder <Episode> .CreateNew()
                        .With(e => e.Title                 = "City Sushi")
                        .With(e => e.SeasonNumber          = 15)
                        .With(e => e.EpisodeNumber         = 6)
                        .With(e => e.AbsoluteEpisodeNumber = 100)
                        .Build();

            _episodeFile = new EpisodeFile {
                Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "SonarrTest"
            };

            _preferredWords = new PreferredWordMatchResults()
            {
                All = new List <string>()
                {
                    "x265",
                    "extended"
                },
                ByReleaseProfile = new Dictionary <string, List <string> >()
                {
                    {
                        "CodecProfile",
                        new List <string>()
                        {
                            "x265"
                        }
                    },
                    {
                        "EditionProfile",
                        new List <string>()
                        {
                            "extended"
                        }
                    }
                }
            };

            Mocker.GetMock <IQualityDefinitionService>()
            .Setup(v => v.Get(Moq.It.IsAny <Quality>()))
            .Returns <Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
        }
Esempio n. 2
0
        private void AddPreferredWords(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, Series series, EpisodeFile episodeFile, PreferredWordMatchResults preferredWords = null)
        {
            if (preferredWords == null)
            {
                preferredWords = _preferredWordService.GetMatchingPreferredWords(series, episodeFile.GetSceneOrFileName());
            }

            tokenHandlers["{Preferred Words}"] = m => {
                var profileName = "";

                if (m.CustomFormat != null)
                {
                    profileName = m.CustomFormat.Trim();
                }

                if (profileName.IsNullOrWhiteSpace())
                {
                    return(string.Join(" ", preferredWords.All));
                }

                if (preferredWords.ByReleaseProfile.TryGetValue(profileName, out var profilePreferredWords))
                {
                    return(string.Join(" ", profilePreferredWords));
                }

                return(string.Empty);
            };
        }
Esempio n. 3
0
        public string BuildFilePath(List <Episode> episodes, Series series, EpisodeFile episodeFile, string extension, NamingConfig namingConfig = null, PreferredWordMatchResults preferredWords = null)
        {
            Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();

            var seasonPath          = BuildSeasonPath(series, episodes.First().SeasonNumber);
            var remainingPathLength = LongPathSupport.MaxFilePathLength - seasonPath.GetByteCount() - 1;
            var fileName            = BuildFileName(episodes, series, episodeFile, extension, remainingPathLength, namingConfig, preferredWords);

            return(Path.Combine(seasonPath, fileName));
        }
Esempio n. 4
0
 public string BuildFileName(List <Episode> episodes, Series series, EpisodeFile episodeFile, string extension = "", NamingConfig namingConfig = null, PreferredWordMatchResults preferredWords = null)
 {
     return(BuildFileName(episodes, series, episodeFile, extension, LongPathSupport.MaxFilePathLength, namingConfig, preferredWords));
 }
Esempio n. 5
0
        private string BuildFileName(List <Episode> episodes, Series series, EpisodeFile episodeFile, string extension, int maxPath, NamingConfig namingConfig = null, PreferredWordMatchResults preferredWords = null)
        {
            if (namingConfig == null)
            {
                namingConfig = _namingConfigService.GetConfig();
            }

            if (!namingConfig.RenameEpisodes)
            {
                return(GetOriginalTitle(episodeFile) + extension);
            }

            if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard)
            {
                throw new NamingFormatException("Standard episode format cannot be empty");
            }

            if (namingConfig.DailyEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Daily)
            {
                throw new NamingFormatException("Daily episode format cannot be empty");
            }

            if (namingConfig.AnimeEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Anime)
            {
                throw new NamingFormatException("Anime episode format cannot be empty");
            }

            var pattern = namingConfig.StandardEpisodeFormat;

            episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList();

            if (series.SeriesType == SeriesTypes.Daily && episodes.First().SeasonNumber > 0)
            {
                pattern = namingConfig.DailyEpisodeFormat;
            }

            if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue))
            {
                pattern = namingConfig.AnimeEpisodeFormat;
            }

            var splitPatterns = pattern.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
            var components    = new List <string>();

            for (var i = 0; i < splitPatterns.Length; i++)
            {
                var splitPattern  = splitPatterns[i];
                var tokenHandlers = new Dictionary <string, Func <TokenMatch, string> >(FileNameBuilderTokenEqualityComparer.Instance);
                splitPattern = AddSeasonEpisodeNumberingTokens(splitPattern, tokenHandlers, episodes, namingConfig);
                splitPattern = AddAbsoluteNumberingTokens(splitPattern, tokenHandlers, series, episodes, namingConfig);

                UpdateMediaInfoIfNeeded(splitPattern, episodeFile, series);

                AddSeriesTokens(tokenHandlers, series);
                AddIdTokens(tokenHandlers, series);
                AddEpisodeTokens(tokenHandlers, episodes);
                AddEpisodeTitlePlaceholderTokens(tokenHandlers);
                AddEpisodeFileTokens(tokenHandlers, episodeFile);
                AddQualityTokens(tokenHandlers, series, episodeFile);
                AddMediaInfoTokens(tokenHandlers, episodeFile);
                AddPreferredWords(tokenHandlers, series, episodeFile, preferredWords);

                var component            = ReplaceTokens(splitPattern, tokenHandlers, namingConfig, true).Trim();
                var maxPathSegmentLength = Math.Min(LongPathSupport.MaxFileNameLength, maxPath);
                if (i == splitPatterns.Length - 1)
                {
                    maxPathSegmentLength -= extension.GetByteCount();
                }
                var maxEpisodeTitleLength = maxPathSegmentLength - GetLengthWithoutEpisodeTitle(component, namingConfig);

                AddEpisodeTitleTokens(tokenHandlers, episodes, maxEpisodeTitleLength);
                component = ReplaceTokens(component, tokenHandlers, namingConfig).Trim();

                component = FileNameCleanupRegex.Replace(component, match => match.Captures[0].Value[0].ToString());
                component = TrimSeparatorsRegex.Replace(component, string.Empty);
                component = component.Replace("{ellipsis}", "...");
                component = ReplaceReservedDeviceNames(component);

                components.Add(component);
            }

            return(string.Join(Path.DirectorySeparatorChar.ToString(), components) + extension);
        }
Esempio n. 6
0
        public FileNameSampleService(IBuildFileNames buildFileNames)
        {
            _buildFileNames = buildFileNames;

            _standardSeries = new Series
            {
                SeriesType = SeriesTypes.Standard,
                Title      = "The Series Title!",
                Year       = 2010,
                ImdbId     = "tt12345",
                TvdbId     = 12345,
                TvMazeId   = 54321
            };

            _dailySeries = new Series
            {
                SeriesType = SeriesTypes.Daily,
                Title      = "The Series Title!",
                Year       = 2010,
                ImdbId     = "tt12345",
                TvdbId     = 12345,
                TvMazeId   = 54321
            };

            _animeSeries = new Series
            {
                SeriesType = SeriesTypes.Anime,
                Title      = "The Series Title!",
                Year       = 2010,
                ImdbId     = "tt12345",
                TvdbId     = 12345,
                TvMazeId   = 54321
            };

            _episode1 = new Episode
            {
                SeasonNumber          = 1,
                EpisodeNumber         = 1,
                Title                 = "Episode Title (1)",
                AirDate               = "2013-10-30",
                AbsoluteEpisodeNumber = 1,
            };

            _episode2 = new Episode
            {
                SeasonNumber          = 1,
                EpisodeNumber         = 2,
                Title                 = "Episode Title (2)",
                AbsoluteEpisodeNumber = 2
            };

            _episode3 = new Episode
            {
                SeasonNumber          = 1,
                EpisodeNumber         = 3,
                Title                 = "Episode Title (3)",
                AbsoluteEpisodeNumber = 3
            };

            _singleEpisode = new List <Episode> {
                _episode1
            };
            _multiEpisodes = new List <Episode> {
                _episode1, _episode2, _episode3
            };

            var mediaInfo = new MediaInfoModel()
            {
                VideoCodec                   = "AVC",
                VideoBitDepth                = 10,
                VideoColourPrimaries         = "BT.2020",
                VideoTransferCharacteristics = "HLG",
                AudioFormat                  = "DTS",
                AudioChannelsContainer       = 6,
                AudioChannelPositions        = "3/2/0.1",
                AudioLanguages               = "English",
                Subtitles = "English/German"
            };

            var mediaInfoAnime = new MediaInfoModel()
            {
                VideoCodec                   = "AVC",
                VideoBitDepth                = 10,
                VideoColourPrimaries         = "BT.2020",
                VideoTransferCharacteristics = "HLG",
                AudioFormat                  = "DTS",
                AudioChannelsContainer       = 6,
                AudioChannelPositions        = "3/2/0.1",
                AudioLanguages               = "Japanese",
                Subtitles = "Japanese/English"
            };

            _singleEpisodeFile = new EpisodeFile
            {
                Quality      = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv",
                SceneName    = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo    = mediaInfo
            };

            _multiEpisodeFile = new EpisodeFile
            {
                Quality      = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv",
                SceneName    = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo    = mediaInfo,
            };

            _dailyEpisodeFile = new EpisodeFile
            {
                Quality      = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv",
                SceneName    = "Series.Title.2013.10.30.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo    = mediaInfo
            };

            _animeEpisodeFile = new EpisodeFile
            {
                Quality      = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv",
                SceneName    = "[RlsGroup] Series Title - 001 [720p]",
                ReleaseGroup = "RlsGrp",
                MediaInfo    = mediaInfoAnime
            };

            _animeMultiEpisodeFile = new EpisodeFile
            {
                Quality      = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv",
                SceneName    = "[RlsGroup] Series Title - 001 - 103 [720p]",
                ReleaseGroup = "RlsGrp",
                MediaInfo    = mediaInfoAnime
            };

            _preferredWords = new PreferredWordMatchResults()
            {
                All = new List <string>()
                {
                    "iNTERNAL"
                }
            };
        }