using System; using System.Collections.Generic; using System.Linq; using Dinah.Core; namespace FileManager { /// Get valid filename. Advanced features incl. parameterized template public class FileNamingTemplate { /// Proposed full file path. May contain optional html-styled template tags. Eg: <name> public string Template { get; } /// Proposed file name with optional html-styled template tags. public FileNamingTemplate(string template) => Template = ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template)); /// Optional step 1: Replace html-styled template tags with parameters. Eg {"name", "Bill Gates"} => /<name>/ => /Bill Gates/ public Dictionary ParameterReplacements { get; } = new Dictionary(); /// Convenience method public void AddParameterReplacement(string key, object value) // 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; } = 50; /// 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 string GetFilePath() { var filename = Template; foreach (var r in ParameterReplacements) filename = filename.Replace($"<{formatKey(r.Key)}>", formatValue(r.Value)); return FileUtility.GetValidFilename(filename, IllegalCharacterReplacements); } private static string formatKey(string key) => key .Replace("<", "") .Replace(">", ""); private string formatValue(object value) { if (value is null) return ""; // 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 .ToString() .Replace($"{System.IO.Path.DirectorySeparatorChar}", IllegalCharacterReplacements) .Replace($"{System.IO.Path.AltDirectorySeparatorChar}", IllegalCharacterReplacements); return ParameterMaxSize.HasValue && ParameterMaxSize.Value > 0 ? val.Truncate(ParameterMaxSize.Value) : val; } } }