-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathScriptDocumentImportService.cs
More file actions
72 lines (60 loc) · 2.86 KB
/
ScriptDocumentImportService.cs
File metadata and controls
72 lines (60 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System.Text;
using MarkItDown;
using PrompterOne.Core.Models.Editor;
namespace PrompterOne.Core.Services.Editor;
public sealed class ScriptDocumentImportService(ScriptImportDescriptorService descriptorService)
{
private const string UnsupportedFileNameMessage = "Only supported script and document files can be imported.";
private readonly ScriptImportDescriptorService _descriptorService = descriptorService;
public bool CanImport(string? fileName) =>
ScriptDocumentFileTypes.CanImportFromPicker(fileName);
public async Task<ScriptImportDescriptor> ImportAsync(
Stream stream,
string? fileName,
string? mimeType,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(stream);
var normalizedFileName = ScriptDocumentFileTypes.NormalizeFileName(fileName);
if (!CanImport(normalizedFileName))
{
throw new ArgumentException(UnsupportedFileNameMessage, nameof(fileName));
}
var isTextImport = ScriptDocumentFileTypes.CanReadAsText(normalizedFileName);
var text = isTextImport
? await ReadTextAsync(stream, cancellationToken)
: await ConvertToMarkdownAsync(stream, normalizedFileName, mimeType, cancellationToken);
var importedDocumentName = ScriptDocumentFileTypes.BuildImportedDocumentName(normalizedFileName);
var descriptor = _descriptorService.Build(importedDocumentName, text);
return isTextImport
? descriptor
: descriptor with
{
Title = ScriptDocumentFileTypes.ResolvePickerTitle(normalizedFileName)
};
}
private static async Task<string> ConvertToMarkdownAsync(
Stream stream,
string fileName,
string? mimeType,
CancellationToken cancellationToken)
{
var extension = ScriptDocumentFileTypes.ResolvePickerSupportedSuffix(fileName) ?? Path.GetExtension(fileName);
var streamInfo = new StreamInfo(
mimeType: string.IsNullOrWhiteSpace(mimeType) ? null : mimeType,
extension: extension,
fileName: fileName);
var client = new MarkItDownClient();
await using var result = await client.ConvertAsync(stream, streamInfo, cancellationToken: cancellationToken);
return NormalizeMarkdown(result.Markdown);
}
private static string NormalizeMarkdown(string? markdown) =>
string.IsNullOrWhiteSpace(markdown)
? string.Empty
: markdown.Replace("\r\n", "\n", StringComparison.Ordinal).Trim();
private static async Task<string> ReadTextAsync(Stream stream, CancellationToken cancellationToken)
{
using var reader = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, leaveOpen: true);
return await reader.ReadToEndAsync(cancellationToken);
}
}