using Microsoft.Extensions.Logging; using System.Reflection; using Inspectron.Epson.PrintServer.Printers; namespace Inspectron.Epson.PrintServer.PrintServices; public class EpsonPrintService: IPrintService { private readonly ILogger _logger; private readonly IPrinterFactory _printerFactory; private readonly IWrapperPrinterFactory _wrapperPrinterFactory; private readonly IPrinterConfigurationSource _printerConfigurationSource; public EpsonPrintService(ILogger logger, IPrinterFactory printerFactory, IWrapperPrinterFactory wrapperPrinterFactory, IPrinterConfigurationSource printerConfigurationSource) { _logger = logger; _printerFactory = printerFactory; _wrapperPrinterFactory = wrapperPrinterFactory; _printerConfigurationSource = printerConfigurationSource; } public async Task PrintAsync(string printerIp, PrintJob job) { try { var configuration = _printerConfigurationSource.GetConfiguration(printerIp); await using var epsonPrinter = _printerFactory.CreatePrinter(); string address; int port = 9100; var printerAddress = configuration.Address; if (printerAddress.Contains(":")) { var parts = printerAddress.Split(':'); address = parts[0]; port = int.Parse(parts[1]); } else { address = printerAddress; } await epsonPrinter.ConnectAsync(address, port); var printerId = await epsonPrinter.GetPrinterIdAsync(); var status = await epsonPrinter.GetPrinterStatusAsync(); if (!status.IsOnline) { throw new InvalidOperationException("Printer is offline or out of paper."); } var printerAdapter = _wrapperPrinterFactory.CreatePrinterFromId(printerId.Value, epsonPrinter); await printerAdapter.InitAsync(); if (!string.IsNullOrEmpty(job.Document.LogoUrl)) { // Download logo image var logoFileName = Path.GetFileName(new Uri(job.Document.LogoUrl).LocalPath); var logoCachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logos"); // Ensure logos cache directory exists if (!Directory.Exists(logoCachePath)) { Directory.CreateDirectory(logoCachePath); } var cachedLogoPath = Path.Combine(logoCachePath, logoFileName); // Download only if not already cached if (!File.Exists(cachedLogoPath)) { using var httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromSeconds(10); var logoData = await httpClient.GetByteArrayAsync(job.Document.LogoUrl); await File.WriteAllBytesAsync(cachedLogoPath, logoData); _logger.LogInformation("Downloaded logo {LogoFileName} from {LogoUrl}", logoFileName, job.Document.LogoUrl); } else { _logger.LogDebug("Using cached logo {LogoFileName}", logoFileName); } await printerAdapter.PrintImageAsync(cachedLogoPath); } await printerAdapter.SetFontSizeAsync(configuration.FontSize); await printerAdapter.PrintTextAsync(job.Document.Content); await Task.Delay(200); status = await epsonPrinter.GetPrinterStatusAsync(); if (!status.IsOnline) { throw new InvalidOperationException("Printer is offline or out of paper."); } await printerAdapter.Cut(); } catch (Exception e) { _logger.LogWarning( e, "Failed to print job for printer {PrinterUid}", printerIp); return false; } return true; } }