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 }); });