Implement basic AP note serializer

This commit is contained in:
Laura Hausmann 2024-01-24 02:21:48 +01:00
parent d6866fe9c2
commit 25c328b02f
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
5 changed files with 35 additions and 19 deletions

View file

@ -13,18 +13,21 @@ namespace Iceshrimp.Backend.Controllers;
[UseNewtonsoftJson]
[MediaTypeRouteFilter("application/activity+json", "application/ld+json")]
[Produces("application/activity+json", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")]
public class ActivityPubController(DatabaseContext db, APUserRenderer userRenderer) : Controller {
/*
public class ActivityPubController(
DatabaseContext db,
UserRenderer userRenderer,
NoteRenderer noteRenderer) : Controller {
[HttpGet("/notes/{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Note))]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ASNote))]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(ErrorResponse))]
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
public async Task<IActionResult> GetNote(string id) {
var note = await db.Notes.FirstOrDefaultAsync(p => p.Id == id);
if (note == null) return NotFound();
return Ok(note);
var rendered = noteRenderer.Render(note);
var compacted = LdHelpers.Compact(rendered);
return Ok(compacted);
}
*/
[HttpGet("/users/{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ASActor))]

View file

@ -1,19 +1,30 @@
using Iceshrimp.Backend.Controllers.Renderers.Entity;
using Iceshrimp.Backend.Controllers.Schemas;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
using Microsoft.Extensions.Options;
namespace Iceshrimp.Backend.Controllers.Renderers.ActivityPub;
public static class ActivityPubNoteRenderer {
public static NoteResponse RenderOne(Note note) {
return new NoteResponse {
Id = note.Id,
Text = note.Text,
User = UserRenderer.RenderOne(note.User)
public class NoteRenderer(IOptions<Config.InstanceSection> config, DatabaseContext db, UserRenderer userRenderer) {
public ASNote Render(Note note) {
var id = $"https://{config.Value.WebDomain}/notes/{note.Id}";
var userId = $"https://{config.Value.WebDomain}/users/{note.User.Id}";
return new ASNote {
Id = id,
Content = note.Text, //FIXME: render to html
AttributedTo = [new LDIdObject(userId)],
Type = "as:Note",
MkContent = note.Text,
PublishedAt = note.CreatedAt,
Sensitive = note.Cw != null,
Source = new ASNoteSource {
Content = note.Text,
MediaType = "text/x.misskeymarkdown"
},
Cc = [new ASLink("https://www.w3.org/ns/activitystreams#Public")],
To = []
};
}
public static IEnumerable<NoteResponse> RenderMany(IEnumerable<Note> notes) {
return notes.Select(RenderOne);
}
}

View file

@ -8,7 +8,7 @@ using Microsoft.Extensions.Options;
namespace Iceshrimp.Backend.Controllers.Renderers.ActivityPub;
public class APUserRenderer(IOptions<Config.InstanceSection> config, DatabaseContext db) {
public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseContext db) {
public async Task<ASActor> Render(User user) {
if (user.Host != null) throw new Exception("Refusing to render remote user");

View file

@ -15,7 +15,8 @@ public static class ServiceExtensions {
services.AddScoped<UserResolver>();
services.AddScoped<UserService>();
services.AddScoped<NoteService>();
services.AddScoped<APUserRenderer>();
services.AddScoped<UserRenderer>();
services.AddScoped<NoteRenderer>();
services.AddScoped<WebFingerService>();
// Singleton = instantiated once across application lifetime

View file

@ -36,5 +36,6 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Iceshrimp/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=misskeymarkdown/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nodeinfo/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=webfinger/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>