[backend/masto-client] Add missing media endpoints, handle media_attributes on status update (ISH-155)
This commit is contained in:
parent
80da86897f
commit
a2075d4c63
5 changed files with 73 additions and 7 deletions
|
@ -2,11 +2,15 @@ using System.Net.Mime;
|
||||||
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
|
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
|
||||||
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
||||||
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
|
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
|
||||||
|
using Iceshrimp.Backend.Core.Database;
|
||||||
|
using Iceshrimp.Backend.Core.Database.Tables;
|
||||||
|
using Iceshrimp.Backend.Core.Extensions;
|
||||||
using Iceshrimp.Backend.Core.Middleware;
|
using Iceshrimp.Backend.Core.Middleware;
|
||||||
using Iceshrimp.Backend.Core.Services;
|
using Iceshrimp.Backend.Core.Services;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Iceshrimp.Backend.Controllers.Mastodon;
|
namespace Iceshrimp.Backend.Controllers.Mastodon;
|
||||||
|
|
||||||
|
@ -17,11 +21,10 @@ namespace Iceshrimp.Backend.Controllers.Mastodon;
|
||||||
[EnableRateLimiting("sliding")]
|
[EnableRateLimiting("sliding")]
|
||||||
[Produces(MediaTypeNames.Application.Json)]
|
[Produces(MediaTypeNames.Application.Json)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AttachmentEntity))]
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AttachmentEntity))]
|
||||||
public class MediaController(DriveService driveSvc) : ControllerBase
|
public class MediaController(DriveService driveSvc, DatabaseContext db) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpPost("/api/v1/media")]
|
[HttpPost("/api/v1/media")]
|
||||||
[HttpPost("/api/v2/media")]
|
[HttpPost("/api/v2/media")]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
|
||||||
public async Task<IActionResult> UploadAttachment(MediaSchemas.UploadMediaRequest request)
|
public async Task<IActionResult> UploadAttachment(MediaSchemas.UploadMediaRequest request)
|
||||||
{
|
{
|
||||||
var user = HttpContext.GetUserOrFail();
|
var user = HttpContext.GetUserOrFail();
|
||||||
|
@ -33,7 +36,40 @@ public class MediaController(DriveService driveSvc) : ControllerBase
|
||||||
MimeType = request.File.ContentType
|
MimeType = request.File.ContentType
|
||||||
};
|
};
|
||||||
var file = await driveSvc.StoreFile(request.File.OpenReadStream(), user, rq);
|
var file = await driveSvc.StoreFile(request.File.OpenReadStream(), user, rq);
|
||||||
var res = new AttachmentEntity
|
var res = RenderAttachment(file);
|
||||||
|
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("/api/v1/media/{id}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
||||||
|
public async Task<IActionResult> UpdateAttachment(string id, [FromHybrid] MediaSchemas.UpdateMediaRequest request)
|
||||||
|
{
|
||||||
|
var user = HttpContext.GetUserOrFail();
|
||||||
|
var file = await db.DriveFiles.FirstOrDefaultAsync(p => p.Id == id && p.User == user) ??
|
||||||
|
throw GracefulException.RecordNotFound();
|
||||||
|
file.Comment = request.Description;
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
var res = RenderAttachment(file);
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("/api/v1/media/{id}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
||||||
|
public async Task<IActionResult> GetAttachment(string id)
|
||||||
|
{
|
||||||
|
var user = HttpContext.GetUserOrFail();
|
||||||
|
var file = await db.DriveFiles.FirstOrDefaultAsync(p => p.Id == id && p.User == user) ??
|
||||||
|
throw GracefulException.RecordNotFound();
|
||||||
|
|
||||||
|
var res = RenderAttachment(file);
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AttachmentEntity RenderAttachment(DriveFile file)
|
||||||
|
{
|
||||||
|
return new AttachmentEntity
|
||||||
{
|
{
|
||||||
Id = file.Id,
|
Id = file.Id,
|
||||||
Type = AttachmentEntity.GetType(file.Type),
|
Type = AttachmentEntity.GetType(file.Type),
|
||||||
|
@ -44,7 +80,5 @@ public class MediaController(DriveService driveSvc) : ControllerBase
|
||||||
RemoteUrl = file.Uri
|
RemoteUrl = file.Uri
|
||||||
//Metadata = TODO
|
//Metadata = TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
||||||
|
using B = Microsoft.AspNetCore.Mvc.BindPropertyAttribute;
|
||||||
|
|
||||||
namespace Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
namespace Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
||||||
|
|
||||||
|
@ -11,4 +13,13 @@ public abstract class MediaSchemas
|
||||||
|
|
||||||
//TODO: add thumbnail & focus properties
|
//TODO: add thumbnail & focus properties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UpdateMediaRequest
|
||||||
|
{
|
||||||
|
[J("description")]
|
||||||
|
[B(Name = "description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
//TODO: add thumbnail & focus properties
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -83,8 +83,15 @@ public abstract class StatusSchemas
|
||||||
[J("media_ids")]
|
[J("media_ids")]
|
||||||
public List<string>? MediaIds { get; set; }
|
public List<string>? MediaIds { get; set; }
|
||||||
|
|
||||||
//TODO: media_attributes
|
[B(Name = "media_attributes")]
|
||||||
|
[J("media_attributes")]
|
||||||
|
public List<MediaAttributesEntry>? MediaAttributes { get; set; }
|
||||||
|
|
||||||
[B(Name = "poll")] [J("poll")] public PostStatusRequest.PollData? Poll { get; set; }
|
[B(Name = "poll")] [J("poll")] public PostStatusRequest.PollData? Poll { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MediaAttributesEntry : MediaSchemas.UpdateMediaRequest
|
||||||
|
{
|
||||||
|
[JR] [J("id")] [B(Name = "id")] public required string Id { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -423,6 +423,18 @@ public class StatusController(
|
||||||
? await db.DriveFiles.Where(p => request.MediaIds.Contains(p.Id)).ToListAsync()
|
? await db.DriveFiles.Where(p => request.MediaIds.Contains(p.Id)).ToListAsync()
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
if (request.MediaAttributes != null)
|
||||||
|
{
|
||||||
|
foreach (var attr in request.MediaAttributes)
|
||||||
|
{
|
||||||
|
var file = attachments.FirstOrDefault(p => p.Id == attr.Id);
|
||||||
|
if (file != null)
|
||||||
|
file.Comment = attr.Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
note = await noteSvc.UpdateNoteAsync(note, request.Text, request.Cw, attachments, poll);
|
note = await noteSvc.UpdateNoteAsync(note, request.Text, request.Cw, attachments, poll);
|
||||||
var res = await noteRenderer.RenderAsync(note, user);
|
var res = await noteRenderer.RenderAsync(note, user);
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,8 @@ public class NoteService(
|
||||||
await ResolveNoteMentionsAsync(text);
|
await ResolveNoteMentionsAsync(text);
|
||||||
if (text != null)
|
if (text != null)
|
||||||
text = mentionsResolver.ResolveMentions(text, null, mentions, splitDomainMapping);
|
text = mentionsResolver.ResolveMentions(text, null, mentions, splitDomainMapping);
|
||||||
|
if (cw != null && string.IsNullOrWhiteSpace(cw))
|
||||||
|
cw = null;
|
||||||
|
|
||||||
mentionedLocalUserIds = mentionedLocalUserIds.Except(previousMentionedLocalUserIds).ToList();
|
mentionedLocalUserIds = mentionedLocalUserIds.Except(previousMentionedLocalUserIds).ToList();
|
||||||
note.Text = text?.Trim();
|
note.Text = text?.Trim();
|
||||||
|
|
Loading…
Add table
Reference in a new issue