/// <summary> /// Processes a single file. /// </summary> /// <param name="type"> /// The sort type to use. /// </param> /// <param name="file"> /// The file to process. /// </param> /// <param name="destination"> /// The destination to process the files to. /// </param> private void ProcessFile(SortType type, FileResult file, IDirectoryInfo destination) { IFileInfo destinationInfo = file.GetFullPath(destination, this.storageProvider); if (destinationInfo.Directory != null && !destinationInfo.Directory.Exists) { destinationInfo.Directory.Create(); } else { if (!this.HandleRenameAndOverwrite(file, destination, ref destinationInfo)) { return; } } if (destinationInfo.Exists) { Logger.OnLogMessage(this, "Skipping {0}. Already exists.", LogType.Info, destinationInfo.Name.Truncate()); return; } switch (type) { case SortType.Move: file.InputFile.MoveTo(destinationInfo.FullName); Logger.OnLogMessage(this, "Moved {0}", LogType.Info, file.InputFile.Name.Truncate()); if (this.settings.DeleteEmptySubdirectories) { this.DeleteEmptySubdirectories(file); } break; case SortType.Copy: file.InputFile.CopyTo(destinationInfo.FullName); Logger.OnLogMessage(this, "Copied {0}", LogType.Info, file.InputFile.Name.Truncate()); break; } foreach (var episode in file.Episodes) { episode.FileCount++; episode.Save(this.storageProvider); } }
/// <summary> /// Deletes the subdirectories of the file if they are empty. /// </summary> /// <param name="file"> /// The file to check. /// </param> private void DeleteEmptySubdirectories(FileResult file) { // If no files exist in the directory if (file.InputFile.Directory != null && !file.InputFile.Directory.GetFiles().Any() && !file.InputFile.Directory.GetDirectories().Any()) { // If this isn't the source directory if ( !file.InputFile.Directory.FullName.TrimEnd(Path.DirectorySeparatorChar).Equals( this.settings.SourceDirectory.TrimEnd(Path.DirectorySeparatorChar))) { file.InputFile.Directory.Delete(true); Logger.OnLogMessage(this, "Delete directory: {0}", LogType.Info, file.InputFile.DirectoryName.Truncate()); } } }
/// <summary> /// Handles the rename and overwrite of the file. /// </summary> /// <param name="file"> /// The file being processed. /// </param> /// <param name="destination"> /// The destination directory. /// </param> /// <param name="destinationInfo"> /// The destination file. /// </param> /// <returns> /// A value indicating whether the ProcessFile operation should continue or not. /// </returns> private bool HandleRenameAndOverwrite( FileResult file, IDirectoryInfo destination, ref IFileInfo destinationInfo) { // If the directory didn't exist then check it for the episode. bool containsOverwriteKeyword = file.ContainsKeyword(this.settings.OverwriteKeywords); // Rename the file that is already in the destination if it exists under a different name. if (this.settings.RenameIfExists || containsOverwriteKeyword) { // Get the files that are already in the destination directory. List<FileResult> results = this.scanManager.SearchDestinationFolder(destinationInfo.Directory).Where( x => x.Episodes != null && !x.Episodes.Where((t, i) => !file.Episodes[i].Equals(t)).Any()).ToList(); // If the episode already exists. if (results.Count > 0) { if (containsOverwriteKeyword) { foreach (FileResult result in results) { result.InputFile.Delete(); foreach (Episode episode in result.Episodes) { episode.FileCount--; episode.Save(this.storageProvider); } } } else if (this.settings.RenameIfExists && results[0].InputFile.Extension.Equals(destinationInfo.Extension)) { // Can't rename more than 1 file to the same thing. // Also don't rename if the file name is already the same. string currentName = results[0].InputFile.Name; string newName = destinationInfo.Name; if (results.Count == 1 && !currentName.Equals(newName)) { string originalName = results[0].InputFile.Name; results[0].InputFile.MoveTo(destinationInfo.FullName); Logger.OnLogMessage( this, "Renamed {0} to {1}", LogType.Info, originalName.Truncate(30), destinationInfo.Name.Truncate(30)); return false; } } } // Refresh the destination info as it may have changed. destinationInfo = file.GetFullPath(destination, this.storageProvider); } return true; }
public string TestOutputFormat(string format) { // Creat the result. var result = new FileResult { Checked = true, Show = this.TestShows.First(), InputFile = Substitute.For<IFileInfo>() }; result.Episode = result.Show.Episodes.First(); result.Episodes = new List<Episode> { result.Episode }; result.InputFile.Extension.Returns(".avi"); // Format the string. return result.FormatOutputPath(format); }
/// <summary> /// Asserts the result matches the first show and its first episode. /// </summary> /// <param name="result"> /// The result to check. /// </param> private void MatchesShow1(FileResult result) { Assert.AreEqual(this.TestShows.First(), result.Show, "The result should be the first test show."); Assert.AreEqual( this.TestShows.First().Episodes.First(), result.Episode, "The result should match the show's first episode."); }
public void DualEpisodeFormatting() { // Creat the result. var result = new FileResult { Checked = true, Show = this.TestShows.First(), InputFile = Substitute.For<IFileInfo>() }; result.Episode = result.Show.Episodes.First(); result.Episodes = new List<Episode> { result.Episode, result.Show.Episodes[1] }; result.InputFile.Extension.Returns(".avi"); // Format the string. string output = result.FormatOutputPath("{SName(.)}.S{SNum(2)}E{ENum(2)}.{EName(.)}"); Assert.AreEqual( "Alpha.Show.S01E01-02.Episode.One.(1-2)", output, "The output format does not match what it should be."); }
public void FileCopyMove() { IFileInfo file = this.CreateTestFile(this.Root, "alpha.s01e01.avi")[0]; var result = new FileResult { Checked = true, Show = this.TestShows.First(), InputFile = file, }; result.Episode = result.Show.Episodes.First(); result.Episodes = new List<Episode> { result.Episode }; IDirectoryInfo seasonOne = null; this.Root.GetFile(Arg.Any<string>()).Returns( x => { var path = x.Arg<string>(); // Check that the path is as expected string expectedPath = string.Format( "Alpha Folder{0}Season 1{0}Alpha.Show.S01E01.Episode.One.(1).avi", Path.DirectorySeparatorChar); Assert.AreEqual(expectedPath, path, "The path is incorrect."); // Return the correct file. IDirectoryInfo alphaFolder = this.CreateTestDirectory(this.Root, "Alpha Folder")[0]; seasonOne = this.CreateTestDirectory(alphaFolder, "Season 1")[0]; seasonOne.Exists.Returns(false); IFileInfo episodeFile = this.CreateTestFile(seasonOne, "Alpha.Show.S01E01.Episode.One.(1).avi")[0]; episodeFile.Exists.Returns(false); return episodeFile; }); this.fileManager.ProcessFiles(new List<FileResult> { result }, FileManager.SortType.Copy, this.Root); // Check that seasonOne has been created. Assert.NotNull(seasonOne, "The Season One folder should have been created."); // Check that there was a call to its create method. seasonOne.Received(1).Create(); // Copy the files. file.Received(1).CopyTo( string.Format( "TV{0}Alpha Folder{0}Season 1{0}Alpha.Show.S01E01.Episode.One.(1).avi", Path.DirectorySeparatorChar)); // Check that the episode was saved. this.StorageProvider.Received(1).SaveEpisode(result.Episode); this.StorageProvider.ClearReceivedCalls(); // Move the files this.fileManager.ProcessFiles(new List<FileResult> { result }, FileManager.SortType.Move, this.Root); // Should be one call to seasonOne Create since it should have been recreated. seasonOne.Received(1).Create(); // Should be one call to MoveTo with the new directory path. file.Received(1).MoveTo( string.Format( "TV{0}Alpha Folder{0}Season 1{0}Alpha.Show.S01E01.Episode.One.(1).avi", Path.DirectorySeparatorChar)); // Check that the episode was saved. this.StorageProvider.Received(1).SaveEpisode(result.Episode); }
/// <summary> /// Initializes a new instance of the <see cref="FormatBuilder"/> class. /// </summary> /// <param name="currentFormat"> /// The current format. /// </param> public FormatBuilder(string currentFormat) { this.InitializeComponent(); this.exampleResult = FileResult.Example; this.textFormat.Text = currentFormat; }
/// <summary> /// Processes the specified file, overriding the show and episode search. /// </summary> /// <param name="file"> /// The file to process. /// </param> /// <param name="ignoreShowUpdate"> /// A value indicating whether the settings to update and lock shows should be ignored. /// </param> /// <returns> /// The results of the file process. /// </returns> private FileResult ProcessFile(IFileInfo file, bool ignoreShowUpdate) { // Attempt to match to a regular express List<Match> firstMatch = this.GetFirstMatch(file); FileResult emptyResult = null; if (firstMatch == null) { return null; } string showname = string.Empty; //Try to resolve an result foreach (Match match in firstMatch) { TvShow show = this.MatchShow(file.Name, match.Index, out showname, ignoreShowUpdate); Episode episode = null; IList<Episode> episodes = null; if (show != null) { episodes = this.ProcessEpisode(match, show).ToList(); if (episodes.Count > 0) { episode = episodes.First(); } return new FileResult { Episode = episode, Episodes = episodes, InputFile = file, Show = show, ShowName = showname }; } else { emptyResult = new FileResult { Episode = episode, Episodes = episodes, InputFile = file, Show = show, ShowName = showname }; } } return emptyResult; }
/// <summary> /// Resets the show of the specified result. /// </summary> /// <param name="result"> /// The result to modify. /// </param> /// <param name="show"> /// The show to set the result to. /// </param> public void ResetShow(FileResult result, TvShow show) { result.Show = show; List<Match> match = this.GetFirstMatch(result.InputFile); if (match == null) { result.Episode = null; } //Resolve Result foreach (Match m in match) { //result.Episodes = this.ProcessEpisode(match, show).ToList(); //result.Episode = result.Episodes.FirstOrDefault(); } }