// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // Defines the AutoNameHelper type. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.Helpers { using System; using System.IO; using System.Linq; using Caliburn.Micro; using HandBrake.Interop.Interop.Model.Encoding; using HandBrakeWPF.Extensions; using HandBrakeWPF.Services.Encode.Model; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Model; using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; /// /// The Destination AutoName Helper /// public class AutoNameHelper { /// /// Function which generates the filename and path automatically based on /// the Source Name, DVD title and DVD Chapters /// /// /// The task. /// /// /// The Source or Label Name /// /// /// The preset Name. /// /// /// The Generated FileName /// public static string AutoName(EncodeTask task, string sourceOrLabelName, Preset presetName) { IUserSettingService userSettingService = IoC.Get(); if (task.Destination == null) { task.Destination = string.Empty; } string autoNamePath = string.Empty; if (task.Title != 0) { // Get the Source Name and remove any invalid characters string sourceName = Path.GetInvalidFileNameChars().Aggregate(sourceOrLabelName, (current, character) => current.Replace(character.ToString(), string.Empty)); // Remove Underscores if (userSettingService.GetUserSetting(UserSettingConstants.AutoNameRemoveUnderscore)) sourceName = sourceName.Replace("_", " "); if (userSettingService.GetUserSetting(UserSettingConstants.RemovePunctuation)) { sourceName = sourceName.Replace("-", string.Empty); sourceName = sourceName.Replace(",", string.Empty); sourceName = sourceName.Replace(".", string.Empty); } // Switch to "Title Case" if (userSettingService.GetUserSetting(UserSettingConstants.AutoNameTitleCase)) sourceName = sourceName.ToTitleCase(); // Get the Selected Title Number string dvdTitle = task.Title.ToString(); // Get the Chapter Start and Chapter End Numbers string chapterStart = task.StartPoint.ToString(); string chapterFinish = task.EndPoint.ToString(); string combinedChapterTag = chapterStart; if (chapterFinish != chapterStart && chapterFinish != string.Empty) combinedChapterTag = chapterStart + "-" + chapterFinish; // Local method to check if we have a creation time in the meta data. If not, fall back to source file creation time. DateTime obtainCreateDateObject() { var rd = task.MetaData.ReleaseDate; if (DateTime.TryParse(rd, out var d)) { return d; } try { return File.GetCreationTime(task.Source); } catch (Exception e) { if (e is UnauthorizedAccessException || e is PathTooLongException || e is NotSupportedException) { // Suspect the most likely concerns trying to grab the creation date in which we would want to swallow exception. return default(DateTime); } throw e; } } var creationDateTime = obtainCreateDateObject(); string createDate = creationDateTime.Date.ToShortDateString().Replace('/', '-'); string createTime = creationDateTime.ToString("HH-mm"); /* * File Name */ string destinationFilename; if (userSettingService.GetUserSetting(UserSettingConstants.AutoNameFormat) != string.Empty) { destinationFilename = userSettingService.GetUserSetting(UserSettingConstants.AutoNameFormat); destinationFilename = destinationFilename .RegexReplace(Constants.Source, sourceName) .RegexReplace(Constants.Title, dvdTitle) .RegexReplace(Constants.Chapters, combinedChapterTag) .RegexReplace(Constants.Date, DateTime.Now.Date.ToShortDateString().Replace('/', '-')) .RegexReplace(Constants.Time, DateTime.Now.ToString("HH-mm")) .RegexReplace(Constants.CretaionDate, createDate) .RegexReplace(Constants.CreationTime, createTime); if (task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality) { destinationFilename = destinationFilename.Replace(Constants.Quality, task.Quality.ToString()); destinationFilename = destinationFilename.Replace(Constants.Bitrate, string.Empty); } else { destinationFilename = destinationFilename.Replace( Constants.Bitrate, task.VideoBitrate.ToString()); destinationFilename = destinationFilename.Replace(Constants.Quality, string.Empty); } } else { destinationFilename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag; } /* * File Extension */ if (task.OutputFormat == OutputFormat.Mp4) { switch (userSettingService.GetUserSetting(UserSettingConstants.UseM4v, typeof(int))) { case 0: // Automatic destinationFilename += task.IncludeChapterMarkers || MP4Helper.RequiresM4v(task) ? ".m4v" : ".mp4"; break; case 1: // Always MP4 destinationFilename += ".mp4"; break; case 2: // Always M4V destinationFilename += ".m4v"; break; } } else if (task.OutputFormat == OutputFormat.Mkv) { destinationFilename += ".mkv"; } /* * File Destination Path */ // If there is an auto name path, use it... if (userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim().StartsWith("{source_path}") && !string.IsNullOrEmpty(task.Source)) { string savedPath = userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim().Replace("{source_path}\\", string.Empty).Replace("{source_path}", string.Empty); string directory = Directory.Exists(task.Source) ? task.Source : Path.GetDirectoryName(task.Source); string requestedPath = Path.Combine(directory, savedPath); autoNamePath = Path.Combine(requestedPath, destinationFilename); if (autoNamePath == task.Source) { // Append out_ to files that already exist or is the source file autoNamePath = Path.Combine(Path.GetDirectoryName(task.Source), "output_" + destinationFilename); } } else if (userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Contains("{source_folder_name}") && !string.IsNullOrEmpty(task.Source)) { // Second Case: We have a Path, with "{source_folder}" in it, therefore we need to replace it with the folder name from the source. string path = Path.GetDirectoryName(task.Source); if (!string.IsNullOrEmpty(path)) { string[] filesArray = path.Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); string sourceFolder = filesArray[filesArray.Length - 1]; autoNamePath = Path.Combine(userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Replace("{source_folder_name}", sourceFolder), destinationFilename); } } else if (!task.Destination.Contains(Path.DirectorySeparatorChar.ToString())) { // Third case: If the destination box doesn't already contain a path, make one. if (userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim() != string.Empty && userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim() != "Click 'Browse' to set the default location") { autoNamePath = Path.Combine(userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath), destinationFilename); } else { // ...otherwise, output to the source directory autoNamePath = null; } } else { // Otherwise, use the path that is already there. // Use the path and change the file extension to match the previous destination autoNamePath = Path.Combine(Path.GetDirectoryName(task.Destination), destinationFilename); } } return autoNamePath; } /// /// Check if there is a valid autoname path. /// /// /// True if there is a valid path /// public static bool IsAutonamingEnabled() { IUserSettingService userSettingService = IoC.Get(); if (!userSettingService.GetUserSetting(UserSettingConstants.AutoNaming)) { return false; } // If there is an auto name path, use it... return userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim().StartsWith(Constants.SourcePath) || (userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Contains(Constants.SourceFolderName) || Directory.Exists(userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath).Trim())); } } }