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.
65 lines
2.7 KiB
C#
65 lines
2.7 KiB
C#
private async Task<OrgSlug?> GetCustomerFolderAsync(OrgName name, OrgId id, CancellationToken cancellationToken)
|
|
{
|
|
if (!OrgSlug.TryFrom(name, out var canonicalSlug) || !OrgSlug.TryFrom(name, id, out var collisionSlug))
|
|
{
|
|
ExceptionlessClient.Default.SubmitLog($"Efecte name '{name}' of organization {id} does not yield a usable folder name.", LogLevel.Warn);
|
|
return null;
|
|
}
|
|
|
|
var (prettySlug, uniqueSlug) = (canonicalSlug.Value, collisionSlug.Value);
|
|
|
|
// Fast path: pretty slug exists & meta-id matches => return slug(name)
|
|
var prettyState = await InspectCustomerFolderAsync(prettySlug, id, cancellationToken);
|
|
if (prettyState is CustomerFolderState.Owned)
|
|
return prettySlug;
|
|
|
|
// Conflict resolution: pretty slug exists & meta-id does not match => return slug(name,id)
|
|
var uniqueState = await InspectCustomerFolderAsync(uniqueSlug, id, cancellationToken);
|
|
if (uniqueState is CustomerFolderState.Owned)
|
|
return uniqueSlug;
|
|
|
|
// State cleanup:
|
|
// Either the folder does not have the name it should have or doesn't exist, so the bucket has to be scanned. And
|
|
// if necessary and possible, renamed such that the next lookup hits one of the expected slugs.
|
|
|
|
OrgSlug? availableSlug =
|
|
prettyState is CustomerFolderState.Missing ? prettySlug
|
|
: uniqueState is CustomerFolderState.Missing ? uniqueSlug
|
|
: null;
|
|
|
|
var currentSlug = await SearchCustomerPrefixAsync(id, cancellationToken);
|
|
|
|
if (currentSlug is null)
|
|
{
|
|
if (availableSlug is not { } available)
|
|
{
|
|
ExceptionlessClient.Default.SubmitLog(
|
|
$"Organization {id} has no customer folder and neither "
|
|
+ $"'{prettySlug}' nor '{uniqueSlug}' is available.", LogLevel.Error);
|
|
return null;
|
|
}
|
|
|
|
if (!await CreateCustomerFolderAsync(available, id, cancellationToken))
|
|
return null;
|
|
|
|
if (await InspectCustomerFolderAsync(available, id, cancellationToken) is not CustomerFolderState.Owned)
|
|
{
|
|
ExceptionlessClient.Default.SubmitLog(
|
|
$"Organization {id} has no customer folder and "
|
|
+ $"'{available}' could not be created.", LogLevel.Error);
|
|
return null;
|
|
}
|
|
|
|
return available;
|
|
}
|
|
|
|
if (availableSlug is null || availableSlug.Value == currentSlug.Value)
|
|
return currentSlug;
|
|
|
|
// A failed move leaves every document under the name it already had, so that name is what
|
|
// gets handed back. The next lookup simply tries the move again.
|
|
return await RenameCustomerFolderAsync(currentSlug.Value, availableSlug.Value, id, cancellationToken)
|
|
? availableSlug
|
|
: currentSlug;
|
|
}
|