CUDA -> ConvertId

KeePass -> ConvertKeePassExport
NMap -> SplitJsonFile
This commit is contained in:
Mike Phares 2023-12-25 17:10:26 -07:00
parent 1f5743cf74
commit 90380fdd43
5 changed files with 670 additions and 33 deletions

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
@ -92,8 +93,19 @@ internal static partial class Helper20231212
{
}
private record HostName(
[property: JsonPropertyName("Name")] string Name,
[property: JsonPropertyName("Type")] string Type
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(HostName))]
private partial class HostNameSourceGenerationContext : JsonSerializerContext
{
}
private record HostNames(
[property: JsonPropertyName("HostName")] object HostName
[property: JsonPropertyName("HostName")] IReadOnlyList<HostName> HostName
);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
@ -324,99 +336,180 @@ internal static partial class Helper20231212
{
}
private static string? GetStrippedIPV4(string value)
private static string[] GetIPV4Segments(string value)
{
string? result;
string[] result;
string[] subSegments = value.Split('.');
if (subSegments.Length != 4)
result = null;
result = [];
else
{
if (!subSegments.All(l => int.TryParse(l, out _)))
result = null;
result = [];
else
result = value.Replace(".", string.Empty);
result = value.Split('.');
}
return result;
}
private static string? GetStrippedMacAddress(string value)
private static string[] GetMacAddressSegments(string value)
{
string? result;
string[] result;
if (value.Length != 17)
result = null;
result = [];
else
{
if (value[2] is not ':' or '-' || value[5] is not ':' or '-' || value[8] is not ':' or '-' || value[11] is not ':' or '-' || value[14] is not ':' or '-')
result = null;
string v = value.ToLower();
if (v[2] is not ':' or '-' || v[5] is not ':' or '-' || v[8] is not ':' or '-' || v[11] is not ':' or '-' || v[14] is not ':' or '-')
result = [];
else
result = $"{value[0]}{value[1]}{value[3]}{value[4]}{value[6]}{value[7]}{value[9]}{value[10]}{value[12]}{value[13]}{value[15]}{value[16]}".ToLower();
{
result = [$"{v[0]}{v[1]}", $"{v[3]}{v[4]}", $"{v[6]}{v[7]}", $"{v[9]}{v[10]}", $"{v[12]}{v[13]}", $"{v[15]}{v[16]}"];
}
}
return result;
}
private static ReadOnlyCollection<ReadOnlyCollection<string>> GetHostLinesSpaceSegments()
{
List<ReadOnlyCollection<string>> results = [];
string hostFile = "C:/Windows/System32/drivers/etc/hosts";
string[] lines = !File.Exists(hostFile) ? [] : File.ReadAllLines(hostFile);
foreach (string line in lines)
results.Add(new(line.Split(' ')));
return new(results);
}
internal static void SplitJsonFile(ILogger<Worker> logger, List<string> args)
{
string json;
string title;
Record? record;
string fileName;
FileInfo fileInfo;
string checkFileName;
string? strippedIpV4;
string sourceFileName;
string[] ipV4Segments;
string outputDirectory;
List<string> lines = [];
List<string> links = [];
string? strippedMacAddress;
List<string> allLines = [];
string[] macAddressSegments;
string macAddressWithHyphens;
string ipV4SegmentsWithPeriods;
List<string> titleSegments = [];
string fileNameWithoutExtension;
const int ipV4SegmentsLength = 4;
string sourceDirectory = args[0];
const int macAddressSegmentsLength = 6;
string[] fileNameWithoutExtensionSegments;
string fileNameWithoutExtensionFirstThreeSegments;
if (!Directory.Exists(sourceDirectory))
throw new Exception(sourceDirectory);
string outputDirectory = Path.Combine(sourceDirectory, Path.GetFileNameWithoutExtension(args[2]));
if (!Directory.Exists(outputDirectory))
_ = Directory.CreateDirectory(outputDirectory);
string[] files = Directory.GetFiles(args[0], args[2], SearchOption.TopDirectoryOnly);
List<ReadOnlyCollection<string>> hostLineMatchSpaceSegments;
ReadOnlyCollection<ReadOnlyCollection<string>> hostLinesSpaceSegments = GetHostLinesSpaceSegments();
string[] files = Directory.GetFiles(sourceDirectory, args[2], SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
links.Clear();
fileInfo = new(file);
json = File.ReadAllText(file);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
outputDirectory = Path.Combine(sourceDirectory, fileNameWithoutExtension);
fileNameWithoutExtensionSegments = GetIPV4Segments(fileNameWithoutExtension);
if (fileNameWithoutExtensionSegments.Length != ipV4SegmentsLength)
continue;
fileNameWithoutExtensionFirstThreeSegments = $"{fileNameWithoutExtensionSegments[0]}.{fileNameWithoutExtensionSegments[1]}.{fileNameWithoutExtensionSegments[2]}.";
if (!Directory.Exists(outputDirectory))
_ = Directory.CreateDirectory(outputDirectory);
record = JsonSerializer.Deserialize(json, RecordSourceGenerationContext.Default.Record);
if (record is null)
continue;
foreach (Host host in record.Hosts)
{
lines.Clear();
strippedIpV4 = null;
strippedMacAddress = null;
ipV4Segments = [];
titleSegments.Clear();
macAddressSegments = [];
foreach (HostAddress hostAddress in host.HostAddresses)
{
if (hostAddress.AddressType == "ipv4")
strippedIpV4 = GetStrippedIPV4(hostAddress.Address);
ipV4Segments = GetIPV4Segments(hostAddress.Address);
else if (hostAddress.AddressType == "mac")
strippedMacAddress = GetStrippedMacAddress(hostAddress.Address);
macAddressSegments = GetMacAddressSegments(hostAddress.Address);
else
continue;
}
if (strippedMacAddress is null && strippedIpV4 is null)
if (ipV4Segments.Length != ipV4SegmentsLength)
continue;
ipV4SegmentsWithPeriods = string.Join('.', ipV4Segments);
macAddressWithHyphens = string.Join('-', macAddressSegments);
if (macAddressSegments.Length != macAddressSegmentsLength)
hostLineMatchSpaceSegments = (from l in hostLinesSpaceSegments where l.Count > 0 && l.Contains(ipV4SegmentsWithPeriods) select l).ToList();
else
{
hostLineMatchSpaceSegments = (from l in hostLinesSpaceSegments where l.Count > 0 && l.Contains(macAddressWithHyphens) select l).ToList();
if (hostLineMatchSpaceSegments.Count == 1)
title = string.Join(' ', hostLineMatchSpaceSegments[0]);
else
hostLineMatchSpaceSegments = (from l in hostLineMatchSpaceSegments where l.Count > 0 && l[0].StartsWith(fileNameWithoutExtensionFirstThreeSegments) select l).ToList();
}
if (ipV4Segments.Length == ipV4SegmentsLength)
titleSegments.Add(ipV4SegmentsWithPeriods);
if (hostLineMatchSpaceSegments.Count == 1)
title = $"{ipV4SegmentsWithPeriods} {string.Join(' ', hostLineMatchSpaceSegments[0].Skip(1))}";
else
{
if (host.HostNames.HostName is null)
titleSegments.Add("unknown #");
else
titleSegments.Add($"{string.Join("_", host.HostNames.HostName.Select(l => l.Name.Replace(' ', '-')))} #");
if (macAddressSegments.Length == macAddressSegmentsLength)
titleSegments.Add(macAddressWithHyphens);
title = string.Join(" ", titleSegments);
logger.LogInformation("{title} Type DeviceInfo ~ needs to be added to host file!", title);
}
json = JsonSerializer.Serialize(host, HostSourceGenerationContext.Default.Host);
fileNameWithoutExtension = strippedMacAddress is null ? $"ipv4-{strippedIpV4}" : $"mac-{strippedMacAddress}";
fileNameWithoutExtension = macAddressSegments.Length != macAddressSegmentsLength ? $"ipv4-{string.Join(string.Empty, ipV4Segments)}" : $"mac-{string.Join(string.Empty, macAddressSegments)}";
fileName = $"{fileNameWithoutExtension}.md";
links.Add($"- [{string.Join(" - ", host.HostAddresses.Select(l => l.Address))}]({fileName})");
lines.Add($"# {fileNameWithoutExtension}");
links.Add($"- [{title}]({fileName})");
lines.Add("---");
allLines.Add(title);
lines.Add(string.Empty);
lines.Add($"# {title}");
lines.Add(string.Empty);
lines.Add($"## {fileNameWithoutExtension}");
if (host.Ports is not null)
{
lines.Add(string.Empty);
lines.Add("## Port(s)");
lines.Add(string.Empty);
lines.Add("| Id | Protocol | State | Service |");
lines.Add("| - | - | - | - |");
foreach (Port port in host.Ports)
lines.Add($"| {port.PortID} | {port.Protocol} | {port.State.Value} | {port.Service.Name} |");
}
lines.Add(string.Empty);
lines.Add("```json");
lines.Add(json);
lines.Add("```");
lines.Add(string.Empty);
logger.LogInformation("{fileName} created", fileName);
checkFileName = Path.Combine(outputDirectory, fileName);
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
File.SetCreationTime(checkFileName, fileInfo.CreationTime);
File.SetLastWriteTime(checkFileName, fileInfo.LastWriteTime);
logger.LogInformation("{title} created", title);
}
lines.Clear();
record.Hosts.Clear();
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
title = Path.GetFileNameWithoutExtension(file);
json = JsonSerializer.Serialize(record, RecordSourceGenerationContext.Default.Record);
lines.Add($"# {fileNameWithoutExtension}");
lines.Add("---");
lines.Add(string.Empty);
lines.Add($"# {title}");
lines.Add(string.Empty);
lines.Add($"## {title}");
lines.Add(string.Empty);
lines.Add("## Hosts");
lines.Add(string.Empty);
@ -425,11 +518,25 @@ internal static partial class Helper20231212
lines.Add("```json");
lines.Add(json);
lines.Add("```");
checkFileName = Path.Combine(outputDirectory, $"{fileNameWithoutExtension}-links.md");
checkFileName = Path.Combine(outputDirectory, $"{title}.md");
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.WriteAllLines(checkFileName, lines);
File.SetCreationTime(checkFileName, fileInfo.CreationTime);
File.SetLastWriteTime(checkFileName, fileInfo.LastWriteTime);
logger.LogInformation("{title} created", title);
checkFileName = Path.Combine(outputDirectory, Path.GetFileName(file));
if (File.Exists(checkFileName))
File.Delete(checkFileName);
File.Move(file, checkFileName);
checkFileName = Path.Combine(outputDirectory, $"{Path.GetFileNameWithoutExtension(file)}.xml");
if (File.Exists(checkFileName))
File.Delete(checkFileName);
sourceFileName = Path.ChangeExtension(file, ".xml");
if (File.Exists(sourceFileName))
File.Move(sourceFileName, checkFileName);
}
File.WriteAllLines(Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}.ssv"), allLines);
}
}

295
Day/Helper-2023-12-21.cs Normal file
View File

@ -0,0 +1,295 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml.Linq;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231221
{
// Folders with these names will be put in the root instead.
private static readonly string[] _BlacklistedFolders =
[
"KeePassHttp Passwords",
"KeePassXC-Browser Passwords"
];
private static readonly string[] _BlacklistedFields = [
"KeePassXC-Browser Settings",
"KeePassHttp Settings"
];
private static Func<XElement, bool> OtherFields()
{
return x =>
{
string? key = x.Element("Key")?.Value;
return key != "Title" && key != "Notes" && key != "UserName" && key != "Password" &&
key != "URL" && !_BlacklistedFields.Contains(key);
};
}
private record Field(
[property: JsonPropertyName("name")] string? Name,
[property: JsonPropertyName("value")] string? Value,
[property: JsonPropertyName("type")] int? Type
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Field))]
private partial class FieldSourceGenerationContext : JsonSerializerContext
{
}
private record Folder(
[property: JsonPropertyName("id")] string? Id,
[property: JsonPropertyName("name")] string? Name
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Folder))]
private partial class FolderSourceGenerationContext : JsonSerializerContext
{
}
private record Item(
[property: JsonPropertyName("revisionDate")] string? RevisionDate,
[property: JsonPropertyName("creationDate")] string? CreationDate,
[property: JsonPropertyName("folderId")] string? FolderId,
[property: JsonPropertyName("type")] int Type,
[property: JsonPropertyName("name")] string? Name,
[property: JsonPropertyName("notes")] string? Notes,
[property: JsonPropertyName("fields")] IReadOnlyList<Field>? Fields,
[property: JsonPropertyName("login")] Login Login
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Item))]
private partial class ItemSourceGenerationContext : JsonSerializerContext
{
}
private record Login(
[property: JsonPropertyName("uris")] IReadOnlyList<Uri> Uris,
[property: JsonPropertyName("username")] string? Username,
[property: JsonPropertyName("password")] string? Password
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Login))]
private partial class LoginSourceGenerationContext : JsonSerializerContext
{
}
private record Root(
[property: JsonPropertyName("folders")] IReadOnlyList<Folder> Folders,
[property: JsonPropertyName("items")] IReadOnlyList<Item> Items
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
private partial class RootSourceGenerationContext : JsonSerializerContext
{
}
private record Uri(
[property: JsonPropertyName("uri")] string? Value,
[property: JsonPropertyName("host")] string? Host
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Uri))]
private partial class UriSourceGenerationContext : JsonSerializerContext
{
}
private static Item? GetEntry(string folderId, XElement entry)
{
Item? result;
XElement[] stringFields = entry.Elements("String").ToArray();
string? name = stringFields.Where(x => x.Element("Key")?.Value == "Title").Select(x => x.Element("Value")?.Value).FirstOrDefault();
if (_BlacklistedFields.Contains(name))
result = null;
else
{
XElement[] timesFields = entry.Elements("Times").ToArray();
string? creationTime = timesFields.Elements("CreationTime").FirstOrDefault()?.Value;
string? revisionDate = timesFields.Elements("LastModificationTime").FirstOrDefault()?.Value;
string? uri = stringFields.Where(x => x.Element("Key")?.Value == "URL").Select(x => x.Element("Value")?.Value).FirstOrDefault();
string? notes = stringFields.Where(x => x.Element("Key")?.Value == "Notes").Select(x => x.Element("Value")?.Value).FirstOrDefault();
string? username = stringFields.Where(x => x.Element("Key")?.Value == "UserName").Select(x => x.Element("Value")?.Value).FirstOrDefault();
string? password = stringFields.Where(x => x.Element("Key")?.Value == "Password").Select(x => x.Element("Value")?.Value).FirstOrDefault();
string? host = string.IsNullOrEmpty(uri) || !uri.Contains(':') ? null : new System.Uri(uri).Host;
Login login = new(new Uri[] { new(uri, host) }, username, password);
List<Field> itemFields = stringFields.Where(OtherFields()).Select(x => new Field(x.Element("Key")?.Value, x.Element("Value")?.Value, 0)).ToList();
result = new(revisionDate,
creationTime,
folderId,
1,
name,
string.IsNullOrEmpty(notes) ? null : notes,
itemFields.Count > 0 ? itemFields : null,
login);
}
return result;
}
private static List<Item> Filter(List<Item> items)
{
List<Item> results = [];
string key;
Item result;
Login login;
string? uri;
string? host;
string? name;
string? folderId;
string? username;
List<Item>? check;
string? creationTime;
string? revisionDate;
List<string> notes = [];
string? password = null;
string?[] checkPasswords;
Dictionary<string, List<Item>> keyValuePairs = [];
foreach (Item item in items)
{
key = string.Concat(item.Login.Username, '-', string.Join('-', item.Login.Uris.Select(l => l.Host)));
if (!keyValuePairs.TryGetValue(key, out check))
{
keyValuePairs.Add(key, []);
if (!keyValuePairs.TryGetValue(key, out check))
throw new NotSupportedException();
}
check.Add(item);
}
foreach (KeyValuePair<string, List<Item>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Value.Count == 1)
results.AddRange(keyValuePair.Value);
else
{
checkPasswords = keyValuePair.Value.Select(l => l.Login.Password).Distinct().ToArray();
if (checkPasswords.Length == 1)
results.Add(keyValuePair.Value[0]);
else
{
uri = null;
host = null;
name = null;
notes.Clear();
folderId = null;
username = null;
creationTime = null;
revisionDate = null;
notes.Add("Unset Password");
foreach (Item item in from l in keyValuePair.Value orderby l.RevisionDate, l.Login.Password?.Length descending select l)
{
if (item.Login.Uris.Count == 1)
{
uri = item.Login.Uris[0].Value;
host = item.Login.Uris[0].Host;
}
name = item.Name;
folderId = item.FolderId;
username = item.Login.Username;
creationTime = item.CreationDate;
revisionDate = item.RevisionDate;
notes.Add($"{item.Login.Password} on {item.RevisionDate}");
}
login = new(new Uri[] { new(uri, host) }, username, password);
result = new(revisionDate,
creationTime,
folderId,
1,
name,
string.Join(Environment.NewLine, notes),
null,
login);
results.Add(result);
}
}
}
results = (from l in results orderby l.Login.Uris[0].Host, l.Login.Username select l).ToList();
return results;
}
private static void SaveTabSeparatedValueFiles(List<Item> items, string xmlFile)
{
List<string> lines = [];
foreach (Item item in items)
lines.Add($"{item.Login.Uris[0].Host}\t{item.Login.Username}\t{item.Login.Password}");
File.WriteAllLines(Path.ChangeExtension(xmlFile, ".tvs"), lines);
}
internal static void ConvertKeePassExport(ILogger<Worker> logger, List<string> args)
{
Root root;
Item? item;
string json;
string folderId;
string groupKey;
List<Item> items;
XElement element;
string newGroupKey;
XDocument xDocument;
List<Folder> folders;
string childGroupName;
string outputPath = args[0];
string newExtension = args[3];
IEnumerable<XElement> childEntries;
IEnumerable<XElement> childElements;
Dictionary<string, string> namesToIds;
Queue<KeyValuePair<string, XElement>> groupsToProcess;
string[] xmlFiles = Directory.GetFiles(args[0], args[2]);
foreach (string xmlFile in xmlFiles)
{
xDocument = XDocument.Load(xmlFile);
if (xDocument.Root is null)
throw new Exception("Root element missing");
items = [];
folders = [];
namesToIds = [];
groupsToProcess = [];
logger.LogInformation($"Loaded XML {xmlFile}.", xmlFile);
groupsToProcess.Enqueue(new KeyValuePair<string, XElement>("", xDocument.Root.Descendants("Group").First()));
while (groupsToProcess.TryDequeue(out KeyValuePair<string, XElement> valuePair))
{
groupKey = valuePair.Key;
element = valuePair.Value;
folderId = Guid.NewGuid().ToString();
childElements = element.Elements("Group");
folders.Add(new Folder(folderId, groupKey));
foreach (XElement childElement in childElements)
{
childGroupName = (childElement.Element("Name")?.Value) ?? throw new Exception("Found group with no name, malformed file");
if (_BlacklistedFolders.Contains(childGroupName))
childGroupName = "";
newGroupKey = $"{groupKey}/{childGroupName}";
if (groupKey == "")
newGroupKey = childGroupName;
logger.LogInformation($"Found group '{newGroupKey}'");
groupsToProcess.Enqueue(new KeyValuePair<string, XElement>(newGroupKey, childElement));
}
childEntries = element.Elements("Entry");
foreach (XElement entry in childEntries)
{
item = GetEntry(folderId, entry);
if (item is null)
continue;
items.Add(item);
}
}
items = Filter(items);
root = new(folders, items);
logger.LogInformation("Serializing output file...");
json = JsonSerializer.Serialize(root, RootSourceGenerationContext.Default.Root);
logger.LogInformation("Writing output file...");
File.WriteAllText(Path.ChangeExtension(xmlFile, newExtension), json);
SaveTabSeparatedValueFiles(items, xmlFile);
}
logger.LogInformation("Done!");
}
}

231
Day/Helper-2023-12-22.cs Normal file
View File

@ -0,0 +1,231 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text;
namespace File_Folder_Helper.Day;
internal static partial class Helper20231222
{
private record Record(string File,
string DestinationDirectory,
string DestinationFile);
private record IntelligentIdRecord(int Key,
ReadOnlyCollection<char> ResultAllInOneSubdirectoryChars,
string Reverse);
private record FilePath(long CreationTicks,
string DirectoryName,
string ExtensionLowered,
string FileNameFirstSegment,
string FullName,
int? Id,
bool IsIntelligentIdFormat,
long LastWriteTicks,
long Length,
string Name,
string NameWithoutExtension,
int? SortOrder);
public record MetadataConfiguration(int ResultAllInOneSubdirectoryLength, int Offset, int IntMinValueLength);
private static short GetSortOrderOnlyLengthIndex(MetadataConfiguration metadataConfiguration) =>
(short)metadataConfiguration.Offset.ToString().Length;
private static int GetId(MetadataConfiguration metadataConfiguration, string intelligentId)
{
int result;
StringBuilder results = new();
if (metadataConfiguration.IntMinValueLength < (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
for (int i = intelligentId.Length - (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2); i > -1; i--)
_ = results.Append(intelligentId[i]);
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
result = int.Parse(results.ToString());
if (intelligentId[^1] is '1' or '2')
result *= -1;
else if (intelligentId[^1] is not '9' and not '8')
throw new NotSupportedException();
return result;
}
private static IntelligentIdRecord GetIntelligentIdRecord(MetadataConfiguration metadataConfiguration, long id, bool ignore)
{
IntelligentIdRecord result;
StringBuilder stringBuilder = new();
if (metadataConfiguration.IntMinValueLength < (metadataConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
int key;
string value;
List<char> chars = [];
if (id > -1)
{
key = ignore ? 8 : 9;
value = id.ToString().PadLeft(metadataConfiguration.IntMinValueLength, '0');
}
else
{
key = ignore ? 2 : 1;
value = id.ToString()[1..].PadLeft(metadataConfiguration.IntMinValueLength, '0');
}
for (int i = value.Length - metadataConfiguration.ResultAllInOneSubdirectoryLength - 1; i > -1; i--)
_ = stringBuilder.Append(value[i]);
for (int i = value.Length - metadataConfiguration.ResultAllInOneSubdirectoryLength; i < value.Length; i++)
chars.Add(value[i]);
result = new(key, new(chars), stringBuilder.ToString());
return result;
}
private static string GetIntelligentId(IntelligentIdRecord intelligentId) =>
$"{intelligentId.Reverse}{string.Join(string.Empty, intelligentId.ResultAllInOneSubdirectoryChars)}{intelligentId.Key}";
private static bool NameWithoutExtensionIsIntelligentIdFormat(MetadataConfiguration metadataConfiguration, string fileNameFirstSegment) =>
fileNameFirstSegment.Length - 1 == metadataConfiguration.IntMinValueLength && fileNameFirstSegment[^1] is '1' or '2' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber);
private static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataConfiguration metadataConfiguration, short sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
fileNameFirstSegment.Length == metadataConfiguration.IntMinValueLength + sortOrderOnlyLengthIndex + 1
&& fileNameFirstSegment[^1] is '1' or '2' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber);
private static bool NameWithoutExtensionIsIdFormat(MetadataConfiguration metadataConfiguration, string fileNameFirstSegment)
{
bool result;
if (fileNameFirstSegment.Length < 5 || fileNameFirstSegment.Length > metadataConfiguration.IntMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameFirstSegment[1..].All(char.IsNumber);
result = (skipOneAllAreNumbers && fileNameFirstSegment[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameFirstSegment[0]));
}
return result;
}
private static FilePath GetFilePath(MetadataConfiguration metadataConfiguration, FileInfo fileInfo, int? index)
{
FilePath result;
int? id;
int? sortOder;
string fileNameFirstSegment = fileInfo.Name.Split('.')[0];
short sortOrderOnlyLengthIndex = GetSortOrderOnlyLengthIndex(metadataConfiguration);
string fileDirectoryName = fileInfo.DirectoryName ?? throw new NullReferenceException();
bool fileNameFirstSegmentIsIntelligentIdFormat = NameWithoutExtensionIsIntelligentIdFormat(metadataConfiguration, fileNameFirstSegment);
bool fileNameFirstSegmentIsPaddedIntelligentIdFormat = NameWithoutExtensionIsPaddedIntelligentIdFormat(metadataConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !fileNameFirstSegmentIsPaddedIntelligentIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && NameWithoutExtensionIsIdFormat(metadataConfiguration, fileNameFirstSegment);
if (fileNameFirstSegmentIsIdFormat)
{
if (index is null)
throw new NullReferenceException(nameof(index));
if (!int.TryParse(fileNameFirstSegment, out int valueOfFileNameFirstSegment))
throw new NotSupportedException();
(id, sortOder) = (valueOfFileNameFirstSegment, metadataConfiguration.Offset + index);
}
else if (!fileNameFirstSegmentIsIntelligentIdFormat && !fileNameFirstSegmentIsPaddedIntelligentIdFormat)
(id, sortOder) = (null, null);
else if (fileNameFirstSegmentIsIntelligentIdFormat)
(id, sortOder) = (GetId(metadataConfiguration, fileNameFirstSegment), null);
else if (fileNameFirstSegmentIsPaddedIntelligentIdFormat)
{
if (!int.TryParse(fileNameFirstSegment[..sortOrderOnlyLengthIndex], out int absoluteValueOfSortOrder))
(id, sortOder) = (null, null);
else
(id, sortOder) = (GetId(metadataConfiguration, fileNameFirstSegment[sortOrderOnlyLengthIndex..]), absoluteValueOfSortOrder);
}
else
throw new NotSupportedException();
result = new(fileInfo.CreationTime.Ticks,
fileDirectoryName,
fileInfo.Extension.ToLower(),
fileNameFirstSegment,
fileInfo.FullName,
id,
fileNameFirstSegmentIsIntelligentIdFormat,
fileInfo.LastWriteTime.Ticks,
fileInfo.Length,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.Name),
sortOder);
return result;
}
private static ReadOnlyCollection<Record> GetRecords(MetadataConfiguration metadataConfiguration, string sourceDirectory, string searchPattern)
{
List<Record> results = [];
int check;
int index = -1;
FileInfo fileInfo;
FilePath filePath;
string? directory;
string[] segments;
bool ignore = false;
string directoryName;
string intelligentId;
string? parentDirectory;
IntelligentIdRecord intelligentIdRecord;
string sourceParentDirectory = Path.GetDirectoryName(sourceDirectory) ?? throw new NotSupportedException();
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
index += 1;
directory = Path.GetDirectoryName(file);
if (directory is null)
continue;
parentDirectory = Path.GetDirectoryName(directory);
if (parentDirectory is null)
continue;
fileInfo = new(file);
directoryName = Path.GetFileName(directory);
filePath = GetFilePath(metadataConfiguration, fileInfo, index);
if (filePath.Id is null)
continue;
intelligentIdRecord = GetIntelligentIdRecord(metadataConfiguration, filePath.Id.Value, ignore);
intelligentId = GetIntelligentId(intelligentIdRecord);
check = GetId(metadataConfiguration, intelligentId);
if (check != filePath.Id.Value)
throw new NotSupportedException();
segments = Path.GetFileName(file).Split('.');
if (segments.Length == 2)
{
if (filePath.SortOrder is not null)
results.Add(new(file, directory, $"{filePath.SortOrder.Value}{intelligentId}.{segments[1]}"));
else
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars)), $"{intelligentId}.{segments[1]}"));
}
else if (segments.Length == 3)
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars)), $"{intelligentId}.{segments[1]}.{segments[2]}"));
else if (segments.Length == 4)
{
if (directoryName != segments[0])
results.Add(new(file, directory, $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}"));
else
results.Add(new(file, Path.Combine(sourceParentDirectory, intelligentIdRecord.Key.ToString(), string.Join(string.Empty, intelligentIdRecord.ResultAllInOneSubdirectoryChars), intelligentId), $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}"));
}
else if (segments.Length == 5)
results.Add(new(file, directory, $"{intelligentId}.{segments[1]}.{segments[2]}.{segments[3]}.{segments[4]}"));
else
continue;
}
return new(results);
}
internal static void ConvertId(ILogger<Worker> logger, List<string> args)
{
List<string> distinct = [];
string searchPattern = args[2];
string sourceDirectory = args[0];
logger.LogInformation("{sourceDirectory}", sourceDirectory);
MetadataConfiguration metadataConfiguration = new(2, 1000000, int.MinValue.ToString().Length);
ReadOnlyCollection<Record> records = GetRecords(metadataConfiguration, sourceDirectory, searchPattern);
foreach (Record record in records)
{
if (distinct.Contains(record.DestinationDirectory))
continue;
distinct.Add(record.DestinationDirectory);
if (!Directory.Exists(record.DestinationDirectory))
_ = Directory.CreateDirectory(record.DestinationDirectory);
}
foreach (Record record in records)
File.Move(record.File, Path.Combine(record.DestinationDirectory, record.DestinationFile));
}
}

View File

@ -30,6 +30,10 @@ internal static class HelperDay
Day.Helper20231205.SplitMarkdownFile(logger, args);
else if (args[1] == "Day-Helper-2023-12-12")
Day.Helper20231212.SplitJsonFile(logger, args);
else if (args[1] == "Day-Helper-2023-12-21")
Day.Helper20231221.ConvertKeePassExport(logger, args);
else if (args[1] == "Day-Helper-2023-12-22")
Day.Helper20231222.ConvertId(logger, args);
else
throw new Exception(appSettings.Company);
}

View File

@ -405,12 +405,12 @@ internal static partial class HelperMarkdown
jsonLines.Add($"{segmentsLast},");
else if (DateTime.TryParse(segmentsLast, out DateTime dateTime))
jsonLines.Add($"\"{segmentsLast}\",");
else if (segmentsLast.All(l => char.IsNumber(l)))
else if (segmentsLast.All(char.IsNumber))
jsonLines.Add($"{segmentsLast},");
else
{
segmentsB = segmentsLast.Split('.');
if (segmentsB.Length == 2 && segmentsB[0].Length < 7 && segmentsB[^1].Length < 7 && segmentsB[0].All(l => char.IsNumber(l)) && segmentsB[^1].All(l => char.IsNumber(l)))
if (segmentsB.Length == 2 && segmentsB[0].Length < 7 && segmentsB[^1].Length < 7 && segmentsB[0].All(char.IsNumber) && segmentsB[^1].All(char.IsNumber))
jsonLines.Add($"{segmentsLast},");
else if (!segmentsLast.Contains('[') && !segmentsLast.Contains('{'))
jsonLines.Add($"\"{segmentsLast}\",");