diff --git a/AobaClient/src/components/media_item.rs b/AobaClient/src/components/media_item.rs
index 36469ea..359cfc6 100644
--- a/AobaClient/src/components/media_item.rs
+++ b/AobaClient/src/components/media_item.rs
@@ -1,6 +1,6 @@
use dioxus::prelude::*;
-use crate::rpc::aoba::MediaModel;
+use crate::{HOST, rpc::aoba::MediaModel};
#[derive(PartialEq, Clone, Props)]
pub struct MediaItemProps {
@@ -14,9 +14,9 @@ pub fn MediaItem(props: MediaItemProps) -> Element {
let id = props.item.media_id.unwrap().value;
#[cfg(debug_assertions)]
- let src = format!("http://localhost:5164/m/{id}");
+ let src = format!("{HOST}/m/thumb/{id}");
#[cfg(not(debug_assertions))]
- let src = format!("https://aoba.app/m/{id}");
+ let src = format!("https://aoba.app/m/thumb/{id}");
// let url = "https://aoba.app/i/{}";
rsx! {
div{
diff --git a/AobaClient/src/main.rs b/AobaClient/src/main.rs
index ad305c8..d35de06 100644
--- a/AobaClient/src/main.rs
+++ b/AobaClient/src/main.rs
@@ -11,9 +11,9 @@ use dioxus::prelude::*;
use route::Route;
#[cfg(debug_assertions)]
-pub const HOST: &'static str = "http://localhost:5164";
+pub const HOST: &'static str = "http://localhost:8080";
#[cfg(debug_assertions)]
-pub const RPC_HOST: &'static str = "http://localhost:5164";
+pub const RPC_HOST: &'static str = "http://localhost:8080";
#[cfg(not(debug_assertions))]
pub const RPC_HOST: &'static str = "https://grpc.aoba.app:8443";
#[cfg(not(debug_assertions))]
diff --git a/AobaCore/AobaCore.csproj b/AobaCore/AobaCore.csproj
index 7eb3c32..4d3e6b0 100644
--- a/AobaCore/AobaCore.csproj
+++ b/AobaCore/AobaCore.csproj
@@ -12,8 +12,9 @@
-
-
+
+
+
diff --git a/AobaCore/Services/AobaService.cs b/AobaCore/Services/AobaService.cs
index 918db8a..846715b 100644
--- a/AobaCore/Services/AobaService.cs
+++ b/AobaCore/Services/AobaService.cs
@@ -18,7 +18,12 @@ public class AobaService(IMongoDatabase db)
return await _media.Find(m => m.Id == id).FirstOrDefaultAsync(cancellationToken);
}
- public async Task> FindMediaAsync(string? query, int page = 1, int pageSize = 100)
+ public async Task GetMediaFromFileAsync(ObjectId id, CancellationToken cancellationToken = default)
+ {
+ return await _media.Find(m => m.MediaId == id).FirstOrDefaultAsync(cancellationToken);
+ }
+
+ public async Task> FindMediaAsync(string? query, int page = 1, int pageSize = 100)
{
var filter = string.IsNullOrWhiteSpace(query) ? "{}" : Builders.Filter.Text(query);
var sort = Builders.Sort.Descending(m => m.UploadDate);
diff --git a/AobaCore/Services/ThumbnailService.cs b/AobaCore/Services/ThumbnailService.cs
index f0f2b40..cf8d92b 100644
--- a/AobaCore/Services/ThumbnailService.cs
+++ b/AobaCore/Services/ThumbnailService.cs
@@ -4,6 +4,9 @@ using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Processing;
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,18 +14,42 @@ using System.Text;
using System.Threading.Tasks;
namespace AobaCore.Services;
-internal class ThumbnailService(IMongoDatabase db, AobaService aobaService)
+public class ThumbnailService(IMongoDatabase db, AobaService aobaService)
{
private readonly GridFSBucket _gridfs = new GridFSBucket(db);
private readonly IMongoCollection _thumbnails = db.GetCollection("thumbs");
- public async Task GetThumbnailAsync(ObjectId id)
+ public async Task GetThumbnailAsync(ObjectId id, CancellationToken cancellationToken = default)
{
- throw new NotImplementedException();
+ var media = await aobaService.GetMediaAsync(id);
+ if (media == null)
+ return null;
+ if (media.MediaType != MediaType.Image)
+ return null;
+ using var file = await _gridfs.OpenDownloadStreamAsync(media.MediaId, new GridFSDownloadOptions { Seekable = true });
+ return await GenerateThumbnailAsync(file, cancellationToken);
+ }
+ public async Task GetThumbnailFromFileAsync(ObjectId id, CancellationToken cancellationToken = default)
+ {
+ var media = await aobaService.GetMediaFromFileAsync(id);
+ if (media == null)
+ return null;
+ if (media.MediaType != MediaType.Image)
+ return null;
+ using var file = await _gridfs.OpenDownloadStreamAsync(media.MediaId, new GridFSDownloadOptions { Seekable = true });
+ return await GenerateThumbnailAsync(file, cancellationToken);
}
- public async Task GenerateThumbnailAsync(ObjectId id)
+ public async Task GenerateThumbnailAsync(Stream stream, CancellationToken cancellationToken = default)
{
-
+ var img = Image.Load(stream);
+ img.Mutate(o =>
+ {
+ o.Resize(200, 200);
+ });
+ var result = new MemoryStream();
+ await img.SaveAsWebpAsync(result, cancellationToken);
+ result.Position = 0;
+ return result;
}
}
diff --git a/AobaServer/AobaServer.csproj b/AobaServer/AobaServer.csproj
index 46e64b9..937446b 100644
--- a/AobaServer/AobaServer.csproj
+++ b/AobaServer/AobaServer.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/AobaServer/Controllers/MediaController.cs b/AobaServer/Controllers/MediaController.cs
index b08c406..acf2853 100644
--- a/AobaServer/Controllers/MediaController.cs
+++ b/AobaServer/Controllers/MediaController.cs
@@ -44,9 +44,11 @@ public class MediaController(AobaService aobaService, ILogger l
}
[HttpGet("thumb/{id}")]
- public async Task ThumbAsync(ObjectId id)
+ public async Task ThumbAsync(ObjectId id, [FromServices] ThumbnailService thumbnailService, CancellationToken cancellationToken)
{
-
- return NoContent();
+ var thumb = await thumbnailService.GetThumbnailFromFileAsync(id, cancellationToken);
+ if (thumb == null)
+ return NotFound();
+ return File(thumb, "image/webp", true);
}
}
diff --git a/AobaServer/Middleware/OpenTelemetry.cs b/AobaServer/Middleware/OpenTelemetry.cs
index 475aac8..af9032e 100644
--- a/AobaServer/Middleware/OpenTelemetry.cs
+++ b/AobaServer/Middleware/OpenTelemetry.cs
@@ -67,7 +67,7 @@ public static class OpenTelemetry
public static IEndpointRouteBuilder MapObserability(this IEndpointRouteBuilder endpoints)
{
- endpoints.MapPrometheusScrapingEndpoint().RequireAuthorization(p => p.RequireRole("metrics"));
+ endpoints.MapPrometheusScrapingEndpoint().RequireAuthorization();
return endpoints;
}
}
diff --git a/AobaServer/Program.cs b/AobaServer/Program.cs
index 230d9f3..d18d33b 100644
--- a/AobaServer/Program.cs
+++ b/AobaServer/Program.cs
@@ -60,10 +60,6 @@ builder.Services.AddCors(o =>
p.AllowAnyHeader();
p.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
p.AllowAnyOrigin();
-//#if DEBUG
-//#else
-// p.WithOrigins("https://aoba.app", "https://grpc.aoba.app");
-//#endif
});
});