// --------------------------------------------------------------------------------------------------------------------
//
// 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()));
}
}
}