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 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
if (inputFile != null && outputFile != null)
@ -25,7 +26,8 @@ public static class CliOptionsHandlers
FilterWirelessNetworksInMemory(ref wirelessNetworks, sqlQuery);
}
var kmlString = GetKmlString(wirelessNetworks);
var kmlString = GetKmlString(wirelessNetworks,
$"WiFi Map - {outputFile.Name}");
Helpers.WriteStringToFile(kmlString, outputFile);
}
else if (inputFile != null && outputFile == null && useDatabase)
@ -45,11 +47,15 @@ public static class CliOptionsHandlers
if (sqlQuery != null)
{
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase(sqlQuery));
kmlString = GetKmlString(
FilterWirelessNetworksFromDatabase(sqlQuery),
$"WiFi Map - {outputFile.Name}");
}
else
{
kmlString = GetKmlString(FilterWirelessNetworksFromDatabase("SELECT * FROM WirelessNetworks"));
kmlString = GetKmlString(
FilterWirelessNetworksFromDatabase("SELECT * FROM WirelessNetworks"),
$"WiFi Map - {outputFile.Name}");
}
Helpers.WriteStringToFile(kmlString, outputFile);
@ -60,6 +66,12 @@ public static class CliOptionsHandlers
using var dbContext = new DatabaseContext();
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
{
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(wepFolder);
document.Add(opnFolder);
document.Add(unknownFolder);
kml.Add(document);
kmlTree.Add(kml);
@ -282,4 +295,44 @@ public static class CliOptionsHandlers
using var dbContext = new DatabaseContext();
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.Xml.Linq;
using netxml2kml.Methods;
namespace netxml2kml;
@ -7,7 +8,7 @@ class Program
{
static int Main(string[] args)
{
// Define CLI parser options, commands & handlers
/*-------------------------Input Option----------------------------*/
var inputOption = new Option<FileInfo?>(
aliases: new[] {"-i", "--input"},
@ -22,8 +23,7 @@ class Program
if (inputFile == null)
{
result.ErrorMessage =
"Argument for input option is not specified.";
result.ErrorMessage = "Argument for input option is not specified.";
return;
}
@ -34,6 +34,8 @@ class Program
}
});
/*-------------------------Output Option---------------------------*/
var outputOption = new Option<FileInfo?>(
aliases: new[] {"-o", "--output"},
description: "The name of the file to be created.",
@ -85,8 +87,7 @@ class Program
if (outputFile == null)
{
result.ErrorMessage =
"Argument for output option is not specified.";
result.ErrorMessage = "Argument for output option is not specified.";
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>(
aliases: new[] {"-d", "--use-database"},
description:
"Use database. Save/retrieve wireless networks and clients to/from sqlite database.")
"Use database (save/retrieve data from database).")
{
Arity = ArgumentArity.ZeroOrOne
};
/*------------------------Query Option-----------------------------*/
var queryOption = new Option<string?>(
aliases: new[] {"-q", "--query"},
description: "Filter input using sql query.")
description: "Filter input/output using sql query.")
{
Arity = ArgumentArity.ZeroOrOne
};
/*----------------------Root Command Setup-------------------------*/
var rootCommand =
new RootCommand("netxml2kml .netxml to .kml converter.");
rootCommand.AddOption(inputOption);
rootCommand.AddOption(outputOption);
rootCommand.AddOption(databaseOption);
rootCommand.AddOption(queryOption);
rootCommand.AddOption(concatOption);
/*----------------------Handlers Setup-----------------------------*/
rootCommand.SetHandler(CliOptionsHandlers.UniversalHandler,
inputOption, outputOption, databaseOption, queryOption);
inputOption, outputOption, databaseOption, queryOption,
concatOption);
/*----------------------------------------------------------------*/
return rootCommand.Invoke(args);
}

View File

@ -5,6 +5,13 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<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>
<ItemGroup>