aboutsummaryrefslogtreecommitdiff
path: root/back-end
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-11-10 22:40:35 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-11-10 22:40:35 -0500
commit39a22deb6a232356bf7b2ef8386679bc8ea2f697 (patch)
tree743eb0a0bb06a8ae85a36778c748880374798f01 /back-end
parent00582bef545a912c2f81ea359dc00c92dd991ceb (diff)
much needed QOL updates
Diffstat (limited to 'back-end')
-rw-r--r--back-end/src/Content.Publishing.Blog.Admin.csproj2
-rw-r--r--back-end/src/Endpoints/ContentEndpoint.cs62
-rw-r--r--back-end/src/Storage/ManagedStorage.cs14
3 files changed, 66 insertions, 12 deletions
diff --git a/back-end/src/Content.Publishing.Blog.Admin.csproj b/back-end/src/Content.Publishing.Blog.Admin.csproj
index 97a575f..8c923f0 100644
--- a/back-end/src/Content.Publishing.Blog.Admin.csproj
+++ b/back-end/src/Content.Publishing.Blog.Admin.csproj
@@ -34,7 +34,7 @@
<ItemGroup>
<PackageReference Include="FluentFTP" Version="48.0.3" />
- <PackageReference Include="Minio" Version="6.0.0" />
+ <PackageReference Include="Minio" Version="6.0.1" />
<PackageReference Include="VNLib.Plugins.Extensions.Loading" Version="0.1.0-ci0042" />
<PackageReference Include="VNLib.Plugins.Extensions.Validation" Version="0.1.0-ci0042" />
</ItemGroup>
diff --git a/back-end/src/Endpoints/ContentEndpoint.cs b/back-end/src/Endpoints/ContentEndpoint.cs
index 2427cf0..92aee3b 100644
--- a/back-end/src/Endpoints/ContentEndpoint.cs
+++ b/back-end/src/Endpoints/ContentEndpoint.cs
@@ -22,6 +22,7 @@
using System;
using System.IO;
using System.Net;
+using System.Linq;
using System.Threading.Tasks;
using FluentValidation;
@@ -45,6 +46,7 @@ namespace Content.Publishing.Blog.Admin.Endpoints
internal sealed class ContentEndpoint : ProtectedWebEndpoint
{
private static readonly IValidator<ContentMeta> MetaValidator = ContentMeta.GetValidator();
+ private static readonly IValidator<string[]> MultiDeleteValidator = GetMultiDeleteValidator();
private readonly ContentManager _content;
private readonly IChannelContextManager _blogContextManager;
@@ -312,12 +314,6 @@ namespace Content.Publishing.Blog.Admin.Endpoints
return VfReturnType.BadRequest;
}
- //get the content id
- if (!entity.QueryArgs.TryGetNonEmptyValue("id", out string? contentId))
- {
- return VfReturnType.BadRequest;
- }
-
//Get channel
IChannelContext? channel = await _blogContextManager.GetChannelAsync(channelId, entity.EventCancellation);
if (channel == null)
@@ -325,11 +321,59 @@ namespace Content.Publishing.Blog.Admin.Endpoints
return VfReturnType.NotFound;
}
- //Try to delete the content
- bool deleted = await _content.DeleteContentAsync(channel, contentId, entity.EventCancellation);
+ //get the single content id
+ if (entity.QueryArgs.TryGetNonEmptyValue("id", out string? contentId))
+ {
+ //Try to delete the content
+ bool deleted = await _content.DeleteContentAsync(channel, contentId, entity.EventCancellation);
+
+ return deleted ? VirtualOk(entity) : VfReturnType.NotFound;
+ }
+
+ //Check for bulk delete
+ if (entity.QueryArgs.TryGetNonEmptyValue("ids", out string? multiIds))
+ {
+ ValErrWebMessage webm = new();
- return deleted ? VirtualOk(entity) : VfReturnType.NotFound;
+ string[] allIds = multiIds.Split(',');
+
+ //validate the ids
+ if (!MultiDeleteValidator.Validate(allIds, webm))
+ {
+ return VirtualClose(entity, webm, HttpStatusCode.UnprocessableEntity);
+ }
+
+ //Delete all async at the same time, then filter out the nulls
+ Task<string>[] deleted = allIds.Select(async id =>
+ {
+ return await _content.DeleteContentAsync(channel, id, entity.EventCancellation) ? id : null;
+
+ }).Where(id => id != null).ToArray()!;
+
+ //Get the deleted ids
+ string[] deletedIds = await Task.WhenAll(deleted);
+
+ webm.Result = deletedIds;
+ webm.Success = true;
+
+ return VirtualOk(entity, webm);
+ }
+
+ return VfReturnType.BadRequest;
+
}
+
+ static IValidator<string[]> GetMultiDeleteValidator()
+ {
+ InlineValidator<string[]> val = new();
+
+ val.RuleForEach(p => p)
+ .NotEmpty()
+ .Length(0, 64)
+ .AlphaNumericOnly();
+
+ return val;
+ }
}
}
diff --git a/back-end/src/Storage/ManagedStorage.cs b/back-end/src/Storage/ManagedStorage.cs
index 19e208c..66e9a4a 100644
--- a/back-end/src/Storage/ManagedStorage.cs
+++ b/back-end/src/Storage/ManagedStorage.cs
@@ -30,13 +30,23 @@ using VNLib.Plugins.Extensions.Loading;
namespace Content.Publishing.Blog.Admin.Storage
{
+ [ConfigurationName("storage", Required = false)]
internal sealed class ManagedStorage : ISimpleFilesystem
{
private readonly ISimpleFilesystem _backingStorage;
- public ManagedStorage(PluginBase plugin)
+ public ManagedStorage(PluginBase plugin) : this(plugin, null)
+ { }
+
+ public ManagedStorage(PluginBase plugin, IConfigScope? config)
{
- if (plugin.HasConfigForType<MinioClientManager>())
+ //try to get custom storage assembly
+ if (config != null && config.ContainsKey("custom_storage_assembly"))
+ {
+ string storageAssembly = config.GetRequiredProperty("custom_storage_assembly", p => p.GetString()!);
+ _backingStorage = plugin.CreateServiceExternal<ISimpleFilesystem>(storageAssembly);
+ }
+ else if (plugin.HasConfigForType<MinioClientManager>())
{
//Use minio storage
_backingStorage = plugin.GetOrCreateSingleton<MinioClientManager>();