1
0
Fork 0

fix(domain): integrate MediaConversionNegotiator into ProviderRegistry.OutputsForInput and categorize xlsx as Data

This commit is contained in:
Yun Chan 2026-09-03 17:21:08 +09:00
parent f1000cc838
commit 233bc8251b
3 changed files with 8 additions and 40 deletions

View file

@ -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<ExternalDependency>(),
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<string> 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();
}
}

View file

@ -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,

View file

@ -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();
}