Date format naming templates
This commit is contained in:
parent
9309aea6d9
commit
3479dbc3f0
@ -10,6 +10,6 @@ namespace AaxDecrypter
|
|||||||
public int PartsPosition { get; set; }
|
public int PartsPosition { get; set; }
|
||||||
public int PartsTotal { get; set; }
|
public int PartsTotal { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
public DateTime FileDate { get; } = DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,11 +27,13 @@ namespace FileLiberator
|
|||||||
public static LibraryBookDto ToDto(this LibraryBook libraryBook) => new()
|
public static LibraryBookDto ToDto(this LibraryBook libraryBook) => new()
|
||||||
{
|
{
|
||||||
Account = libraryBook.Account,
|
Account = libraryBook.Account,
|
||||||
|
DateAdded = libraryBook.DateAdded,
|
||||||
|
|
||||||
AudibleProductId = libraryBook.Book.AudibleProductId,
|
AudibleProductId = libraryBook.Book.AudibleProductId,
|
||||||
Title = libraryBook.Book.Title ?? "",
|
Title = libraryBook.Book.Title ?? "",
|
||||||
Locale = libraryBook.Book.Locale,
|
Locale = libraryBook.Book.Locale,
|
||||||
YearPublished = libraryBook.Book.DatePublished?.Year,
|
YearPublished = libraryBook.Book.DatePublished?.Year,
|
||||||
|
DatePublished = libraryBook.Book.DatePublished,
|
||||||
|
|
||||||
Authors = libraryBook.Book.Authors.Select(c => c.Name).ToList(),
|
Authors = libraryBook.Book.Authors.Select(c => c.Name).ToList(),
|
||||||
|
|
||||||
|
|||||||
@ -9,11 +9,15 @@ namespace FileManager
|
|||||||
/// <summary>Get valid filename. Advanced features incl. parameterized template</summary>
|
/// <summary>Get valid filename. Advanced features incl. parameterized template</summary>
|
||||||
public class FileNamingTemplate : NamingTemplate
|
public class FileNamingTemplate : NamingTemplate
|
||||||
{
|
{
|
||||||
|
public ReplacementCharacters ReplacementCharacters { get; }
|
||||||
/// <param name="template">Proposed file name with optional html-styled template tags.</param>
|
/// <param name="template">Proposed file name with optional html-styled template tags.</param>
|
||||||
public FileNamingTemplate(string template) : base(template) { }
|
public FileNamingTemplate(string template, ReplacementCharacters replacement) : base(template)
|
||||||
|
{
|
||||||
|
ReplacementCharacters = replacement ?? ReplacementCharacters.Default;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Generate a valid path for this file or directory</summary>
|
/// <summary>Generate a valid path for this file or directory</summary>
|
||||||
public LongPath GetFilePath(ReplacementCharacters replacements, string fileExtension, bool returnFirstExisting = false)
|
public LongPath GetFilePath(string fileExtension, bool returnFirstExisting = false)
|
||||||
{
|
{
|
||||||
string fileName =
|
string fileName =
|
||||||
Template.EndsWith(Path.DirectorySeparatorChar) || Template.EndsWith(Path.AltDirectorySeparatorChar) ?
|
Template.EndsWith(Path.DirectorySeparatorChar) || Template.EndsWith(Path.AltDirectorySeparatorChar) ?
|
||||||
@ -22,7 +26,7 @@ namespace FileManager
|
|||||||
|
|
||||||
List<string> pathParts = new();
|
List<string> pathParts = new();
|
||||||
|
|
||||||
var paramReplacements = ParameterReplacements.ToDictionary(r => $"<{formatKey(r.Key)}>", r => formatValue(r.Value, replacements));
|
var paramReplacements = ParameterReplacements.ToDictionary(r => $"<{formatKey(r.Key)}>", r => formatValue(r.Value, ReplacementCharacters));
|
||||||
|
|
||||||
while (!string.IsNullOrEmpty(fileName))
|
while (!string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
@ -54,7 +58,7 @@ namespace FileManager
|
|||||||
return FileUtility
|
return FileUtility
|
||||||
.GetValidFilename(
|
.GetValidFilename(
|
||||||
Path.Join(directory, replaceFileName(fileNamePart, paramReplacements, LongPath.MaxFilenameLength - fileExtension.Length - 5)) + fileExtension,
|
Path.Join(directory, replaceFileName(fileNamePart, paramReplacements, LongPath.MaxFilenameLength - fileExtension.Length - 5)) + fileExtension,
|
||||||
replacements,
|
ReplacementCharacters,
|
||||||
fileExtension,
|
fileExtension,
|
||||||
returnFirstExisting
|
returnFirstExisting
|
||||||
);
|
);
|
||||||
|
|||||||
@ -50,7 +50,9 @@ namespace LibationAvalonia.Dialogs
|
|||||||
{
|
{
|
||||||
var dataGrid = sender as DataGrid;
|
var dataGrid = sender as DataGrid;
|
||||||
|
|
||||||
var item = (dataGrid.SelectedItem as Tuple<string, string>).Item1.Replace("\x200C", "").Replace("...", "");
|
var item = (dataGrid.SelectedItem as Tuple<string, string, string>).Item3;
|
||||||
|
if (string.IsNullOrWhiteSpace(item)) return;
|
||||||
|
|
||||||
var text = userEditTbox.Text;
|
var text = userEditTbox.Text;
|
||||||
|
|
||||||
userEditTbox.Text = text.Insert(Math.Min(Math.Max(0, userEditTbox.CaretIndex), text.Length), item);
|
userEditTbox.Text = text.Insert(Math.Min(Math.Max(0, userEditTbox.CaretIndex), text.Length), item);
|
||||||
@ -84,13 +86,14 @@ namespace LibationAvalonia.Dialogs
|
|||||||
Template = templates;
|
Template = templates;
|
||||||
Description = templates.Description;
|
Description = templates.Description;
|
||||||
ListItems
|
ListItems
|
||||||
= new AvaloniaList<Tuple<string, string>>(
|
= new AvaloniaList<Tuple<string, string, string>>(
|
||||||
Template
|
Template
|
||||||
.GetTemplateTags()
|
.GetTemplateTags()
|
||||||
.Select(
|
.Select(
|
||||||
t => new Tuple<string, string>(
|
t => new Tuple<string, string, string>(
|
||||||
$"<{t.TagName.Replace("->", "-\x200C>").Replace("<-", "<\x200C-")}>",
|
$"<{t.TagName.Replace("->", "-\x200C>").Replace("<-", "<\x200C-")}>",
|
||||||
t.Description)
|
t.Description,
|
||||||
|
t.DefaultValue)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -108,13 +111,13 @@ namespace LibationAvalonia.Dialogs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string workingTemplateText => Template.Sanitize(UserTemplateText);
|
public string workingTemplateText => Template.Sanitize(UserTemplateText, Configuration.Instance.ReplacementCharacters);
|
||||||
private string _warningText;
|
private string _warningText;
|
||||||
public string WarningText { get => _warningText; set => this.RaiseAndSetIfChanged(ref _warningText, value); }
|
public string WarningText { get => _warningText; set => this.RaiseAndSetIfChanged(ref _warningText, value); }
|
||||||
|
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
|
|
||||||
public AvaloniaList<Tuple<string, string>> ListItems { get; set; }
|
public AvaloniaList<Tuple<string, string, string>> ListItems { get; set; }
|
||||||
|
|
||||||
public void resetTextBox(string value) => UserTemplateText = value;
|
public void resetTextBox(string value) => UserTemplateText = value;
|
||||||
|
|
||||||
@ -138,6 +141,8 @@ namespace LibationAvalonia.Dialogs
|
|||||||
var libraryBookDto = new LibraryBookDto
|
var libraryBookDto = new LibraryBookDto
|
||||||
{
|
{
|
||||||
Account = "my account",
|
Account = "my account",
|
||||||
|
DateAdded = new DateTime(2022, 6, 9, 0, 0, 0),
|
||||||
|
DatePublished = new DateTime(2017, 2, 27, 0, 0, 0),
|
||||||
AudibleProductId = "123456789",
|
AudibleProductId = "123456789",
|
||||||
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
||||||
Locale = "us",
|
Locale = "us",
|
||||||
|
|||||||
@ -25,10 +25,14 @@ namespace LibationFileManager
|
|||||||
public int BitRate { get; set; }
|
public int BitRate { get; set; }
|
||||||
public int SampleRate { get; set; }
|
public int SampleRate { get; set; }
|
||||||
public int Channels { get; set; }
|
public int Channels { get; set; }
|
||||||
}
|
public DateTime FileDate { get; set; } = DateTime.Now;
|
||||||
|
public DateTime? DatePublished { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class LibraryBookDto : BookDto
|
public class LibraryBookDto : BookDto
|
||||||
{
|
{
|
||||||
public string Account { get; set; }
|
public DateTime? DateAdded { get; set; }
|
||||||
|
public string Account { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,16 +7,19 @@ namespace LibationFileManager
|
|||||||
{
|
{
|
||||||
public sealed class TemplateTags : Enumeration<TemplateTags>
|
public sealed class TemplateTags : Enumeration<TemplateTags>
|
||||||
{
|
{
|
||||||
public string TagName => DisplayName;
|
public string TagName => DisplayName;
|
||||||
|
public string DefaultValue { get; }
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
public bool IsChapterOnly { get; }
|
public bool IsChapterOnly { get; }
|
||||||
|
|
||||||
private static int value = 0;
|
private static int value = 0;
|
||||||
private TemplateTags(string tagName, string description, bool isChapterOnly = false) : base(value++, tagName)
|
private TemplateTags(string tagName, string description, bool isChapterOnly = false, string defaultValue = null) : base(value++, tagName)
|
||||||
{
|
{
|
||||||
Description = description;
|
Description = description;
|
||||||
IsChapterOnly = isChapterOnly;
|
IsChapterOnly = isChapterOnly;
|
||||||
}
|
DefaultValue = defaultValue ?? $"<{tagName}>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// putting these first is the incredibly lazy way to make them show up first in the EditTemplateDialog
|
// putting these first is the incredibly lazy way to make them show up first in the EditTemplateDialog
|
||||||
public static TemplateTags ChCount { get; } = new TemplateTags("ch count", "Number of chapters", true);
|
public static TemplateTags ChCount { get; } = new TemplateTags("ch count", "Number of chapters", true);
|
||||||
@ -43,7 +46,9 @@ namespace LibationFileManager
|
|||||||
|
|
||||||
// Special cases. Aren't mapped to replacements in Templates.cs
|
// Special cases. Aren't mapped to replacements in Templates.cs
|
||||||
// Included here for display by EditTemplateDialog
|
// Included here for display by EditTemplateDialog
|
||||||
public static TemplateTags Date { get; } = new TemplateTags("date[...]", "File date/time. e.g. yyyy-MM-dd HH-mm");
|
public static TemplateTags FileDate { get; } = new TemplateTags("file date [...]", "File date/time. e.g. yyyy-MM-dd HH-mm", false, $"<file date [{Templates.DEFAULT_DATE_FORMAT}]>");
|
||||||
public static TemplateTags IfSeries { get; } = new TemplateTags("if series->...<-if series", "Only include if part of a series");
|
public static TemplateTags DatePublished { get; } = new TemplateTags("pub date [...]", "Publication date. e.g. yyyy-MM-dd", false, $"<pub date [{Templates.DEFAULT_DATE_FORMAT}]>");
|
||||||
|
public static TemplateTags DateAdded { get; } = new TemplateTags("date added [...]", "Date added to you Audible account. e.g. yyyy-MM-dd", false, $"<date added [{Templates.DEFAULT_DATE_FORMAT}]>");
|
||||||
|
public static TemplateTags IfSeries { get; } = new TemplateTags("if series->...<-if series", "Only include if part of a series", false, "<if series-><-if series>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
|
using Dinah.Core.Collections.Generic;
|
||||||
using FileManager;
|
using FileManager;
|
||||||
|
|
||||||
namespace LibationFileManager
|
namespace LibationFileManager
|
||||||
@ -102,17 +103,21 @@ namespace LibationFileManager
|
|||||||
public string GetPortionFilename(LibraryBookDto libraryBookDto, string template, string fileExtension)
|
public string GetPortionFilename(LibraryBookDto libraryBookDto, string template, string fileExtension)
|
||||||
=> string.IsNullOrWhiteSpace(template)
|
=> string.IsNullOrWhiteSpace(template)
|
||||||
? ""
|
? ""
|
||||||
: getFileNamingTemplate(libraryBookDto, template, null, fileExtension)
|
: getFileNamingTemplate(libraryBookDto, template, null, fileExtension, Configuration.Instance.ReplacementCharacters)
|
||||||
.GetFilePath(Configuration.Instance.ReplacementCharacters, fileExtension).PathWithoutPrefix;
|
.GetFilePath(fileExtension).PathWithoutPrefix;
|
||||||
|
|
||||||
private static Regex dateFormatRegex { get; } = new Regex(@"<date\[(.*?)\]>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
public const string DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||||
|
private static Regex fileDateTagRegex { get; } = new Regex(@"<file\s*?date\s*?(?:\s*?|\[(.*?)\])\s*?>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
private static Regex dateAddedTagRegex { get; } = new Regex(@"<date\s*?added\s*?(?:\s*?|\[(.*?)\])\s*?>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
private static Regex datePublishedTagRegex { get; } = new Regex(@"<pub\s*?date\s*?(?:\s*?|\[(.*?)\])\s*?>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension)
|
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension, ReplacementCharacters replacements)
|
||||||
{
|
{
|
||||||
ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template));
|
ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template));
|
||||||
ArgumentValidator.EnsureNotNull(libraryBookDto, nameof(libraryBookDto));
|
ArgumentValidator.EnsureNotNull(libraryBookDto, nameof(libraryBookDto));
|
||||||
|
|
||||||
|
replacements ??= Configuration.Instance.ReplacementCharacters;
|
||||||
dirFullPath = dirFullPath?.Trim() ?? "";
|
dirFullPath = dirFullPath?.Trim() ?? "";
|
||||||
|
|
||||||
// for non-series, remove <if series-> and <-if series> tags and everything in between
|
// for non-series, remove <if series-> and <-if series> tags and everything in between
|
||||||
@ -121,12 +126,16 @@ namespace LibationFileManager
|
|||||||
template,
|
template,
|
||||||
string.IsNullOrWhiteSpace(libraryBookDto.SeriesName) ? "" : "$1");
|
string.IsNullOrWhiteSpace(libraryBookDto.SeriesName) ? "" : "$1");
|
||||||
|
|
||||||
template = dateFormatRegex.Replace(template, dateMatchEvaluator);
|
//Get date replacement parameters. Sanitizes the format text and replaces
|
||||||
|
//the template with the sanitized text before creating FileNamingTemplate
|
||||||
|
var fileDateParams = getSanitizeDateReplacementParameters(fileDateTagRegex, ref template, replacements, libraryBookDto.FileDate);
|
||||||
|
var dateAddedParams = getSanitizeDateReplacementParameters(dateAddedTagRegex, ref template, replacements, libraryBookDto.DateAdded);
|
||||||
|
var pubDateParams = getSanitizeDateReplacementParameters(datePublishedTagRegex, ref template, replacements, libraryBookDto.DatePublished);
|
||||||
|
|
||||||
var t = template + FileUtility.GetStandardizedExtension(extension);
|
var t = template + FileUtility.GetStandardizedExtension(extension);
|
||||||
var fullfilename = dirFullPath == "" ? t : Path.Combine(dirFullPath, t);
|
var fullfilename = dirFullPath == "" ? t : Path.Combine(dirFullPath, t);
|
||||||
|
|
||||||
var fileNamingTemplate = new FileNamingTemplate(fullfilename);
|
var fileNamingTemplate = new FileNamingTemplate(fullfilename, replacements);
|
||||||
|
|
||||||
var title = libraryBookDto.Title ?? "";
|
var title = libraryBookDto.Title ?? "";
|
||||||
var titleShort = title.IndexOf(':') < 1 ? title : title.Substring(0, title.IndexOf(':'));
|
var titleShort = title.IndexOf(':') < 1 ? title : title.Substring(0, title.IndexOf(':'));
|
||||||
@ -147,31 +156,92 @@ namespace LibationFileManager
|
|||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale);
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale);
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.YearPublished, libraryBookDto.YearPublished?.ToString() ?? "1900");
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.YearPublished, libraryBookDto.YearPublished?.ToString() ?? "1900");
|
||||||
|
|
||||||
return fileNamingTemplate;
|
//Add the sanitized replacement parameters
|
||||||
|
foreach (var param in fileDateParams)
|
||||||
|
fileNamingTemplate.ParameterReplacements.AddIfNotContains(param);
|
||||||
|
foreach (var param in dateAddedParams)
|
||||||
|
fileNamingTemplate.ParameterReplacements.AddIfNotContains(param);
|
||||||
|
foreach (var param in pubDateParams)
|
||||||
|
fileNamingTemplate.ParameterReplacements.AddIfNotContains(param);
|
||||||
|
|
||||||
|
return fileNamingTemplate;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static string dateMatchEvaluator(Match match)
|
#region DateTime Tags
|
||||||
|
|
||||||
|
/// <param name="template">the file naming template. Any found date tags will be sanitized,
|
||||||
|
/// and the template's original date tag will be replaced with the sanitized tag.</param>
|
||||||
|
/// <returns>A list of parameter replacement key-value pairs</returns>
|
||||||
|
private static List<KeyValuePair<string, object>> getSanitizeDateReplacementParameters(Regex datePattern, ref string template, ReplacementCharacters replacements, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
|
List<KeyValuePair<string, object>> dateParams = new();
|
||||||
|
|
||||||
|
foreach (Match dateTag in datePattern.Matches(template))
|
||||||
|
{
|
||||||
|
var sanitizedTag = sanitizeDateParameterTag(dateTag, replacements, out var sanitizedFormatter);
|
||||||
|
if (tryFormatDateTime(dateTime, sanitizedFormatter, replacements, out var formattedDateString))
|
||||||
|
{
|
||||||
|
dateParams.Add(new(sanitizedTag, formattedDateString));
|
||||||
|
template = template.Replace(dateTag.Value, sanitizedTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dateParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <returns>a date parameter replacement tag with the format string sanitized</returns>
|
||||||
|
private static string sanitizeDateParameterTag(Match dateTag, ReplacementCharacters replacements, out string sanitizedFormatter)
|
||||||
|
{
|
||||||
|
if (dateTag.Groups.Count < 2 || string.IsNullOrWhiteSpace(dateTag.Groups[1].Value))
|
||||||
|
{
|
||||||
|
sanitizedFormatter = DEFAULT_DATE_FORMAT;
|
||||||
|
return dateTag.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var formatter = dateTag.Groups[1].Value;
|
||||||
|
|
||||||
|
sanitizedFormatter = replacements.ReplaceFilenameChars(formatter).Trim();
|
||||||
|
|
||||||
|
return dateTag.Value.Replace(formatter, sanitizedFormatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool tryFormatDateTime(DateTime? dateTime, string sanitizedFormatter, ReplacementCharacters replacements, out string formattedDateString)
|
||||||
|
{
|
||||||
|
if (!dateTime.HasValue)
|
||||||
|
{
|
||||||
|
formattedDateString = string.Empty;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DateTime.Now.ToString(match.Groups[1].Value);
|
formattedDateString = replacements.ReplaceFilenameChars(dateTime.Value.ToString(sanitizedFormatter)).Trim();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return match.Value;
|
formattedDateString = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public virtual IEnumerable<TemplateTags> GetTemplateTags()
|
public virtual IEnumerable<TemplateTags> GetTemplateTags()
|
||||||
=> TemplateTags.GetAll()
|
=> TemplateTags.GetAll()
|
||||||
// yeah, this line is a little funky but it works when you think through it. also: trust the unit tests
|
// yeah, this line is a little funky but it works when you think through it. also: trust the unit tests
|
||||||
.Where(t => IsChapterized || !t.IsChapterOnly);
|
.Where(t => IsChapterized || !t.IsChapterOnly);
|
||||||
|
|
||||||
public string Sanitize(string template)
|
public string Sanitize(string template, ReplacementCharacters replacements)
|
||||||
{
|
{
|
||||||
var value = template ?? "";
|
var value = template ?? "";
|
||||||
|
|
||||||
|
// Replace invalid filename characters in the DateTime format provider so we don't trip any alarms.
|
||||||
|
// Illegal filename characters in the formatter are allowed because they will be replaced by
|
||||||
|
// getFileNamingTemplate()
|
||||||
|
value = fileDateTagRegex.Replace(value, m => sanitizeDateParameterTag(m, replacements, out _));
|
||||||
|
value = dateAddedTagRegex.Replace(value, m => sanitizeDateParameterTag(m, replacements, out _));
|
||||||
|
value = datePublishedTagRegex.Replace(value, m => sanitizeDateParameterTag(m, replacements, out _));
|
||||||
|
|
||||||
// don't use alt slash
|
// don't use alt slash
|
||||||
value = value.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
value = value.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
@ -218,7 +288,7 @@ namespace LibationFileManager
|
|||||||
|
|
||||||
// must be relative. no colons. all other path chars are valid enough to pass this check and will be handled on final save.
|
// must be relative. no colons. all other path chars are valid enough to pass this check and will be handled on final save.
|
||||||
if (ReplacementCharacters.ContainsInvalidPathChar(template.Replace("<", "").Replace(">", "")))
|
if (ReplacementCharacters.ContainsInvalidPathChar(template.Replace("<", "").Replace(">", "")))
|
||||||
return new[] { ERROR_INVALID_FILE_NAME_CHAR };
|
return new[] { ERROR_INVALID_FILE_NAME_CHAR };
|
||||||
|
|
||||||
return Valid;
|
return Valid;
|
||||||
}
|
}
|
||||||
@ -229,8 +299,8 @@ namespace LibationFileManager
|
|||||||
#region to file name
|
#region to file name
|
||||||
/// <summary>USES LIVE CONFIGURATION VALUES</summary>
|
/// <summary>USES LIVE CONFIGURATION VALUES</summary>
|
||||||
public string GetFilename(LibraryBookDto libraryBookDto, string baseDir = null)
|
public string GetFilename(LibraryBookDto libraryBookDto, string baseDir = null)
|
||||||
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FolderTemplate, baseDir ?? AudibleFileStorage.BooksDirectory, null)
|
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FolderTemplate, baseDir ?? AudibleFileStorage.BooksDirectory, null, Configuration.Instance.ReplacementCharacters)
|
||||||
.GetFilePath(Configuration.Instance.ReplacementCharacters, string.Empty);
|
.GetFilePath(string.Empty);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,8 +322,8 @@ namespace LibationFileManager
|
|||||||
#region to file name
|
#region to file name
|
||||||
/// <summary>USES LIVE CONFIGURATION VALUES</summary>
|
/// <summary>USES LIVE CONFIGURATION VALUES</summary>
|
||||||
public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension, bool returnFirstExisting = false)
|
public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension, bool returnFirstExisting = false)
|
||||||
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FileTemplate, dirFullPath, extension)
|
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FileTemplate, dirFullPath, extension, Configuration.Instance.ReplacementCharacters)
|
||||||
.GetFilePath(Configuration.Instance.ReplacementCharacters, extension, returnFirstExisting);
|
.GetFilePath(extension, returnFirstExisting);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,14 +364,21 @@ namespace LibationFileManager
|
|||||||
|
|
||||||
replacements ??= Configuration.Instance.ReplacementCharacters;
|
replacements ??= Configuration.Instance.ReplacementCharacters;
|
||||||
var fileExtension = Path.GetExtension(props.OutputFileName);
|
var fileExtension = Path.GetExtension(props.OutputFileName);
|
||||||
var fileNamingTemplate = getFileNamingTemplate(libraryBookDto, template, fullDirPath, fileExtension);
|
var fileNamingTemplate = getFileNamingTemplate(libraryBookDto, template, fullDirPath, fileExtension, replacements);
|
||||||
|
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChCount, props.PartsTotal);
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChCount, props.PartsTotal);
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber, props.PartsPosition);
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber, props.PartsPosition);
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber0, FileUtility.GetSequenceFormatted(props.PartsPosition, props.PartsTotal));
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber0, FileUtility.GetSequenceFormatted(props.PartsPosition, props.PartsTotal));
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChTitle, props.Title ?? "");
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChTitle, props.Title ?? "");
|
||||||
|
|
||||||
return fileNamingTemplate.GetFilePath(replacements, fileExtension).PathWithoutPrefix;
|
foreach (Match dateTag in fileDateTagRegex.Matches(fileNamingTemplate.Template))
|
||||||
|
{
|
||||||
|
var sanitizedTag = sanitizeDateParameterTag(dateTag, replacements, out string sanitizedFormatter);
|
||||||
|
if (tryFormatDateTime(props.FileDate, sanitizedFormatter, replacements, out var formattedDateString))
|
||||||
|
fileNamingTemplate.ParameterReplacements[sanitizedTag] = formattedDateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileNamingTemplate.GetFilePath(fileExtension).PathWithoutPrefix;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,5 +9,8 @@ namespace LibationFileManager
|
|||||||
{
|
{
|
||||||
public static void AddParameterReplacement(this NamingTemplate fileNamingTemplate, TemplateTags templateTags, object value)
|
public static void AddParameterReplacement(this NamingTemplate fileNamingTemplate, TemplateTags templateTags, object value)
|
||||||
=> fileNamingTemplate.AddParameterReplacement(templateTags.TagName, value);
|
=> fileNamingTemplate.AddParameterReplacement(templateTags.TagName, value);
|
||||||
|
|
||||||
|
public static void AddUniqueParameterReplacement(this NamingTemplate namingTemplate, string key, object value)
|
||||||
|
=> namingTemplate.ParameterReplacements[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
private string workingTemplateText
|
private string workingTemplateText
|
||||||
{
|
{
|
||||||
get => _workingTemplateText;
|
get => _workingTemplateText;
|
||||||
set => _workingTemplateText = template.Sanitize(value);
|
set => _workingTemplateText = template.Sanitize(value, Configuration.Instance.ReplacementCharacters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetTextBox(string value) => this.templateTb.Text = workingTemplateText = value;
|
private void resetTextBox(string value) => this.templateTb.Text = workingTemplateText = value;
|
||||||
@ -59,7 +59,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
|
|
||||||
// populate list view
|
// populate list view
|
||||||
foreach (var tag in template.GetTemplateTags())
|
foreach (var tag in template.GetTemplateTags())
|
||||||
listView1.Items.Add(new ListViewItem(new[] { $"<{tag.TagName}>", tag.Description }));
|
listView1.Items.Add(new ListViewItem(new[] { $"<{tag.TagName}>", tag.Description }) { Tag = tag.DefaultValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetToDefaultBtn_Click(object sender, EventArgs e) => resetTextBox(template.DefaultTemplate);
|
private void resetToDefaultBtn_Click(object sender, EventArgs e) => resetTextBox(template.DefaultTemplate);
|
||||||
@ -73,6 +73,8 @@ namespace LibationWinForms.Dialogs
|
|||||||
var libraryBookDto = new LibraryBookDto
|
var libraryBookDto = new LibraryBookDto
|
||||||
{
|
{
|
||||||
Account = "my account",
|
Account = "my account",
|
||||||
|
DateAdded = new DateTime(2022, 6, 9, 0, 0, 0),
|
||||||
|
DatePublished = new DateTime(2017, 2, 27, 0, 0, 0),
|
||||||
AudibleProductId = "123456789",
|
AudibleProductId = "123456789",
|
||||||
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
||||||
Locale = "us",
|
Locale = "us",
|
||||||
@ -207,9 +209,11 @@ namespace LibationWinForms.Dialogs
|
|||||||
|
|
||||||
private void listView1_DoubleClick(object sender, EventArgs e)
|
private void listView1_DoubleClick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var itemText = listView1.SelectedItems[0].Text.Replace("...", "");
|
var itemText = listView1.SelectedItems[0].Tag as string;
|
||||||
var text = templateTb.Text;
|
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(itemText)) return;
|
||||||
|
|
||||||
|
var text = templateTb.Text;
|
||||||
var selStart = Math.Min(Math.Max(0, templateTb.SelectionStart), text.Length);
|
var selStart = Math.Min(Math.Max(0, templateTb.SelectionStart), text.Length);
|
||||||
|
|
||||||
templateTb.Text = text.Insert(selStart, itemText);
|
templateTb.Text = text.Insert(selStart, itemText);
|
||||||
|
|||||||
@ -36,10 +36,10 @@ namespace FileNamingTemplateTests
|
|||||||
extension = FileUtility.GetStandardizedExtension(extension);
|
extension = FileUtility.GetStandardizedExtension(extension);
|
||||||
var fullfilename = Path.Combine(dirFullPath, template + extension);
|
var fullfilename = Path.Combine(dirFullPath, template + extension);
|
||||||
|
|
||||||
var fileNamingTemplate = new FileNamingTemplate(fullfilename);
|
var fileNamingTemplate = new FileNamingTemplate(fullfilename, Replacements);
|
||||||
fileNamingTemplate.AddParameterReplacement("title", filename);
|
fileNamingTemplate.AddParameterReplacement("title", filename);
|
||||||
fileNamingTemplate.AddParameterReplacement("id", metadataSuffix);
|
fileNamingTemplate.AddParameterReplacement("id", metadataSuffix);
|
||||||
return fileNamingTemplate.GetFilePath(Replacements, extension).PathWithoutPrefix;
|
return fileNamingTemplate.GetFilePath(extension).PathWithoutPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -61,10 +61,10 @@ namespace FileNamingTemplateTests
|
|||||||
var estension = Path.GetExtension(originalPath);
|
var estension = Path.GetExtension(originalPath);
|
||||||
var t = Path.ChangeExtension(originalPath, null) + " - <chapter> - <title>" + estension;
|
var t = Path.ChangeExtension(originalPath, null) + " - <chapter> - <title>" + estension;
|
||||||
|
|
||||||
var fileNamingTemplate = new FileNamingTemplate(t);
|
var fileNamingTemplate = new FileNamingTemplate(t, Replacements);
|
||||||
fileNamingTemplate.AddParameterReplacement("chapter", chapterCountLeadingZeros);
|
fileNamingTemplate.AddParameterReplacement("chapter", chapterCountLeadingZeros);
|
||||||
fileNamingTemplate.AddParameterReplacement("title", suffix);
|
fileNamingTemplate.AddParameterReplacement("title", suffix);
|
||||||
return fileNamingTemplate.GetFilePath(Replacements, estension).PathWithoutPrefix;
|
return fileNamingTemplate.GetFilePath(estension).PathWithoutPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -74,9 +74,9 @@ namespace FileNamingTemplateTests
|
|||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == platformID)
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
{
|
{
|
||||||
var fileNamingTemplate = new FileNamingTemplate(inStr);
|
var fileNamingTemplate = new FileNamingTemplate(inStr, Replacements);
|
||||||
fileNamingTemplate.AddParameterReplacement("title", @"s\l/a\s/h\e/s");
|
fileNamingTemplate.AddParameterReplacement("title", @"s\l/a\s/h\e/s");
|
||||||
fileNamingTemplate.GetFilePath(Replacements, "txt").PathWithoutPrefix.Should().Be(outStr);
|
fileNamingTemplate.GetFilePath("txt").PathWithoutPrefix.Should().Be(outStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -26,11 +26,32 @@ namespace TemplatesTests
|
|||||||
=> new()
|
=> new()
|
||||||
{
|
{
|
||||||
Account = "my account",
|
Account = "my account",
|
||||||
|
DateAdded = new DateTime(2022, 6, 9, 0, 0, 0),
|
||||||
|
DatePublished = new DateTime(2017, 2, 27, 0, 0, 0),
|
||||||
|
FileDate = new DateTime(2023, 1, 28, 0, 0, 0),
|
||||||
AudibleProductId = "asin",
|
AudibleProductId = "asin",
|
||||||
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
||||||
Locale = "us",
|
Locale = "us",
|
||||||
YearPublished = 2017,
|
YearPublished = 2017,
|
||||||
Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" },
|
Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" },
|
||||||
|
Narrators = new List<string> { "Stephen Fry" },
|
||||||
|
SeriesName = seriesName ?? "",
|
||||||
|
SeriesNumber = "1",
|
||||||
|
BitRate = 128,
|
||||||
|
SampleRate = 44100,
|
||||||
|
Channels = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
public static LibraryBookDto GetLibraryBookWithNullDates(string seriesName = "Sherlock Holmes")
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Account = "my account",
|
||||||
|
FileDate = new DateTime(2023, 1, 28, 0, 0, 0),
|
||||||
|
AudibleProductId = "asin",
|
||||||
|
Title = "A Study in Scarlet: A Sherlock Holmes Novel",
|
||||||
|
Locale = "us",
|
||||||
|
YearPublished = 2017,
|
||||||
|
Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" },
|
||||||
Narrators = new List<string> { "Stephen Fry" },
|
Narrators = new List<string> { "Stephen Fry" },
|
||||||
SeriesName = seriesName ?? "",
|
SeriesName = seriesName ?? "",
|
||||||
SeriesNumber = "1",
|
SeriesNumber = "1",
|
||||||
@ -71,14 +92,14 @@ namespace TemplatesTests
|
|||||||
[DataRow(null, @"C:\", "ext")]
|
[DataRow(null, @"C:\", "ext")]
|
||||||
[ExpectedException(typeof(ArgumentNullException))]
|
[ExpectedException(typeof(ArgumentNullException))]
|
||||||
public void arg_null_exception(string template, string dirFullPath, string extension)
|
public void arg_null_exception(string template, string dirFullPath, string extension)
|
||||||
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension);
|
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements);
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[DataRow("", @"C:\foo\bar", "ext")]
|
[DataRow("", @"C:\foo\bar", "ext")]
|
||||||
[DataRow(" ", @"C:\foo\bar", "ext")]
|
[DataRow(" ", @"C:\foo\bar", "ext")]
|
||||||
[ExpectedException(typeof(ArgumentException))]
|
[ExpectedException(typeof(ArgumentException))]
|
||||||
public void arg_exception(string template, string dirFullPath, string extension)
|
public void arg_exception(string template, string dirFullPath, string extension)
|
||||||
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension);
|
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements);
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[DataRow("f.txt", @"C:\foo\bar", "", @"C:\foo\bar\f.txt", PlatformID.Win32NT)]
|
[DataRow("f.txt", @"C:\foo\bar", "", @"C:\foo\bar\f.txt", PlatformID.Win32NT)]
|
||||||
@ -98,20 +119,126 @@ namespace TemplatesTests
|
|||||||
public void Tests(string template, string dirFullPath, string extension, string expected, PlatformID platformID)
|
public void Tests(string template, string dirFullPath, string extension, string expected, PlatformID platformID)
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == platformID)
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension)
|
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements)
|
||||||
.GetFilePath(Replacements, extension)
|
.GetFilePath(extension)
|
||||||
.PathWithoutPrefix
|
.PathWithoutPrefix
|
||||||
.Should().Be(expected);
|
.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow("<id> - <filedate[yy-MM-dd]>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 23-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <filedate [ yy-MM-dd ] >", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 23-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <file date [yy-MM-dd] >", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 23-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <file date[yy-MM-dd]>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 23-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <file date[]>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <filedate[]>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <filedate [ ] >", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <filedate>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <filedate >", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <file date>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
[DataRow("<id> - <file date>", @"C:\foo\bar", "m4b", @"C:\foo\bar\asin - 2023-01-28.m4b")]
|
||||||
|
public void DateFormat_pattern(string template, string dirFullPath, string extension, string expected)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Platform is not PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
dirFullPath = dirFullPath.Replace("C:", "").Replace('\\', '/');
|
||||||
|
expected = expected.Replace("C:", "").Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements)
|
||||||
|
.GetFilePath(extension)
|
||||||
|
.PathWithoutPrefix
|
||||||
|
.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow("<filedate[h]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[h]>.m4b")]
|
||||||
|
[DataRow("< filedate[yyyy]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\< filedate[yyyy]>.m4b")]
|
||||||
|
[DataRow("<filedate yyyy]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate yyyy]>.m4b")]
|
||||||
|
[DataRow("<filedate [yyyy>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate [yyyy>.m4b")]
|
||||||
|
[DataRow("<filedate yyyy>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate yyyy>.m4b")]
|
||||||
|
[DataRow("<filedate[yyyy]", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[yyyy].m4b")]
|
||||||
|
[DataRow("<fil edate[yyyy]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<fil edate[yyyy]>.m4b")]
|
||||||
|
[DataRow("<filed ate[yyyy]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filed ate[yyyy]>.m4b")]
|
||||||
|
public void DateFormat_invalid(string template, string dirFullPath, string extension, string expected)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Platform is not PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
dirFullPath = dirFullPath.Replace("C:", "").Replace('\\', '/');
|
||||||
|
expected = expected.Replace("C:", "").Replace('\\', '/').Replace('<', '<').Replace('>','>');
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements)
|
||||||
|
.GetFilePath(extension)
|
||||||
|
.PathWithoutPrefix
|
||||||
|
.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow("<filedate[yy-MM-dd]> <date added[yy-MM-dd]> <pubdate[yy-MM]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\23-01-28 22-06-09 17-02.m4b")]
|
||||||
|
[DataRow("<filedate[yy-MM-dd]> <filedate[yy-MM-dd]> <filedate[yy-MM-dd]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\23-01-28 23-01-28 23-01-28.m4b")]
|
||||||
|
[DataRow("<file date [ yy-MM-dd ] > <filedate [ yy-MM-dd ] > <file date [ yy-MM-dd] >", @"C:\foo\bar", ".m4b", @"C:\foo\bar\23-01-28 23-01-28 23-01-28.m4b")]
|
||||||
|
public void DateFormat_multiple(string template, string dirFullPath, string extension, string expected)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Platform is not PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
dirFullPath = dirFullPath.Replace("C:", "").Replace('\\', '/');
|
||||||
|
expected = expected.Replace("C:", "").Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements)
|
||||||
|
.GetFilePath(extension)
|
||||||
|
.PathWithoutPrefix
|
||||||
|
.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow("<id> - <pubdate[MM/dd/yy HH:mm]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\asin - 02∕27∕17 00꞉00.m4b", PlatformID.Win32NT)]
|
||||||
|
[DataRow("<id> - <pubdate[MM/dd/yy HH:mm]>", @"/foo/bar", ".m4b", @"/foo/bar/asin - 02∕27∕17 00:00.m4b", PlatformID.Unix)]
|
||||||
|
[DataRow("<id> - <filedate[MM/dd/yy HH:mm]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\asin - 01∕28∕23 00꞉00.m4b", PlatformID.Win32NT)]
|
||||||
|
[DataRow("<id> - <filedate[MM/dd/yy HH:mm]>", @"/foo/bar", ".m4b", @"/foo/bar/asin - 01∕28∕23 00:00.m4b", PlatformID.Unix)]
|
||||||
|
[DataRow("<id> - <date added[MM/dd/yy HH:mm]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\asin - 06∕09∕22 00꞉00.m4b", PlatformID.Win32NT)]
|
||||||
|
[DataRow("<id> - <date added[MM/dd/yy HH:mm]>", @"/foo/bar", ".m4b", @"/foo/bar/asin - 06∕09∕22 00:00.m4b", PlatformID.Unix)]
|
||||||
|
public void DateFormat_illegal(string template, string dirFullPath, string extension, string expected, PlatformID platformID)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
|
{
|
||||||
|
Templates.File.HasWarnings(template).Should().BeTrue();
|
||||||
|
Templates.File.HasWarnings(Templates.File.Sanitize(template, Replacements)).Should().BeFalse();
|
||||||
|
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension, Replacements)
|
||||||
|
.GetFilePath(extension)
|
||||||
|
.PathWithoutPrefix
|
||||||
|
.Should().Be(expected);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow("<filedate[yy-MM-dd]> <date added[yy-MM-dd]> <pubdate[yy-MM]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\23-01-28.m4b")]
|
||||||
|
public void DateFormat_null(string template, string dirFullPath, string extension, string expected)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.Platform is not PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
dirFullPath = dirFullPath.Replace("C:", "").Replace('\\', '/');
|
||||||
|
expected = expected.Replace("C:", "").Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates.getFileNamingTemplate(GetLibraryBookWithNullDates(), template, dirFullPath, extension, Replacements)
|
||||||
|
.GetFilePath(extension)
|
||||||
|
.PathWithoutPrefix
|
||||||
|
.Should().Be(expected);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[DataRow(@"C:\a\b", @"C:\a\b\foobar.ext", PlatformID.Win32NT)]
|
[DataRow(@"C:\a\b", @"C:\a\b\foobar.ext", PlatformID.Win32NT)]
|
||||||
[DataRow(@"/a/b", @"/a/b/foobar.ext", PlatformID.Unix)]
|
[DataRow(@"/a/b", @"/a/b/foobar.ext", PlatformID.Unix)]
|
||||||
public void IfSeries_empty(string directory, string expected, PlatformID platformID)
|
public void IfSeries_empty(string directory, string expected, PlatformID platformID)
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == platformID)
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series-><-if series>bar", directory, "ext")
|
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series-><-if series>bar", directory, "ext", Replacements)
|
||||||
.GetFilePath(Replacements, ".ext")
|
.GetFilePath(".ext")
|
||||||
.PathWithoutPrefix
|
.PathWithoutPrefix
|
||||||
.Should().Be(expected);
|
.Should().Be(expected);
|
||||||
}
|
}
|
||||||
@ -122,8 +249,8 @@ namespace TemplatesTests
|
|||||||
public void IfSeries_no_series(string directory, string expected, PlatformID platformID)
|
public void IfSeries_no_series(string directory, string expected, PlatformID platformID)
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == platformID)
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
Templates.getFileNamingTemplate(GetLibraryBook(null), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext")
|
Templates.getFileNamingTemplate(GetLibraryBook(null), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext", Replacements)
|
||||||
.GetFilePath(Replacements, ".ext")
|
.GetFilePath(".ext")
|
||||||
.PathWithoutPrefix
|
.PathWithoutPrefix
|
||||||
.Should().Be(expected);
|
.Should().Be(expected);
|
||||||
}
|
}
|
||||||
@ -134,8 +261,8 @@ namespace TemplatesTests
|
|||||||
public void IfSeries_with_series(string directory, string expected, PlatformID platformID)
|
public void IfSeries_with_series(string directory, string expected, PlatformID platformID)
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == platformID)
|
if (Environment.OSVersion.Platform == platformID)
|
||||||
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext")
|
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext", Replacements)
|
||||||
.GetFilePath(Replacements, ".ext")
|
.GetFilePath(".ext")
|
||||||
.PathWithoutPrefix
|
.PathWithoutPrefix
|
||||||
.Should().Be(expected);
|
.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user