Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ public async Task<CreateDataFileResponse> HandleAsync(CreateDataFile request, Ca
};
try
{
await using Stream fileStream = fileSystem.OpenWrite(path);
await request.FileStream.CopyToAsync(fileStream, cancellationToken);
using (Stream fileStream = fileSystem.OpenWrite(path))
{
await request.FileStream.CopyToAsync(fileStream, cancellationToken);
}
if (dataFile.Format == FileFormat.Paratext)
{
ParatextMetadata metadata = await ParatextProjectDataParser.ParseParatextMetadataAsync(path);
dataFile = dataFile with { FileMetadata = metadata };
}
await dataFiles.InsertAsync(dataFile, cancellationToken);
}
catch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ await dataAccessContext.WithTransactionAsync(
);
if (originalDataFile is null)
throw new EntityNotFoundException($"Could not find the DataFile '{request.FileId}'.");
if (originalDataFile.Format == FileFormat.Paratext)
{
ParatextMetadata metadata = await ParatextProjectDataParser.ParseParatextMetadataAsync(path);
await dataFiles.UpdateAsync(
request.FileId,
u => u.Set(f => f.FileMetadata, metadata),
cancellationToken: ct
);
}

await deletedFiles.InsertAsync(
new DeletedFile { Filename = originalDataFile.Filename, DeletedAt = DateTime.UtcNow },
ct
Expand Down
1 change: 1 addition & 0 deletions src/Serval/src/Serval.DataFiles/Models/DataFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public record DataFile : IOwnedEntity
public required string Name { get; init; }
public string Filename { get; init; } = "";
public required FileFormat Format { get; init; }
public ParatextMetadata? FileMetadata { get; init; }
}
12 changes: 12 additions & 0 deletions src/Serval/src/Serval.DataFiles/Models/ParatextMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Serval.DataFiles.Models;

public record ParatextMetadata
{
public required string ProjectGuid { get; init; }
public required string Name { get; init; }
public required string FullName { get; init; }
public required string Versification { get; init; }
public required string TranslationType { get; init; }
public string? LanguageCode { get; init; }
public string? Visibility { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Serval.DataFiles.Services;

public class ParatextProjectDataParser
{
public static async Task<ParatextMetadata> ParseParatextMetadataAsync(string path)
{
using ZipContainer zipContainer = new(path);
try
{
ParatextProjectSettings projectSettings = new Shared.Services.ZipParatextProjectSettingsParser(
zipContainer
).Parse();
return new ParatextMetadata
{
ProjectGuid = projectSettings.Guid,
Name = projectSettings.Name,
FullName = projectSettings.FullName,
Versification = projectSettings.Versification.Name,
TranslationType = projectSettings.TranslationType,
LanguageCode = projectSettings.LanguageCode,
Visibility = projectSettings.Visibility,
};
}
catch (Exception e) when (e is not OperationCanceledException)
{
throw new InvalidOperationException(
"Unable to parse the Paratext project settings for the uploaded data file.",
e
);
}
}
}
1 change: 1 addition & 0 deletions src/Serval/src/Serval.DataFiles/Usings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
global using Serval.Shared.Services;
global using Serval.Shared.Utils;
global using SIL.DataAccess;
global using SIL.Machine.Corpora;
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ public async Task CreateDataFile_Error()
env.FileSystem.Received().DeleteFile(Arg.Any<string>());
}

[Test]
public async Task CreateDataFile_Paratext()
{
var env = new TestEnvironment();
env.FileSystem.OpenWrite(Arg.Any<string>())
.Returns(callInfo => new FileStream(callInfo.Arg<string>(), FileMode.Create, FileAccess.Write));
string paratextZipPath = ZipParatextProject();
CreateDataFileHandler handler = new(env.DataFiles, env.IdGenerator, env.Options, env.FileSystem, env.Mapper);
using FileStream stream = File.OpenRead(paratextZipPath);
CreateDataFileResponse response = await handler.HandleAsync(
new(Owner, "file1", "file1.txt", FileFormat.Paratext, stream),
CancellationToken.None
);
DataFile? dataFile = await env.DataFiles.GetAsync(response.DataFile.Id, CancellationToken.None);
Assert.That(dataFile, Is.Not.Null);
Assert.That(dataFile.FileMetadata, Is.Not.Null);
ParatextMetadata metadata = dataFile.FileMetadata;
using (Assert.EnterMultipleScope())
{
Assert.That(metadata.ProjectGuid, Is.EqualTo("a7e0b3ce0200736062f9f810a444dbfbe64aca35"));
Assert.That(metadata.Name, Is.EqualTo("Te1"));
Assert.That(metadata.FullName, Is.EqualTo("Test1"));
Assert.That(metadata.TranslationType, Is.EqualTo("Standard"));
Assert.That(metadata.Versification, Does.StartWith("English"));
Assert.That(metadata.LanguageCode, Is.EqualTo("en"));
Assert.That(metadata.Visibility, Is.EqualTo("Public"));
}
}

[Test]
public async Task DownloadDataFile_FileExists()
{
Expand Down Expand Up @@ -273,4 +302,13 @@ public async Task<DataFile> CreateDataFileAsync(string id = "df00000000000000000
return file;
}
}

private static string ZipParatextProject()
{
string path = Path.Combine(Path.GetTempPath(), "pt-project.zip");
if (File.Exists(path))
File.Delete(path);
ZipFile.CreateFromDirectory(Path.Combine("..", "..", "..", "data", "pt-project"), path);
return path;
}
}
1 change: 1 addition & 0 deletions src/Serval/test/Serval.DataFiles.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
global using System.IO.Compression;
global using System.Text;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
\id MAT - SRC
\c 1
\v 1 SRC - Chapter one, verse one.
\p new paragraph
\v 2
\v 3 SRC - Chapter one, verse three.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<ScriptureText>
<StyleSheet>usfm.sty</StyleSheet>
<Versification>4</Versification>
<LanguageIsoCode>en:::</LanguageIsoCode>
<Language>English</Language>
<MinParatextVersion>8.0.100.76</MinParatextVersion>
<FullName>Test1</FullName>
<Encoding>65001</Encoding>
<Editable>T</Editable>
<Copyright />
<NormalizationForm>NFC</NormalizationForm>
<Name>Te1</Name>
<Guid>a7e0b3ce0200736062f9f810a444dbfbe64aca35</Guid>
<DefaultFont>Charis SIL</DefaultFont>
<DefaultFontSize>12</DefaultFontSize>
<FontFeatures />
<HtmlLanguage />
<AssociatedLexicalProject />
<FileNameBookNameForm>41MAT</FileNameBookNameForm>
<FileNamePrePart />
<FileNamePostPart>Tes.SFM</FileNamePostPart>
<BiblicalTermsListSetting>Major::BiblicalTerms.xml</BiblicalTermsListSetting>
<MatchBasedOnStems>F</MatchBasedOnStems>
<AllowReadAccess>F</AllowReadAccess>
<AllowSharingWithSLDR>F</AllowSharingWithSLDR>
<Visibility>Public</Visibility>
<TranslationInfo>Standard::</TranslationInfo>
<EncodingConverter />
<UsfmVersion>3</UsfmVersion>
<ParallelPassagesBooks>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</ParallelPassagesBooks>
<BooksPresent>000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000</BooksPresent>
<BibleModuleAssociations />
<Naming PrePart="" PostPart="Te1.SFM" BookNameForm="41MAT" />
</ScriptureText>
31 changes: 31 additions & 0 deletions src/Serval/test/Serval.DataFiles.Tests/data/pt-project/custom.vrs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# custom.vrs

LEV 14:56
ROM 14:26
REV 12:17
TOB 5:22
TOB 10:12
SIR 23:28
ESG 1:22
ESG 3:15
ESG 5:14
ESG 8:17
ESG 10:14
SIR 33:33
SIR 41:24
BAR 1:22
4MA 7:25
4MA 12:20

# deliberately missing verses
-ROM 16:26
-ROM 16:27
-3JN 1:15
-S3Y 1:49
-ESG 4:6
-ESG 9:5
-ESG 9:30

LEV 14:55 = LEV 14:55
LEV 14:55 = LEV 14:56
LEV 14:56 = LEV 14:57
Loading