feat: Teilnehmerlisten in Lerngruppen importieren
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using System.Text;
|
||||
|
||||
namespace LehrerApp.Core.Importing;
|
||||
|
||||
/// <summary>Erkennt den Notenlistenexport und erklärt dessen fehlende Teilnehmerdaten.</summary>
|
||||
public sealed class MarksPerLessonCsvImportHandler : IImportHandler<ImportedStudent>
|
||||
{
|
||||
private static readonly string[] SignatureHeaders =
|
||||
["Datum", "Name", "Klasse", "Fach", "Prüfungsart", "Note", "Bemerkung", "Benutzer", "Schlüssel (extern)", "Gesamtnote"];
|
||||
private static readonly UTF8Encoding StrictUtf8 = new(false, true);
|
||||
|
||||
public ImportFormatId FormatId => StudentImportFormats.MarksPerLessonCsv;
|
||||
public string DisplayName => "Unterrichts-Notenliste";
|
||||
public IReadOnlyCollection<string> SupportedExtensions { get; } = [".csv"];
|
||||
|
||||
public ValueTask<ImportDetection> DetectAsync(ImportFile file, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string text;
|
||||
try { text = StrictUtf8.GetString(file.Content.Span); }
|
||||
catch (DecoderFallbackException) { return ValueTask.FromResult(ImportDetection.NoMatch()); }
|
||||
var end = text.IndexOfAny(['\r', '\n']);
|
||||
var firstLine = (end >= 0 ? text[..end] : text).TrimStart('\uFEFF');
|
||||
var headers = firstLine.Split('\t').Select(x => x.Trim()).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
return ValueTask.FromResult(SignatureHeaders.All(headers.Contains)
|
||||
? ImportDetection.Match(file.Extension.Equals(".csv", StringComparison.OrdinalIgnoreCase) ? 100 : 95)
|
||||
: ImportDetection.NoMatch());
|
||||
}
|
||||
|
||||
public ValueTask<ImportParseResult<ImportedStudent>> ParseAsync(ImportFile file, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
IReadOnlyList<ImportMessage> messages =
|
||||
[
|
||||
new(ImportMessageSeverity.Error, "marks-per-lesson.no-participants",
|
||||
"Die Notenliste enthält keine verlässlichen Teilnehmerdaten. Bitte exportiere die echte Kurs-/Teilnehmerliste.")
|
||||
];
|
||||
return ValueTask.FromResult(new ImportParseResult<ImportedStudent>([], messages));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user