Pin nixpkgs to the revision used by itc.componentware: the channel version ships a latexminted that crashes on Python 3.14, which made every listing fail and sent latexmk into an endless error prompt. Also force nonstopmode/halt-on-error so a broken listing can never loop again.
43 lines
1.6 KiB
C#
43 lines
1.6 KiB
C#
public async Task<IActionResult> OnPostDownloadZipAsync(CancellationToken cancellationToken)
|
|
{
|
|
if (!OrgName.TryCreate(User.GetCompanyName(), out var orgName))
|
|
return NotFound();
|
|
|
|
var fallback = RedirectToPage(new
|
|
{
|
|
q = Search,
|
|
types = TypeFilterSelection,
|
|
pageSize = PageSize,
|
|
pageToken = PageToken,
|
|
});
|
|
|
|
if (SelectedDocuments is null || SelectedDocuments.Count == 0)
|
|
return fallback;
|
|
|
|
var relativePaths = SelectedDocuments
|
|
.SelectWhere<string, DocumentRelativePath>(x => new DocumentId(x).TryDecode(out var y) ? y.Value : null)
|
|
.Where(x => IsDownloadable(x.Name))
|
|
.ToList();
|
|
|
|
if (relativePaths.Count == 0)
|
|
return fallback;
|
|
|
|
var orgSlug = await documents.ResolveCustomerPrefixAsync(OrgId, orgName.Value, cancellationToken);
|
|
if (orgSlug is null)
|
|
return fallback;
|
|
|
|
// Zipping compresses each entry with a DeflateStream, which flushes its buffers synchronously
|
|
// when the entry is closed. Kestrel forbids synchronous response writes by default, so we opt
|
|
// in for this streamed response only. Nothing large is written synchronously - the document
|
|
// payloads are still copied with async IO.
|
|
var bodyControl = HttpContext.Features.Get<IHttpBodyControlFeature>();
|
|
bodyControl?.AllowSynchronousIO = true;
|
|
|
|
Response.ContentType = "application/zip";
|
|
Response.Headers.ContentDisposition = $"attachment; filename=\"{DocumentsService.ZipDownloadFileName}\"";
|
|
|
|
await documents.WriteZipArchiveAsync(orgSlug.Value, relativePaths, Response.Body, cancellationToken);
|
|
|
|
return new EmptyResult();
|
|
}
|