From 2b66d00175950d845a794422433d4a350cf87775 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Wed, 6 May 2026 22:33:52 +1000 Subject: v0.13a --- Controllers/ApiMediaController.cs | 98 +++++++++++++++++++++++++++++++++++++++ Controllers/ApiTagController.cs | 36 ++++++++++++++ Controllers/LoginController.cs | 1 - Controllers/MediaController.cs | 3 +- 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 Controllers/ApiMediaController.cs create mode 100644 Controllers/ApiTagController.cs (limited to 'Controllers') diff --git a/Controllers/ApiMediaController.cs b/Controllers/ApiMediaController.cs new file mode 100644 index 0000000..0539b77 --- /dev/null +++ b/Controllers/ApiMediaController.cs @@ -0,0 +1,98 @@ +using HyperBooru.ApiModels; +using HyperBooru.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using System.Text.Json; + +namespace HyperBooru.Controllers; + +[ApiController] +[Route("/api/media")] +public class ApiMediaController : Controller { + private IDbContextFactory dbFactory; + private IMediaService mediaService; + + public ApiMediaController(IDbContextFactory dbFactory, IMediaService mediaService) { + this.dbFactory = dbFactory; + this.mediaService = mediaService; + } + + [HttpGet("{mediaId}")] + public async Task Get([FromRoute] Guid mediaId) { + using var db = dbFactory.CreateDbContext(); + + var media = await db.Media.FirstOrDefaultAsync(m => m.Guid == mediaId); + + if(media is null) + throw new ObjectNotFoundException(mediaId); + + return Ok((ApiModels.Media) media); + } + + [HttpGet("{mediaId}/files")] + public async Task GetUploadedFiles([FromRoute] Guid mediaId) { + using var db = dbFactory.CreateDbContext(); + + var media = await db.Media + .Include(m => m.UploadedFiles) + .FirstOrDefaultAsync(m => m.Guid == mediaId); + + if(media is null) + throw new ObjectNotFoundException(mediaId); + + return Ok(media.UploadedFiles.Select(uf => (ApiModels.UploadedFile) uf).ToArray()); + } + + [HttpPatch] + public async Task UpdateMedia([FromBody] ApiModels.Media updatedMedia) { + using var db = dbFactory.CreateDbContext(); + using var transaction = await db.Database.BeginTransactionAsync(); + + var media = await db.Media.FirstOrDefaultAsync(m => m.Guid == updatedMedia.MediaId); + if(media is null) + return NotFound(); + + media.ShortDescription = updatedMedia.ShortDescription; + media.LongDescription = updatedMedia.LongDescription; + + await db.SaveChangesAsync(); + await transaction.CommitAsync(); + + return Ok(); + } + + [HttpPost] + public IActionResult Upload() { + if(Request.Form.Files.Count == 0) + return BadRequest("No files"); + if(Request.Form.Files.Count > 1) + return BadRequest("More than one file supplied"); + + var metadataString = Request.Form.Files + .First() + .Headers["X-HyperBooru-Metadata"] + .ElementAtOrDefault(0); + + MediaUploadRequest? metadata = metadataString is null ? null : + JsonSerializer.Deserialize(metadataString); + + var formFile = Request.Form.Files.First(); + + var media = mediaService.Create( + formFile.OpenReadStream(), + formFile.FileName, + metadata?.Checksum, + metadata?.LastAccessTime, + metadata?.LastWriteTime, + metadata?.CreateTime, + metadata?.Path, + metadata?.PathType, + metadata?.Tags); + + return Ok((ApiModels.Media) media); + } + + [HttpDelete("{mediaId}")] + public void Delete([FromRoute] Guid mediaId) => + mediaService.Delete(mediaId); +} diff --git a/Controllers/ApiTagController.cs b/Controllers/ApiTagController.cs new file mode 100644 index 0000000..afd5b05 --- /dev/null +++ b/Controllers/ApiTagController.cs @@ -0,0 +1,36 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace HyperBooru.Controllers; + +[ApiController] +[Route("/api/tag")] +public class ApiTagController : Controller { + private IDbContextFactory dbFactory; + + public ApiTagController(IDbContextFactory dbFactory) => + this.dbFactory = dbFactory; + + [HttpGet("definition")] + public async Task GetAllTagDefinitionsAsync() { + using var db = dbFactory.CreateDbContext(); + + var definitions = await db.TagDefinitions + .Include(td => td.ImplicitTags) + .Select(td => (ApiModels.TagDefinition)td) + .ToArrayAsync(); + + return Ok(definitions); + } + + [HttpGet("definition/{tagDefinitionId}")] + public async Task GetTagDefinitionAsync([FromRoute] Guid tagDefinitionId) { + using var db = dbFactory.CreateDbContext(); + + var tagDefinition = await db.TagDefinitions + .Include(td => td.ImplicitTags) + .FirstOrDefaultAsync(td => td.Guid == tagDefinitionId); + + return tagDefinition is not null ? Ok(tagDefinition) : NotFound(); + } +} diff --git a/Controllers/LoginController.cs b/Controllers/LoginController.cs index b01553c..c93f0d5 100644 --- a/Controllers/LoginController.cs +++ b/Controllers/LoginController.cs @@ -1,7 +1,6 @@ using HyperBooru.Services; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Cryptography.KeyDerivation; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; diff --git a/Controllers/MediaController.cs b/Controllers/MediaController.cs index 7eb46c6..96ecb44 100644 --- a/Controllers/MediaController.cs +++ b/Controllers/MediaController.cs @@ -1,4 +1,5 @@ -using HyperBooru.Services; +using HyperBooru.ApiModels; +using HyperBooru.Services; using HyperBooru.Util; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -- cgit v1.3