feat: results exporting

This commit is contained in:
2026-08-13 09:56:08 +03:00
parent 96ca781fe7
commit 6773503a76
12 changed files with 811 additions and 48 deletions
@@ -7,6 +7,10 @@ namespace GSS2.Core.Analysis.AmineContent;
public static class ResultExporter
{
static ResultExporter()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
public static void ExportCsv(string path, IEnumerable<ResultRecord> records)
{
NumberFormatInfo nfi = new NumberFormatInfo
@@ -75,31 +79,31 @@ public static class ResultExporter
};
rows.Add(row);
row = new List<string>(23);
row = Enumerable.Repeat("", 23).ToList();
row.Add("Нормированная обработанная площадь");
foreach (var v in results.processedAreas)
row.Add(v.ToString("F3", nfi));
rows.Add(row);
row = new List<string>(23);
row = Enumerable.Repeat("", 23).ToList();
row.Add("Горячая площадь");
foreach (var v in results.hotspotAreas)
row.Add(v.ToString("F3", nfi));
rows.Add(row);
row = new List<string>(23);
row = Enumerable.Repeat("", 23).ToList();
row.Add("Оптический интегральный показатель");
foreach (var v in results.opticalIntegrals)
row.Add(v.ToString("F3", nfi));
rows.Add(row);
row = new List<string>(23);
row = Enumerable.Repeat("", 23).ToList();
row.Add("Нормированная обработанная площадь");
foreach (var v in results.innerStdDevs)
row.Add(v.ToString("F3", nfi));
rows.Add(row);
row = new List<string>(23);
row = Enumerable.Repeat("", 23).ToList();
row.Add("Внутригранульная неоднородность");
foreach (var v in results.innerHeterogeneities)
row.Add(v.ToString("F3", nfi));
@@ -117,6 +121,6 @@ public static class ResultExporter
sb.Append("\n");
}
File.WriteAllText(path, sb.ToString());
File.WriteAllText(path, sb.ToString(), Encoding.GetEncoding(1251));
}
}
-1
View File
@@ -92,7 +92,6 @@ public static class DependencyInjectionHelper
return new CameraService(logger, serviceConfiguration, autoInitialize);
}
);
[Obsolete]
public static IServiceCollection AddUsbService(this IServiceCollection services) => services
.AddSingleton<UsbService>();
+1
View File
@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.0" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.3" />
+174 -39
View File
@@ -1,51 +1,192 @@
using System.Device.I2c;
using System.Text.RegularExpressions;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using GSS2.Core.Abstractions;
using System.Diagnostics;
namespace GSS2.Core.Hardware;
[Obsolete("Not implemented")]
public class UsbService : IDisposable
{
private bool _disposedValue;
private readonly ILogger<UsbService> _logger;
private readonly Process _monitor;
public UsbService(ILogger<UsbService> logger)
{
_logger = logger;
_logger.LogInformation("Инициализация");
_monitor = new Process();
_monitor.StartInfo = new ProcessStartInfo()
{
FileName = "udisksctl",
Arguments = "monitor",
RedirectStandardOutput = true,
RedirectStandardError = true
};
_monitor.OutputDataReceived += MonitorDataReceived;
_monitor.ErrorDataReceived += MonitorDataReceived;
_monitor.Exited += (s, ea) => _logger.LogWarning("Монитор udisksctl отключен");
if (_monitor.Start())
_logger.LogInformation("Монитор udisksctl запущен");
else
_logger.LogError("Не удалось запустить монитор udisksctl");
_monitor.BeginOutputReadLine();
_monitor.BeginErrorReadLine();
_logger.LogInformation("Инициализировано");
}
private void MonitorDataReceived(object sender, DataReceivedEventArgs ea)
public List<(string id, string name, bool mounted, string? mountPath)> GetDevices()
{
if (ea.Data is null)
return;
_logger.LogInformation("Data rec {}", ea.Data);
var devices = new List<(string name, string id, bool mounted, string? mountPath)>();
try
{
_logger.LogInformation("Получаем список дисков");
var (exitCode, output, error) = RunCommand("lsblk", "-P -o NAME,PATH,RM,TYPE,MOUNTPOINT,LABEL,MODEL");
if (exitCode != 0)
{
_logger.LogWarning("Не удалось получить список дисков: {} {}", exitCode, error.Trim());
return devices;
}
var lines = output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var model = string.Empty;
foreach (var line in lines)
{
var dict = new Dictionary<string, string>();
var matches = Regex.Matches(line, @"(\w+)=""([^""]*)""");
foreach (Match m in matches)
dict[m.Groups[1].Value] = m.Groups[2].Value;
if (dict.TryGetValue("RM", out var rm) &&
dict.TryGetValue("TYPE", out var type) &&
rm == "1" &&
type == "disk")
{
model = dict.GetValueOrDefault("MODEL", "").Trim();
}
if (dict.TryGetValue("RM", out rm) &&
dict.TryGetValue("TYPE", out type) &&
rm == "1" &&
type == "part")
{
var id = dict.GetValueOrDefault("PATH", "");
var mountpoint = dict.GetValueOrDefault("MOUNTPOINT", "");
var label = dict.GetValueOrDefault("LABEL", "").Trim();
var rawName = dict.GetValueOrDefault("NAME", "").Trim();
string displayName = string.Empty;
if (!string.IsNullOrWhiteSpace(label))
displayName = label;
if (!string.IsNullOrWhiteSpace(model))
displayName = displayName + (!string.IsNullOrWhiteSpace(displayName) ? " " : "") + model;
else
displayName = displayName + (!string.IsNullOrWhiteSpace(displayName) ? " " : "") + rawName;
if (!string.IsNullOrWhiteSpace(id))
devices.Add((id, displayName, !string.IsNullOrWhiteSpace(mountpoint), string.IsNullOrWhiteSpace(mountpoint) ? null : mountpoint));
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Исключение при попытке получить список дисков");
}
_logger.LogInformation("Список дисков: \n\t{}", string.Join("\n\t", devices.Select(d => $"{d.name} {d.mounted} {d.id}")));
return devices;
}
public string? MountDevice(string id)
{
try
{
_logger.LogInformation("Монтируем диск: {}", id);
var (exitCode, output, error) = RunCommand("udisksctl", $"mount -b {id} --no-user-interaction");
if (exitCode != 0)
{
_logger.LogWarning("Не удалось смонтировать диск {}: {} {}", id, exitCode, error.Trim());
return null;
}
_logger.LogInformation("Диск смонтирован {}: {}", id, output.Trim());
var result = output.Trim().Split("\n").Last();
if (result.StartsWith($"Mounted {id} at "))
{
var path = result.Substring($"Mounted {id} at ".Count());
return path;
}
return null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Исключение при попытке смонтировать диск {}", id);
return null;
}
}
public string? GetMountPath(string id)
{
try
{
_logger.LogInformation("Получаем информацию о диске: {}", id);
var (exitCode, output, error) = RunCommand("udisksctl", $"info -b {id}");
if (exitCode != 0)
{
_logger.LogWarning("Не удалось получить информацию о дисе {}: {} {}", id, exitCode, error.Trim());
return null;
}
_logger.LogInformation("Информация о диске {}: {}", id, output.Trim());
var result = output.Split("\n").FirstOrDefault(l => l.Trim().StartsWith("MountPoints:"));
if (result is null)
return null;
result = result.Trim().Substring("MountPoints:".Count()).Trim();
if (string.IsNullOrEmpty(result))
return null;
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Исключение при получении информации о диске {}", id);
return null;
}
}
public bool UnmountDevice(string id)
{
try
{
_logger.LogInformation("Размонтируем диск {}", id);
var (exitCode, output, error) = RunCommand("udisksctl", $"unmount -b {id} --no-user-interaction");
if (exitCode != 0)
{
_logger.LogError("Не удалось размонтировать диск {}: {} {}", id, exitCode, error.Trim());
return false;
}
_logger.LogInformation("Диск размонтирован {}", id);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Исключение при попытке размонтировать диск {}", id);
return false;
}
}
public void UnmountAllDevices()
{
_logger.LogInformation("Размонтируем все диски");
var mountedDevices = GetDevices().Where(d => d.mounted).ToList();
foreach (var device in mountedDevices){
Console.WriteLine(device.id);
UnmountDevice(device.id);}
}
private (int exitCode, string output, string error) RunCommand(string fileName, string arguments)
{
using var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
return (process.ExitCode, output, error);
}
protected virtual void Dispose(bool disposing)
@@ -53,13 +194,7 @@ public class UsbService : IDisposable
if (!_disposedValue)
{
if (disposing)
{
try
{
_monitor.Close();
}
catch { }
}
UnmountAllDevices();
_disposedValue = true;
}