From 233bc8251bd60a70ec8429e0400aefff037f2f0d Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Thu, 3 Sep 2026 17:21:08 +0900 Subject: [PATCH] fix(domain): integrate MediaConversionNegotiator into ProviderRegistry.OutputsForInput and categorize xlsx as Data --- .../Converters/OcrProvider.cs | 41 ++----------------- .../Filters/QueueFilterMatcher.cs | 4 +- .../Providers/ProviderRegistry.cs | 3 ++ 3 files changed, 8 insertions(+), 40 deletions(-) diff --git a/src/Everything2Everything.Core/Converters/OcrProvider.cs b/src/Everything2Everything.Core/Converters/OcrProvider.cs index a9683cf..1b278d4 100644 --- a/src/Everything2Everything.Core/Converters/OcrProvider.cs +++ b/src/Everything2Everything.Core/Converters/OcrProvider.cs @@ -1,6 +1,3 @@ -using DocumentFormat.OpenXml; -using DocumentFormat.OpenXml.Packaging; -using DocumentFormat.OpenXml.Wordprocessing; using Everything2Everything.Core.Providers; using Windows.Globalization; using Windows.Graphics.Imaging; @@ -14,7 +11,7 @@ public sealed class OcrProvider : IConverterProvider private static readonly string[] OcrInputs = { ".png", ".jpg", ".jpeg", ".bmp", ".tif", ".tiff", ".webp", ".gif", ".heic", ".heif", ".pdf" }; - private static readonly string[] OcrOutputs = { ".txt", ".docx" }; + private static readonly string[] OcrOutputs = { ".txt" }; private readonly PdfProvider _pdfProvider; @@ -27,10 +24,10 @@ public sealed class OcrProvider : IConverterProvider public ProviderCapability Capability { get; } = new( Id: "ocr", - DisplayName: "OCR (이미지/PDF → 텍스트·DOCX)", + DisplayName: "OCR (이미지/PDF → 텍스트)", SupportedConversions: ProviderCapability.PairsFromMatrix(OcrInputs, OcrOutputs, LossClass.Rasterize), Status: ProviderStatus.Available, - Summary: "Windows OCR 엔진으로 이미지 또는 PDF 페이지에서 텍스트를 추출해 .txt 또는 .docx로 저장합니다.", + Summary: "Windows OCR 엔진으로 이미지 또는 PDF 페이지에서 텍스트를 추출해 .txt로 저장합니다.", ExternalDependencies: Array.Empty(), RoadmapNote: "Windows에 설치된 OCR 언어 팩을 사용 — 한국어/영어는 Windows 11 기본 포함."); @@ -96,10 +93,6 @@ public sealed class OcrProvider : IConverterProvider : string.Join(Environment.NewLine + Environment.NewLine + "---" + Environment.NewLine + Environment.NewLine, pageTexts); await File.WriteAllTextAsync(path, combined, System.Text.Encoding.UTF8, cancellationToken).ConfigureAwait(false); } - else if (outExt == ".docx") - { - WriteDocx(path, pageTexts); - } else { return ConvertResult.Fail(sourcePath, $"지원하지 않는 출력 형식: {outExt}"); @@ -189,32 +182,4 @@ public sealed class OcrProvider : IConverterProvider return result.OutputPaths.ToList(); } - - private static void WriteDocx(string path, IReadOnlyList pageTexts) - { - using var doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document); - var mainPart = doc.AddMainDocumentPart(); - mainPart.Document = new Document(); - var body = mainPart.Document.AppendChild(new Body()); - - for (var pageIndex = 0; pageIndex < pageTexts.Count; pageIndex++) - { - var pageText = pageTexts[pageIndex] ?? string.Empty; - foreach (var line in pageText.Split('\n', StringSplitOptions.None)) - { - var paragraph = body.AppendChild(new Paragraph()); - var run = paragraph.AppendChild(new Run()); - run.AppendChild(new Text(line.TrimEnd('\r')) { Space = SpaceProcessingModeValues.Preserve }); - } - - if (pageIndex < pageTexts.Count - 1) - { - var pageBreakPara = body.AppendChild(new Paragraph()); - var pageBreakRun = pageBreakPara.AppendChild(new Run()); - pageBreakRun.AppendChild(new Break { Type = BreakValues.Page }); - } - } - - mainPart.Document.Save(); - } } diff --git a/src/Everything2Everything.Core/Filters/QueueFilterMatcher.cs b/src/Everything2Everything.Core/Filters/QueueFilterMatcher.cs index 344aead..ed44a71 100644 --- a/src/Everything2Everything.Core/Filters/QueueFilterMatcher.cs +++ b/src/Everything2Everything.Core/Filters/QueueFilterMatcher.cs @@ -29,13 +29,13 @@ public static class QueueFilterMatcher or ".svg" or ".heic" or ".heif" or ".raw" or ".dng" or ".cr2" or ".cr3" or ".nef" or ".arw" => FilterCategory.Image, - ".pdf" or ".docx" or ".doc" or ".hwp" or ".hwpx" or ".txt" or ".md" or ".markdown" or ".html" or ".htm" or ".xlsx" or ".xls" + ".pdf" or ".docx" or ".doc" or ".hwp" or ".hwpx" or ".txt" or ".md" or ".markdown" or ".html" or ".htm" => FilterCategory.Document, ".mp4" or ".mkv" or ".webm" or ".mov" or ".avi" or ".mp3" or ".wav" or ".flac" or ".aac" or ".m4a" or ".ogg" or ".opus" => FilterCategory.Media, - ".csv" or ".json" or ".tsv" or ".xml" or ".yaml" or ".yml" + ".csv" or ".json" or ".tsv" or ".xml" or ".yaml" or ".yml" or ".xlsx" or ".xls" => FilterCategory.Data, _ => FilterCategory.All, diff --git a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs index a1c8507..7d207c4 100644 --- a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs +++ b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs @@ -1,3 +1,5 @@ +using Everything2Everything.Core.Filters; + namespace Everything2Everything.Core.Providers; public sealed class ProviderRegistry @@ -63,6 +65,7 @@ public sealed class ProviderRegistry var input = ConversionPair.Normalize(inputExtension); return _graph.ReachableOutputs(input, maxHops: 2, allowLossy: true) .Where(o => !string.Equals(o, input, StringComparison.OrdinalIgnoreCase)) + .Where(o => MediaConversionNegotiator.CanConvert(input, o)) .OrderBy(e => e, StringComparer.OrdinalIgnoreCase) .ToList(); }