internal static void PrintDirectoriesWithErrors(string directory, int level = 2, bool isLoadingVideo = false, bool isNoAudioAllowed = false, Action <string>?log = null) { log ??= TraceLog; List <string>?allVideos = null; if (isLoadingVideo) { allVideos = new(); } EnumerateDirectories(directory, level) .ForEach(movie => { string trimmedMovie = Path.GetFileName(movie) ?? throw new InvalidOperationException(movie); if (trimmedMovie.StartsWith("0.")) { trimmedMovie = trimmedMovie.Substring("0.".Length); } if (trimmedMovie.Contains("{")) { trimmedMovie = trimmedMovie.Substring(0, trimmedMovie.IndexOf("{", StringComparison.Ordinal)); } if (Regex.IsMatch(trimmedMovie, @"·[0-9]")) { log($"!Special character ·: {trimmedMovie}"); } if (trimmedMovie.Contains(":")) { log($"!Special character :: {trimmedMovie}"); } VideoDirectoryInfo videoDirectoryInfo = new(trimmedMovie); //if (!string.Equals(level1Number1, level1Number3) || !string.IsNullOrWhiteSpace(level1Number2) && !string.Equals(level1Number1, level1Number2)) //{ // log($"{movie}"); //} //if (Regex.IsMatch(Regex.Replace(match.Groups[5].Value, "([0-9]{1,2})$", ""), "[0-9]+")) //{ // log($"!Index: {movie}"); //} new string[] { videoDirectoryInfo.TranslatedTitle1, videoDirectoryInfo.TranslatedTitle2, videoDirectoryInfo.TranslatedTitle3 } .Where(translated => Regex.IsMatch(translated.Split("`").First(), "[0-9]+")) .ForEach(translated => log($"!Translation has number {translated}: {movie}")); string[] files = Directory.EnumerateFiles(movie, PathHelper.AllSearchPattern, SearchOption.TopDirectoryOnly).Select(file => Path.GetFileName(file) ?? throw new InvalidOperationException(file)).ToArray(); if (trimmedMovie.Contains("1080p") && !files.Any(file => file.Contains("1080p"))) { log($"!Not 1080p: {movie}"); } if (!trimmedMovie.Contains("1080p") && files.Any(file => file.Contains("1080p"))) { log($"!1080p: {movie}"); } if (trimmedMovie.Contains("720p") && !files.Any(file => file.Contains("720p"))) { log($"!Not 720p: {movie}"); } if (!trimmedMovie.Contains("1080p") && !trimmedMovie.Contains("720p") && files.Any(file => file.Contains("720p"))) { log($"!720p: {movie}"); } string[] videos = files.Where(IsCommonVideo).ToArray(); string[] subtitles = files.Where(file => file.HasAnyExtension(AllSubtitleExtensions)).ToArray(); string[] metadataFiles = files.Where(file => file.HasExtension(XmlMetadataExtension)).ToArray(); string[] imdbFiles = files.Where(file => file.HasExtension(JsonMetadataExtension)).ToArray(); string[] otherFiles = files.Except(videos).Except(subtitles).Except(metadataFiles).Except(imdbFiles).ToArray(); if (videos.Length < 1) { log($"!No video: {movie}"); } else if (videos.Length == 1 || videos.All(video => Regex.IsMatch(Path.GetFileNameWithoutExtension(video), @"\.cd[1-9]$", RegexOptions.IgnoreCase))) { string[] allowedAttachments = Attachments.Concat(AdaptiveAttachments).ToArray(); otherFiles .Where(file => !allowedAttachments.Contains(file, StringComparer.InvariantCultureIgnoreCase)) .ForEach(file => log($"!Attachment: {Path.Combine(movie, file)}")); } else { string[] allowedAttachments = videos .SelectMany(video => AdaptiveAttachments.Select(attachment => $"{Path.GetFileNameWithoutExtension(video)}-{attachment}")) .Concat(Attachments) .ToArray(); otherFiles .Where(file => !allowedAttachments.Contains(file, StringComparer.InvariantCultureIgnoreCase)) .ForEach(file => log($"!Attachment: {Path.Combine(movie, file)}")); } string[] allowedSubtitles = videos .SelectMany(video => SubtitleLanguages .Select(language => $"{Path.GetFileNameWithoutExtension(video)}.{language}") .Prepend(Path.GetFileNameWithoutExtension(video))) .SelectMany(subtitle => AllSubtitleExtensions.Select(extension => $"{subtitle}{extension}")) .ToArray(); subtitles .Where(subtitle => !allowedSubtitles.Contains(subtitle, StringComparer.InvariantCultureIgnoreCase)) .ForEach(file => log($"!Subtitle: {Path.Combine(movie, file)}")); string[] allowedMetadataFiles = videos .Select(video => $"{Path.GetFileNameWithoutExtension(video)}{XmlMetadataExtension}") .ToArray(); metadataFiles .Where(metadata => !allowedMetadataFiles.Contains(metadata, StringComparer.InvariantCultureIgnoreCase)) .ForEach(file => log($"!Metadata: {Path.Combine(movie, file)}")); files .Except(imdbFiles) .Where(file => Regex.IsMatch(file, "(1080[^p]|720[^p])")) .ForEach(file => log($"Definition: {Path.Combine(movie, file)}")); if (isLoadingVideo) { allVideos !.AddRange(videos.Select(video => Path.Combine(movie, video))); } if (metadataFiles.Length < 1) { log($"!Metadata: {movie}"); } if (imdbFiles.Length != 1) { log($"!Imdb files {imdbFiles.Length}: {movie}"); } string imdbRating = Imdb.TryLoad(movie, out ImdbMetadata? imdbMetadata) ? imdbMetadata.FormattedAggregateRating : NotExistingFlag; if (!string.Equals(videoDirectoryInfo.AggregateRating, imdbRating, StringComparison.InvariantCulture)) { log($"!Imdb rating {videoDirectoryInfo.AggregateRating} should be {imdbRating}: {movie}"); } string contentRating = imdbMetadata?.FormattedContentRating ?? NotExistingFlag; if (!string.Equals(contentRating, videoDirectoryInfo.ContentRating, StringComparison.InvariantCulture)) { log($"!Content rating {videoDirectoryInfo.ContentRating} should be {contentRating}: {movie}"); } metadataFiles.ForEach(metadataFile => { metadataFile = Path.Combine(movie, metadataFile); XDocument metadata = XDocument.Load(Path.Combine(movie, metadataFile)); string?metadataImdbId = metadata.Root?.Element("imdbid")?.Value; // string? metadataImdbRating = metadata.Root?.Element("rating")?.Value; if (imdbMetadata == null) { if (!string.IsNullOrWhiteSpace(metadataImdbId)) { log($"!Metadata should have no imdb id: {metadataFile}"); } // if (!string.IsNullOrWhiteSpace(metadataImdbRating)) // { // log($"!Metadata should have no rating: {metadataFile}"); // } } else { if (!string.Equals(imdbMetadata.ImdbId, metadataImdbId)) { log($"!Metadata imdb id {metadataImdbId} should be {imdbMetadata.ImdbId}: {metadataFile}"); } } }); string?imdbYear = imdbMetadata?.Year; if (!string.IsNullOrWhiteSpace(imdbYear)) { if (!string.Equals(videoDirectoryInfo.Year, imdbYear)) { log($"!Year should be {imdbYear}: {movie}"); } } string[] directories = Directory.GetDirectories(movie); if (directories.Length > 1) { log($"!Directory {directories.Length}: {movie}"); } if (directories.Length == 1 && !string.Equals(Featurettes, Path.GetFileName(directories.Single()))) { log($"!Directory: {directories.Single()}"); } }); if (isLoadingVideo) { PrintVideosWithErrors(allVideos !, isNoAudioAllowed, log); } }