diff --git a/Source/FileManager/FileNamingTemplate.cs b/Source/FileManager/FileNamingTemplate.cs
index f21b3b06..b22f0007 100644
--- a/Source/FileManager/FileNamingTemplate.cs
+++ b/Source/FileManager/FileNamingTemplate.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text;
using Dinah.Core;
namespace FileManager
@@ -22,21 +23,65 @@ namespace FileManager
// using .Add() instead of "[key] = value" will make unintended overwriting throw exception
=> ParameterReplacements.Add(key, value);
- /// If set, truncate each parameter replacement to this many characters. Default 50
- public int? ParameterMaxSize { get; set; } = null;
-
/// Optional step 2: Replace all illegal characters with this. Default=
public string IllegalCharacterReplacements { get; set; }
/// Generate a valid path for this file or directory
public LongPath GetFilePath(bool returnFirstExisting = false)
{
- var filename = Template;
-
- foreach (var r in ParameterReplacements)
- filename = filename.Replace($"<{formatKey(r.Key)}>", formatValue(r.Value));
+ int lastSlash = Template.LastIndexOf('\\');
- return FileUtility.GetValidFilename(filename, IllegalCharacterReplacements, returnFirstExisting);
+ var directoryName = lastSlash >= 0 ? Template[..(lastSlash + 1)] : string.Empty;
+ var filename = lastSlash >= 0 ? Template[(lastSlash + 1)..] : Template;
+
+ List filenameParts = new();
+
+ var paramReplacements = ParameterReplacements.ToDictionary(r => $"<{formatKey(r.Key)}>", r => formatValue(r.Value));
+
+ //Build the filename in parts, replacing replacement parameters with
+ //their values, and storing the parts in a list.
+ while(!string.IsNullOrEmpty(filename))
+ {
+ int openIndex = filename.IndexOf('<');
+ int closeIndex = filename.IndexOf('>');
+
+ if (openIndex == 0 && closeIndex > 0)
+ {
+ var key = filename[..(closeIndex + 1)];
+
+ if (paramReplacements.ContainsKey(key))
+ filenameParts.Add(new StringBuilder(paramReplacements[key]));
+ else
+ filenameParts.Add(new StringBuilder(key));
+
+ filename = filename[(closeIndex + 1)..];
+ }
+ else if (openIndex > 0 && closeIndex > openIndex)
+ {
+ var other = filename[..openIndex];
+ filenameParts.Add(new StringBuilder(other));
+ filename = filename[openIndex..];
+ }
+ else
+ {
+ filenameParts.Add(new StringBuilder(filename));
+ filename = string.Empty;
+ }
+ }
+
+ //Remove 1 character from the end of the longest filename part until
+ //the total filename is less than max filename length
+ while(filenameParts.Sum(p => p.Length) > LongPath.MaxFilenameLength)
+ {
+ int maxLength = filenameParts.Max(p => p.Length);
+ var maxEntry = filenameParts.First(p => p.Length == maxLength);
+
+ maxEntry.Remove(maxLength - 1, 1);
+ }
+
+ filename = string.Join("", filenameParts);
+
+ return FileUtility.GetValidFilename(directoryName + filename, IllegalCharacterReplacements, returnFirstExisting);
}
private static string formatKey(string key)
@@ -51,14 +96,10 @@ namespace FileManager
// Other illegal characters will be taken care of later. Must take care of slashes now so params can't introduce new folders.
// Esp important for file templates.
- var val = value
+ return value
.ToString()
.Replace($"{System.IO.Path.DirectorySeparatorChar}", IllegalCharacterReplacements)
.Replace($"{System.IO.Path.AltDirectorySeparatorChar}", IllegalCharacterReplacements);
- return
- ParameterMaxSize.HasValue && ParameterMaxSize.Value > 0
- ? val.Truncate(ParameterMaxSize.Value)
- : val;
}
}
}