diff --git a/Nyanbyte.PPCheck.sln b/Nyanbyte.PPCheck.sln
index 46adace..f034907 100644
--- a/Nyanbyte.PPCheck.sln
+++ b/Nyanbyte.PPCheck.sln
@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B1DE5D4C-2
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nyanbyte.PPCheck.Tests", "test\Nyanbyte.PPCheck.Tests\Nyanbyte.PPCheck.Tests.csproj", "{0C4EC394-8D41-42DF-BCE3-5FB43661D8E2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nyanbyte.PPCheck.Worker", "src\Nyanbyte.PPCheck.Worker\Nyanbyte.PPCheck.Worker.csproj", "{D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -28,9 +30,14 @@ Global
{0C4EC394-8D41-42DF-BCE3-5FB43661D8E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C4EC394-8D41-42DF-BCE3-5FB43661D8E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C4EC394-8D41-42DF-BCE3-5FB43661D8E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{02AFAE01-FBD5-49EE-8D3F-329CDA5FEA79} = {C3B18ED6-C901-49BD-A417-B28A660CE50A}
{0C4EC394-8D41-42DF-BCE3-5FB43661D8E2} = {B1DE5D4C-2699-46CA-AB98-27172F955862}
+ {D53CFC0B-D1B9-408D-B8D8-5F8FD3B06DC8} = {C3B18ED6-C901-49BD-A417-B28A660CE50A}
EndGlobalSection
EndGlobal
diff --git a/src/Nyanbyte.PPCheck.Worker/Nyanbyte.PPCheck.Worker.csproj b/src/Nyanbyte.PPCheck.Worker/Nyanbyte.PPCheck.Worker.csproj
new file mode 100644
index 0000000..40112a8
--- /dev/null
+++ b/src/Nyanbyte.PPCheck.Worker/Nyanbyte.PPCheck.Worker.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Nyanbyte.PPCheck.Worker/Program.cs b/src/Nyanbyte.PPCheck.Worker/Program.cs
new file mode 100644
index 0000000..3be8f6f
--- /dev/null
+++ b/src/Nyanbyte.PPCheck.Worker/Program.cs
@@ -0,0 +1,172 @@
+using ClosedXML.Excel;
+using DocumentFormat.OpenXml.Spreadsheet;
+using Nyanbyte.PPCheck.Lib;
+using Nyanbyte.PPCheck.Lib.Models;
+
+internal class Program
+{
+ private static async Task Main(string[] args)
+ {
+ Console.WriteLine("Starting...");
+ string file = args[0];
+
+ var wb = new XLWorkbook(file);
+ var ws = wb.Worksheets.First();
+
+ Dictionary dic = new();
+ Dictionary results = new();
+
+ {
+ var cell = ws.Cell("B2");
+ while (!cell.IsEmpty())
+ {
+ string name = cell.Value.GetText().Trim();
+ if (!cell.CellRight().CellRight().IsEmpty())
+ {
+ Console.WriteLine($"Skipping {name}...");
+ cell = cell.CellBelow();
+ continue;
+ }
+
+ dic[name] = cell;
+
+ cell = cell.CellBelow();
+ }
+ }
+
+ Console.WriteLine($"Consolidated {dic.Count} records!\n");
+
+ var api = new ApiClient();
+
+ foreach (var record in dic)
+ {
+ string name = record.Key;
+ Console.Write($"Processing: {name}... ");
+
+ string[] names = name.Split(' ');
+ if (names.Length != 2)
+ {
+ Console.WriteLine($"INVALID!\nCannot process '{name}' due to an irregular name!");
+ continue;
+ }
+
+ SearchRequest req = new()
+ {
+ FirstName = names[1],
+ LastName = names[0]
+ };
+
+ try
+ {
+ var result = await api.Search(req);
+
+ if (result.HasError)
+ {
+ Console.WriteLine($"ERR!\nCannot process '{name}' due to an unknown error!");
+ continue;
+ }
+
+ results[name] = (result, DateTimeOffset.Now);
+
+ if (result.Data.Any())
+ {
+ Console.WriteLine($"ATTENTION!\n\x1b[1;91mRecord exists for '\x1b[1;93m{name}\x1b[1;91m'!!!\x1b[0m");
+ }
+ else
+ {
+ Console.WriteLine("OK");
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ Console.WriteLine("Aborting searches due to an exception...");
+ break;
+ }
+
+ int rand = Random.Shared.Next(200);
+ await Task.Delay(rand + 1000);
+ }
+
+ Console.WriteLine("\nSaving results...");
+
+ if (File.Exists("pedooutput.csv"))
+ File.Delete("pedooutput.csv");
+
+ if (File.Exists("pedoerrors.csv"))
+ File.Delete("pedoerrors.csv");
+
+ using var fs = new StreamWriter(File.OpenWrite("pedooutput.csv"));
+ using var errfs = new StreamWriter(File.OpenWrite("pedoerrors.csv"));
+ await fs.WriteLineAsync("Name,Date,LikelyRecords");
+ await errfs.WriteLineAsync("Name");
+
+ foreach (var rec in dic)
+ {
+ var cell = rec.Value.CellRight().CellRight();
+ string name = rec.Key;
+
+ if (!results.ContainsKey(name))
+ {
+ cell.CreateRichText().AddText("błąd sprawdzania").SetFontColor(XLColor.DarkRed);
+ await errfs.WriteLineAsync($"{name}");
+ continue;
+ }
+
+ var (result, date) = results[name];
+
+ string strRec = result.Total == 0 ? "brak rekordów" : (result.Total == 1 ? "1 rekord" : $"{result.Total} rekordy");
+ cell.CreateRichText().AddText($"{date:dd.MM.yyyy, HH:mm:ss} - {strRec}").SetFontColor(result.Total == 0 ? XLColor.DarkGreen : XLColor.Red);
+
+ await fs.WriteLineAsync($"{name},{date.ToUnixTimeMilliseconds()},{result.Total}");
+ }
+
+ wb.Save();
+
+ if (!Directory.Exists("pedofiles"))
+ Directory.CreateDirectory("pedofiles");
+
+ foreach (var records in results.Where(f => f.Value.Item1.Total > 0))
+ {
+ string sub = $"pedofiles/{records.Key}";
+ Directory.CreateDirectory(sub);
+
+ foreach (var data in records.Value.Item1.Data)
+ {
+ try
+ {
+ var img = await api.GetImage(data.PersonIdentityId);
+ if (img != null)
+ {
+ await File.WriteAllBytesAsync($"{sub}/{data.PersonIdentityId}.png", img);
+ }
+ }
+ catch (Exception)
+ {
+ }
+
+ using var write = new StreamWriter(File.OpenWrite($"{sub}/{data.PersonIdentityId}.txt"));
+
+ await write.WriteLineAsync($"Identyfikator: {data.PersonIdentityId}");
+ await write.WriteLineAsync($"Ilość adnotacji: {data.AnnotationCount}\n");
+ await write.WriteLineAsync("Znane tożsamości:\n");
+ foreach (var persona in data.Personas)
+ {
+ await write.WriteLineAsync($"Id: {persona.Id}");
+ await write.WriteLineAsync($"Imię: {persona.FirstName} {(persona.SecondName != null ? $"{persona.SecondName} " : "")}{persona.LastName}");
+ await write.WriteLineAsync($"Date urodzenia: {persona.DateOfBirth.ToShortDateString()}");
+ await write.WriteLineAsync($"Miejsce urodzenia: {persona.CityOfBirth}");
+ await write.WriteLineAsync($"Płeć: {persona.OffenderSex}");
+ await write.WriteLineAsync($"Nazwisko rodowe: {persona.FamilyName}");
+ await write.WriteLineAsync($"Państwo urodzenia: {persona.CountryOfBirth}");
+ await write.WriteLineAsync($"Obywatelstwo: {persona.Nationalities}");
+ await write.WriteLineAsync($"Miejscowość przebywania: {persona.DwellingPlace}\n");
+ }
+ }
+
+ await Task.Delay(100);
+ }
+
+ Console.WriteLine("Done!");
+ }
+}