This commit is contained in:
Chris 2024-02-05 21:07:48 -05:00 committed by GitHub
commit fc15b0fecb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 124 additions and 4 deletions

View File

@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
@ -423,5 +424,57 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
Mocker.GetMock<IMakeImportDecision>()
.Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 1), _movie, false), Times.Once());
}
[Test]
public void should_detect_obfuscated_movie_files()
{
GivenMovieFolder();
GivenFiles(new List<string>
{
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.mp4]-[1_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.nfo]-[2_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.txt]-[3_12]").AsOsAgnostic()
});
var files = Subject.GetVideoFiles(_movie.Path);
files.Should().HaveCount(1);
}
[Test]
public void should_detect_obfuscated_nonmovie_files()
{
GivenMovieFolder();
GivenFiles(new List<string>
{
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.mp4]-[1_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.nfo]-[2_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.txt]-[3_12]").AsOsAgnostic()
});
var files = Subject.GetNonVideoFiles(_movie.Path);
files.Should().HaveCount(2);
}
[Test]
public void should_detect_obfuscated_and_normal_movie_files()
{
GivenMovieFolder();
GivenFiles(new List<string>
{
Path.Combine(_movie.Path, "This is a Movie.mp4").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.mp4]-[1_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.nfo]-[2_12]").AsOsAgnostic(),
Path.Combine(_movie.Path, "[private]-[group]-[This is a Movie.txt]-[3_12]").AsOsAgnostic()
});
var files = Subject.GetVideoFiles(_movie.Path);
files.Should().HaveCount(2);
}
}
}

View File

@ -755,6 +755,30 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
Mocker.GetMock<IUpdateMediaInfo>().Verify(v => v.Update(_movieFile, _movie), Times.Never());
}
[TestCase("Movie.mp4", "Movie.mp4")]
[TestCase("Movie.mkv", "Movie.mkv")]
[TestCase("Movie.mp4]-[1_2]", "Movie.mp4")]
[TestCase("Movie.mkv]-[1_2]", "Movie.mkv")]
public void should_rename_invalid_extensions(string filePath, string expectedName)
{
_namingConfig.StandardMovieFormat =
"{Movie.Title}";
var movie = Builder<Movie>
.CreateNew()
.With(s => s.Title = "Movie")
.With(s => s.Path = "")
.Build();
var movieFile = Builder<MovieFile>
.CreateNew()
.With(s => s.RelativePath = filePath)
.Build();
var newFileName = Subject.BuildFileName(movie, movieFile);
Subject.BuildFilePath(movie, newFileName, Path.GetExtension(filePath)).Should().Be(expectedName);
}
private void GivenMediaInfoModel(string videoCodec = "h264",
string audioCodec = "dts",
int audioChannels = 6,

View File

@ -201,7 +201,18 @@ namespace NzbDrone.Core.MediaFiles
var mediaFileList = filesOnDisk.Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file)))
.ToList();
// Find corrupted extensions in the format of: "[FileName.mkv]-[1_2]"
var mediaFilesListIncorrectExtension = filesOnDisk.Except(mediaFileList).Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file).Split(']').First())).ToList();
mediaFileList.AddRange(mediaFilesListIncorrectExtension);
_logger.Trace("{0} files were found in {1}", filesOnDisk.Count, path);
if (mediaFilesListIncorrectExtension.Count > 0)
{
_logger.Debug("{0} video files were found in {1} with incorrect extensions", mediaFilesListIncorrectExtension.Count, path);
}
_logger.Debug("{0} video files were found in {1}", mediaFileList.Count, path);
return mediaFileList.ToArray();
@ -213,13 +224,20 @@ namespace NzbDrone.Core.MediaFiles
var filesOnDisk = _diskProvider.GetFiles(path, allDirectories).ToList();
var mediaFileList = filesOnDisk.Where(file => !MediaFileExtensions.Extensions.Contains(Path.GetExtension(file)))
var mediaFileList = filesOnDisk.Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file)))
.ToList();
_logger.Trace("{0} files were found in {1}", filesOnDisk.Count, path);
_logger.Debug("{0} non-video files were found in {1}", mediaFileList.Count, path);
// Find corrupted extensions in the format of: "[FileName.mkv]-[1_2]"
var mediaFilesListIncorrectExtension = filesOnDisk.Except(mediaFileList).Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file).Split(']').First())).ToList();
return mediaFileList.ToArray();
mediaFileList.AddRange(mediaFilesListIncorrectExtension);
var nonVideoFiles = filesOnDisk.Except(mediaFileList).ToList();
_logger.Trace("{0} files were found in {1}", filesOnDisk.Count, path);
_logger.Debug("{0} non-video files were found in {1}", nonVideoFiles.Count, path);
return nonVideoFiles.ToArray();
}
public List<string> FilterPaths(string basePath, IEnumerable<string> paths, bool filterExtras = true)

View File

@ -150,11 +150,36 @@ namespace NzbDrone.Core.Organizer
{
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
extension = CleanUpExtension(fileName, extension);
var path = movie.Path;
return Path.Combine(path, fileName + extension);
}
private string CleanUpExtension(string fileName, string extension)
{
if (MediaFileExtensions.Extensions.Contains(extension))
{
return extension;
}
// Fix corrupted extensions in the format of: "[FileName.mkv]-[1_2]"
if (extension.Contains(']'))
{
_logger.Trace("Attempting to clean up extension on '{0}{1}'", fileName, extension);
var fixedExtension = extension.Substring(0, extension.IndexOf(']'));
if (MediaFileExtensions.Extensions.Contains(fixedExtension))
{
_logger.Debug("Extension on '{0}{1}' renamed to '{2}'", fileName, extension, fixedExtension);
return fixedExtension;
}
}
// Default back to existing extension if not in above format
return extension;
}
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
{
return new BasicNamingConfig(); // For now let's be lazy