livia-test/Livia/Models/Data/LocalCommandLineServerHandler.cs
2025-03-28 14:31:53 +08:00

258 lines
8.8 KiB
C#

using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using Livia.Utility;
using Microsoft.Extensions.Logging;
namespace Livia.Models.Data;
public class LocalCommandLineServerHandler(ILogger logger) : IServerHandler
{
public event PropertyChangedEventHandler? PropertyChanged;
public event PropertyChangingEventHandler? PropertyChanging;
public bool Processing { get; set; }
public bool IsLoggedIn => true;
public string Quota => "0";
private const int FilePrintCount = 10;
public async Task<(bool success, string messageIndex)> ProcessData(DataBlock dataBlock, CancellationToken token)
{
string outputPath = Path.Combine(ServiceConfigurations.TempFolder, dataBlock.Key);
string prevWorkingDirectory = Environment.CurrentDirectory;
if (dataBlock.ArgsDict == null)
{
return (false, "ServerErrorUnknown");
}
try
{
string inputDir = dataBlock.ArgsDict["input_dir"];
logger.LogInformation("Input dir: {path}", inputDir);
DirectoryInfo dirInfo = new(inputDir);
if (!dirInfo.Exists)
{
return (false, "InvalidInputDirectoryError");
}
logger.LogInformation("Printing first {num} files", FilePrintCount);
LogDirInfo(dirInfo, FilePrintCount);
string exePath = Path.Join(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "cereflow_command_line");
logger.LogInformation("Attempting to find exe in {path}", exePath);
Environment.CurrentDirectory = exePath;
string args = $"--input_dir \"{inputDir}\" --tmp_dir \"{outputPath}\" --output_dicom_dir \"{dataBlock.ArgsDict["output_dir"]}\" --language \"{LiviaUtility.GetLanguageOnlyString()}\"";
logger.LogInformation("Args is :{args}", args);
Process process = new();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
process.StartInfo.StandardInputEncoding = Encoding.UTF8;
process.OutputDataReceived += OutputDataReceived;
process.ErrorDataReceived += ErrorDataReceived;
process.Start();
await using StreamWriter streamWriter = process.StandardInput;
//set everything to utf-8
// ReSharper disable once StringLiteralTypo
await streamWriter.WriteLineAsync(@"C:\Windows\System32\chcp.com 65001");
// ReSharper disable once StringLiteralTypo
await streamWriter.WriteLineAsync("set PYTHONIOENCODING=utf-8");
// ReSharper disable once StringLiteralTypo
await streamWriter.WriteLineAsync("set PYTHONUTF8=1");
await streamWriter.WriteLineAsync($"command_line.exe {args}");
await streamWriter.WriteLineAsync("exit");
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await process.WaitForExitAsync(token);
logger.LogInformation("Process exited with code {code}", process.ExitCode);
if (process.ExitCode != 0)
{
return (false, $"ServerError{process.ExitCode}");
}
process.Close();
dataBlock.ResultPath = Path.Join(outputPath, "result");
File.Create(Path.Join(outputPath, "complete"));
}
catch (Exception e)
{
logger.LogError(e, "Error in ProcessData:");
return (false, "ServerErrorUnknown");
}
finally
{
Environment.CurrentDirectory = prevWorkingDirectory;
}
return (true, "");
}
private void LogDirInfo(DirectoryInfo dirInfo, int count)
{
foreach (FileInfo fileInfo in dirInfo.GetFiles())
{
logger.LogInformation(fileInfo.FullName);
count--;
if (count <= 0)
return;
}
foreach (DirectoryInfo directoryInfo in dirInfo.GetDirectories())
{
LogDirInfo(directoryInfo, count);
if (count <= 0)
return;
}
}
private void OutputDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
{
logger.LogInformation(outLine.Data);
}
private void ErrorDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
{
logger.LogError(outLine.Data);
}
public Task<(bool success, string messageIndex)> DownloadData(DataBlock dataBlock)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> DownloadReport(string key, int id, string savePath, CancellationToken token)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> EditPassword(string oldPassword, string newPassword)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(List<ServerJobData> list, int count)> CheckServerJobList(int limit, int offset)
{
return Task.FromResult((new List<ServerJobData>(), 0));
}
public Task<(List<ServerJobData> list, int count)> SearchData(SearchQueryJson json)
{
return Task.FromResult((new List<ServerJobData>(), 0));
}
public Task<List<ReportItem>> GetReportList(string key)
{
return Task.FromResult(new List<ReportItem>());
}
public Task<string> Login(string username, string password)
{
return Task.FromResult("ServerErrorUnknown");
}
public Task Cancel(string key)
{
return Task.CompletedTask;
}
public Task DeleteReport(string key, int id)
{
return Task.CompletedTask;
}
public Task<(bool success, string messageIndex)> DownloadArchive(string? key, string savePath, CancellationToken token)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> DownloadSorted(string? key, string savePath, CancellationToken none)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> DeleteData(int? dataKey, CancellationToken cancellationToken)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> DeleteHistory(string? key, CancellationToken cancellationToken)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task UpdateDongleInfo()
{
return Task.CompletedTask;
}
public Task<ServerNotice?> GetNotice()
{
return Task.FromResult<ServerNotice?>(null);
}
public Task<List<SeriesGroup>> GetSeriesGroupList(string key)
{
return Task.FromResult(new List<SeriesGroup>());
}
public Task<(bool success, string messageIndex)> SelectSeries(string key, List<string> series)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> SelectReportModule(string fileName, SelectReportModuleJson json, CancellationToken token)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<(bool success, string messageIndex)> PushToPacs(string key, int id)
{
return Task.FromResult((false, "ServerErrorUnknown"));
}
public Task<DicomNodeInfo?> GetDicomNodeInfo()
{
return Task.FromResult<DicomNodeInfo?>(null);
}
public static (string msgIndex, string arg, Dictionary<string, string>? argsDictionary) ParseArgs(IEnumerable<string> requiredArgList)
{
Dictionary<string, string>? argsDictionary;
try
{
argsDictionary = LiviaUtility.ParseArgs(Environment.GetCommandLineArgs());
foreach (string arg in requiredArgList)
{
if (argsDictionary.ContainsKey(arg))
continue;
//set argsDictionary to null is important here because otherwise commandline will run.
return ("ArgumentNotFoundError", arg, null);
}
}
catch (ArgumentException e)
{
return ("InvalidArgumentError", e.Message, null);
}
catch (Exception e)
{
return ("ParsingArgumentError", e.Message, null);
}
return ("", "", argsDictionary);
}
}