feat: add concatenation option

The option makes possible to concatenate multiple kml files generated by the program
This commit is contained in:
cuqmbr 2022-08-17 12:56:12 +03:00
parent f22b812060
commit 2748647eb3
3 changed files with 125 additions and 13 deletions

View File

@ -8,7 +8,8 @@ namespace netxml2kml.Methods;
public static class CliOptionsHandlers public static class CliOptionsHandlers
{ {
public static void UniversalHandler(FileInfo? inputFile, public static void UniversalHandler(FileInfo? inputFile,
FileInfo? outputFile, bool useDatabase, string? sqlQuery) FileInfo? outputFile, bool useDatabase, string? sqlQuery,
IEnumerable<FileInfo>? concatFiles)
{ {
// Run some logic based on options combination // Run some logic based on options combination
if (inputFile != null && outputFile != null) if (inputFile != null && outputFile != null)
@ -25,7 +26,8 @@ public static class CliOptionsHandlers
FilterWirelessNetworksInMemory(ref wirelessNetworks, sqlQuery); FilterWirelessNetworksInMemory(ref wirelessNetworks, sqlQuery);
} }
var kmlString = GetKmlString(wirelessNetworks); var kmlString = GetKmlString(wirelessNetworks,
$"WiFi Map - {outputFile.Name}");
Helpers.WriteStringToFile(kmlString, outputFile); Helpers.WriteStringToFile(kmlString, outputFile);
} }
else if (inputFile != null && outputFile == null && useDatabase) else if (inputFile != null && outputFile == null && useDatabase)
@ -45,11 +47,15 @@ public static class CliOptionsHandlers
if (sqlQuery != null) if (sqlQuery != null)
{ {
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase(sqlQuery)); kmlString = GetKmlString(
FilterWirelessNetworksFromDatabase(sqlQuery),
$"WiFi Map - {outputFile.Name}");
} }
else else
{ {
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase("SELECT * FROM WirelessNetworks")); kmlString = GetKmlString(
FilterWirelessNetworksFromDatabase("SELECT * FROM WirelessNetworks"),
$"WiFi Map - {outputFile.Name}");
} }
Helpers.WriteStringToFile(kmlString, outputFile); Helpers.WriteStringToFile(kmlString, outputFile);
@ -60,6 +66,12 @@ public static class CliOptionsHandlers
using var dbContext = new DatabaseContext(); using var dbContext = new DatabaseContext();
Console.WriteLine(dbContext.Database.ExecuteSqlRaw(sqlQuery)); Console.WriteLine(dbContext.Database.ExecuteSqlRaw(sqlQuery));
} }
else if (concatFiles != null && outputFile != null)
{
var inputFiles = concatFiles as FileInfo[] ?? concatFiles.ToArray();
var kmlString = ConcatKml(inputFiles);
Helpers.WriteStringToFile(kmlString, outputFile);
}
else else
{ {
Console.WriteLine("Options combination is unsupported or some option lacks an argument." + Console.WriteLine("Options combination is unsupported or some option lacks an argument." +
@ -129,6 +141,7 @@ public static class CliOptionsHandlers
document.Add(wpaFolder); document.Add(wpaFolder);
document.Add(wepFolder); document.Add(wepFolder);
document.Add(opnFolder); document.Add(opnFolder);
document.Add(unknownFolder);
kml.Add(document); kml.Add(document);
kmlTree.Add(kml); kmlTree.Add(kml);
@ -282,4 +295,44 @@ public static class CliOptionsHandlers
using var dbContext = new DatabaseContext(); using var dbContext = new DatabaseContext();
return dbContext.WirelessNetworks.FromSqlRaw(sqlQuery).ToArray(); return dbContext.WirelessNetworks.FromSqlRaw(sqlQuery).ToArray();
} }
private static string ConcatKml(IEnumerable<FileInfo> inputFiles)
{
var inFs = inputFiles.ToArray();
var result = XDocument.Load(inFs[0].FullName);
result.Root!.Element("Document")!.Element("name")!.Value =
"WiFi Map - Concatenated";
var folders = result.Root?.Element("Document")?.Elements("Folder")
.ToArray();
var wpa3Folder = folders?[0];
var wpa2Folder = folders?[1];
var wpaFolder = folders?[2];
var wepFolder = folders?[3];
var opnFolder = folders?[4];
var unknownFolder = folders?[5];
foreach (var inF in inFs[1..])
{
var inFDoc = XDocument.Load(inF.FullName);
var inFolders = inFDoc.Root?.Element("Document")?.Elements("Folder")
.ToArray();
inFolders?[0].Elements("Placemark").ToList()
.ForEach(p => wpa3Folder?.Add(p));
inFolders?[1].Elements("Placemark").ToList()
.ForEach(p => wpa2Folder?.Add(p));
inFolders?[2].Elements("Placemark").ToList()
.ForEach(p => wpaFolder?.Add(p));
inFolders?[3].Elements("Placemark").ToList()
.ForEach(p => wepFolder?.Add(p));
inFolders?[4].Elements("Placemark").ToList()
.ForEach(p => opnFolder?.Add(p));
inFolders?[5].Elements("Placemark").ToList()
.ForEach(p => unknownFolder?.Add(p));
}
return result.ToString();
}
} }

View File

@ -1,4 +1,5 @@
using System.CommandLine; using System.CommandLine;
using System.Xml.Linq;
using netxml2kml.Methods; using netxml2kml.Methods;
namespace netxml2kml; namespace netxml2kml;
@ -7,8 +8,8 @@ class Program
{ {
static int Main(string[] args) static int Main(string[] args)
{ {
// Define CLI parser options, commands & handlers /*-------------------------Input Option----------------------------*/
var inputOption = new Option<FileInfo?>( var inputOption = new Option<FileInfo?>(
aliases: new[] {"-i", "--input"}, aliases: new[] {"-i", "--input"},
description: "Path to the file to be converted.") description: "Path to the file to be converted.")
@ -22,8 +23,7 @@ class Program
if (inputFile == null) if (inputFile == null)
{ {
result.ErrorMessage = result.ErrorMessage = "Argument for input option is not specified.";
"Argument for input option is not specified.";
return; return;
} }
@ -34,6 +34,8 @@ class Program
} }
}); });
/*-------------------------Output Option---------------------------*/
var outputOption = new Option<FileInfo?>( var outputOption = new Option<FileInfo?>(
aliases: new[] {"-o", "--output"}, aliases: new[] {"-o", "--output"},
description: "The name of the file to be created.", description: "The name of the file to be created.",
@ -85,8 +87,7 @@ class Program
if (outputFile == null) if (outputFile == null)
{ {
result.ErrorMessage = result.ErrorMessage = "Argument for output option is not specified.";
"Argument for output option is not specified.";
return; return;
} }
@ -97,30 +98,81 @@ class Program
} }
}); });
/*-------------------------Concat Option---------------------------*/
var concatOption = new Option<IEnumerable<FileInfo>?>(
aliases: new[] {"-c", "--concat"},
description: "Concatenate multiple kml files. ")
{
Arity = ArgumentArity.OneOrMore,
AllowMultipleArgumentsPerToken = true
};
concatOption.AddValidator(result =>
{
var inputFiles = result.GetValueForOption(concatOption);
if (inputFiles == null)
{
result.ErrorMessage = "Argument for concat option is not specified.";
return;
}
var fileInfos = inputFiles as FileInfo[] ?? inputFiles.ToArray();
foreach (var inputFile in fileInfos)
{
if (!inputFile.Exists)
{
result.ErrorMessage = $"File {inputFile.FullName} doesen't exist.";
return;
}
}
// Validate that inputted files have the same format
if (fileInfos.Any(fi => XDocument.Load(fi.FullName).Root?.Name != "kml"))
{
result.ErrorMessage = "Some files passed to concat option have invalid content.";
return;
}
});
/*------------------------Database Option--------------------------*/
var databaseOption = new Option<bool>( var databaseOption = new Option<bool>(
aliases: new[] {"-d", "--use-database"}, aliases: new[] {"-d", "--use-database"},
description: description:
"Use database. Save/retrieve wireless networks and clients to/from sqlite database.") "Use database (save/retrieve data from database).")
{ {
Arity = ArgumentArity.ZeroOrOne Arity = ArgumentArity.ZeroOrOne
}; };
/*------------------------Query Option-----------------------------*/
var queryOption = new Option<string?>( var queryOption = new Option<string?>(
aliases: new[] {"-q", "--query"}, aliases: new[] {"-q", "--query"},
description: "Filter input using sql query.") description: "Filter input/output using sql query.")
{ {
Arity = ArgumentArity.ZeroOrOne Arity = ArgumentArity.ZeroOrOne
}; };
/*----------------------Root Command Setup-------------------------*/
var rootCommand = var rootCommand =
new RootCommand("netxml2kml .netxml to .kml converter."); new RootCommand("netxml2kml .netxml to .kml converter.");
rootCommand.AddOption(inputOption); rootCommand.AddOption(inputOption);
rootCommand.AddOption(outputOption); rootCommand.AddOption(outputOption);
rootCommand.AddOption(databaseOption); rootCommand.AddOption(databaseOption);
rootCommand.AddOption(queryOption); rootCommand.AddOption(queryOption);
rootCommand.AddOption(concatOption);
/*----------------------Handlers Setup-----------------------------*/
rootCommand.SetHandler(CliOptionsHandlers.UniversalHandler, rootCommand.SetHandler(CliOptionsHandlers.UniversalHandler,
inputOption, outputOption, databaseOption, queryOption); inputOption, outputOption, databaseOption, queryOption,
concatOption);
/*----------------------------------------------------------------*/
return rootCommand.Invoke(args); return rootCommand.Invoke(args);
} }

View File

@ -5,6 +5,13 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Title>netxml2kml</Title>
<Authors>cuqmbr</Authors>
<Description>netxml to kml CLI converter &amp; tools</Description>
<Company>cuqmbr</Company>
<NeutralLanguage>en-US</NeutralLanguage>
<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>