Untis-API Optimierung.

This commit is contained in:
2026-08-24 22:33:30 +02:00
parent 1db16f8b69
commit 17475a781f
9 changed files with 109 additions and 53 deletions
@@ -30,8 +30,6 @@ public sealed record UntisStudentReportDto(int Count, string? ClassNameFilter, I
public sealed record UntisStudentAbsenceDto(int StudentKey, int Date, int StartTime, int EndTime, int AbsentMinutes,
bool Checked, string? AbsenceReason, string? ExcuseStatus, int? SubjectId, IReadOnlyList<int> TeacherIds,
string? StudentGroup);
public sealed record UntisStudentAbsenceReportDto(int StudentKey, int StartDate, int EndDate, int EntryCount,
int AbsentMinutes, IReadOnlyList<UntisStudentAbsenceDto> Absences);
/// <summary>Direkter WebUntis-Client des Desktops. Personenbezogene Antworten und der
/// unverschlüsselte CSV-Report passieren zu keinem Zeitpunkt den LehrerApp-Server.</summary>
@@ -56,19 +54,19 @@ public sealed class WebUntisIntegrationService(HttpClient http, WebUntisSettings
}
WebUntisClient? previous;
await _clientGate.WaitAsync(token);
await _clientGate.WaitAsync(token).ConfigureAwait(false);
try { previous = _client; _client = candidate; }
finally { _clientGate.Release(); }
if (previous is not null) await previous.DisposeAsync();
if (previous is not null) await previous.DisposeAsync().ConfigureAwait(false);
}
public async Task DisconnectAsync(CancellationToken token = default)
{
WebUntisClient? previous;
await _clientGate.WaitAsync(token);
await _clientGate.WaitAsync(token).ConfigureAwait(false);
try { previous = _client; _client = null; }
finally { _clientGate.Release(); }
if (previous is not null) await previous.DisposeAsync();
if (previous is not null) await previous.DisposeAsync().ConfigureAwait(false);
}
public Task<IReadOnlyList<UntisSchoolYearDto>> GetSchoolYearsAsync(CancellationToken token = default) => ExecuteAsync(
@@ -109,14 +107,13 @@ public sealed class WebUntisIntegrationService(HttpClient http, WebUntisSettings
x.Address.PostCode, x.Address.Street), x.AttributeIL)).ToList());
}, token);
public Task<UntisStudentAbsenceReportDto> GetAbsencesAsync(int studentKey, DateOnly start, DateOnly end,
public Task<IReadOnlyList<UntisStudentAbsenceDto>> GetAbsencesAsync(DateOnly start, DateOnly end,
CancellationToken token = default) => ExecuteAsync(async client =>
{
var report = await client.GetStudentAbsencesAsync(studentKey, Date(start), Date(end), token);
return new UntisStudentAbsenceReportDto(report.StudentKey, report.StartDate, report.EndDate,
report.EntryCount, report.AbsentMinutes, report.Absences.Select(x => new UntisStudentAbsenceDto(
x.StudentKey, x.Date, x.StartTime, x.EndTime, x.AbsentMinutes, x.Checked, x.AbsenceReason,
x.ExcuseStatus, x.SubjectId, x.TeacherIds, x.StudentGroup)).ToList());
var absences = await client.GetAbsencesAsync(Date(start), Date(end), token);
return (IReadOnlyList<UntisStudentAbsenceDto>)absences.Select(x => new UntisStudentAbsenceDto(
x.StudentKey, x.Date, x.StartTime, x.EndTime, x.AbsentMinutes, x.Checked, x.AbsenceReason,
x.ExcuseStatus, x.SubjectId, x.TeacherIds, x.StudentGroup)).ToList();
}, token);
private async Task<T> ExecuteAsync<T>(Func<WebUntisClient, Task<T>> operation, CancellationToken token)
@@ -153,5 +150,5 @@ public sealed class WebUntisIntegrationService(HttpClient http, WebUntisSettings
private static WebUntisIntegrationException Translate(Exception exception) =>
new(exception.Message);
public async ValueTask DisposeAsync() => await DisconnectAsync();
public async ValueTask DisposeAsync() => await DisconnectAsync().ConfigureAwait(false);
}