[feat] Bulk query

This commit is contained in:
acite
2025-09-13 13:06:55 +08:00
parent ae93b75e41
commit 197cf525fb
5 changed files with 58 additions and 5 deletions

View File

@@ -11,7 +11,10 @@
<component name="ChangeListManager">
<list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/ImageController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/ImageController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Tools/AbyssStream.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Tools/AbyssStream.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -85,7 +88,7 @@
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;XThreadsFramesViewSplitterKey&quot;: &quot;0.30266345&quot;,
&quot;git-widget-placeholder&quot;: &quot;dev-abyss&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;last_opened_file_path&quot;: &quot;/storage/Images/31/summary.json&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
@@ -201,6 +204,9 @@
<workItem from="1757687641035" duration="2969000" />
<workItem from="1757693751836" duration="667000" />
<workItem from="1757694833696" duration="11000" />
<workItem from="1757695721386" duration="749000" />
<workItem from="1757702942841" duration="32000" />
<workItem from="1757735249561" duration="4543000" />
</task>
<servers />
</component>

View File

@@ -9,6 +9,8 @@ using Newtonsoft.Json.Linq;
namespace Abyss.Components.Controllers.Media;
using System.IO;
using Task = System.Threading.Tasks.Task;
[ApiController]
[Route("api/[controller]")]
public class ImageController(ILogger<ImageController> logger, ResourceService rs, ConfigureService config) : BaseController
@@ -46,6 +48,27 @@ public class ImageController(ILogger<ImageController> logger, ResourceService rs
return Ok(await System.IO.File.ReadAllTextAsync(d));
}
[HttpPost("bulkquery")]
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id)
{
List<string> result = new List<string>();
var db = id.Select(x => Helpers.SafePathCombine(ImageFolder, [x, "summary.json"])).ToArray();
if(db.Any(x => x == null))
return StatusCode(403, new { message = "403 Denied" });
var rb = db.Select(x => rs.Get(x!, token, Ip)).ToArray();
bool[] results = await Task.WhenAll(rb);
if(results.Any(x => !x))
return StatusCode(403, new { message = "403 Denied" });
var rc = db.Select(x => System.IO.File.ReadAllTextAsync(x!)).ToArray();
string[] rcs = await Task.WhenAll(rc);
return Ok(rcs);
}
[HttpPost("{id}/bookmark")]
public async Task<IActionResult> Bookmark(string id, string token, [FromBody] Bookmark bookmark)
{

View File

@@ -8,6 +8,8 @@ using Newtonsoft.Json;
namespace Abyss.Components.Controllers.Media;
using Task = System.Threading.Tasks.Task;
[ApiController]
[Route("api/[controller]")]
public class VideoController(ILogger<VideoController> logger, ResourceService rs, ConfigureService config) : BaseController
@@ -73,6 +75,27 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
return Ok(await System.IO.File.ReadAllTextAsync(d));
}
[HttpPost("{klass}/bulkquery")]
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id, [FromRoute] string klass)
{
List<string> result = new List<string>();
var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray();
if(db.Any(x => x == null))
return BadRequest();
var rb = db.Select(x => rs.Get(x!, token, Ip)).ToArray();
bool[] results = await Task.WhenAll(rb);
if(results.Any(x => !x))
return StatusCode(403, new { message = "403 Denied" });
var rc = db.Select(x => System.IO.File.ReadAllTextAsync(x!)).ToArray();
string[] rcs = await Task.WhenAll(rc);
return Ok(rcs);
}
[HttpGet("{klass}/{id}/cover")]
public async Task<IActionResult> Cover(string klass, string id, string token)
{
@@ -82,8 +105,6 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
var r = await rs.Get(d, token, Ip);
if (!r) return StatusCode(403, new { message = "403 Denied" });
_logger.LogInformation($"Cover found for {id}");
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
}

View File

@@ -41,6 +41,7 @@ public class AbyssService(ILogger<AbyssService> logger, ConfigureService config)
int bytesRead = await upstream.ReadAsync(buffer, 0, buffer.Length, token);
if (bytesRead == 0)
break;
await client.WriteAsync(buffer, 0, bytesRead, token);
}
});

View File

@@ -5,7 +5,7 @@
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Data;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
@@ -16,6 +16,8 @@ using ChaCha20Poly1305 = System.Security.Cryptography.ChaCha20Poly1305;
namespace Abyss.Components.Tools
{
// TODO: Since C25519 has already been used for user authentication,
// TODO: why not use that public key to verify user identity when establishing a secure channel here?
public sealed class AbyssStream : NetworkStream, IDisposable
{
private const int PublicKeyLength = 32;