[backend/database] Add entity methods for getting the public url/uri for users & notes (ISH-47)

This commit is contained in:
Laura Hausmann 2024-02-16 02:56:42 +01:00
parent aff1f6e788
commit 9496d81abe
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
9 changed files with 39 additions and 19 deletions

View file

@ -20,7 +20,7 @@ public class NoteRenderer(
List<Attachment>? attachments = null, Dictionary<string, int>? likeCounts = null,
List<string>? likedNotes = null, int recurse = 2
) {
var uri = note.Uri ?? $"https://{config.Value.WebDomain}/notes/{note.Id}";
var uri = note.Uri ?? note.GetPublicUri(config.Value);
var renote = note.Renote != null && recurse > 0
? await RenderAsync(note.Renote, user, accounts, mentions, attachments, likeCounts, likedNotes, --recurse)
: null;

View file

@ -18,7 +18,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, MfmConverter
var res = new Account {
Id = user.Id,
DisplayName = user.DisplayName ?? user.Username,
AvatarUrl = user.AvatarUrl ?? $"https://{config.Value.WebDomain}/identicon/{user.Id}",
AvatarUrl = user.AvatarUrl ?? user.GetIdenticonUrl(config.Value),
Username = user.Username,
Acct = acct,
FullyQualifiedName = $"{user.Username}@{user.Host ?? config.Value.AccountDomain}",
@ -28,8 +28,8 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, MfmConverter
FollowingCount = user.FollowingCount,
StatusesCount = user.NotesCount,
Note = await mfmConverter.ToHtmlAsync(profile?.Description ?? "", [], user.Host),
Url = profile?.Url ?? user.Uri ?? $"https://{user.Host ?? config.Value.WebDomain}/@{user.Username}",
AvatarStaticUrl = user.AvatarUrl ?? $"https://{config.Value.WebDomain}/identicon/{user.Id}", //TODO
Url = profile?.Url ?? user.Uri ?? user.GetPublicUrl(config.Value),
AvatarStaticUrl = user.AvatarUrl ?? user.GetIdenticonUrl(config.Value), //TODO
HeaderUrl = user.BannerUrl ?? _transparent,
HeaderStaticUrl = user.BannerUrl ?? _transparent, //TODO
MovedToAccount = null, //TODO

View file

@ -21,9 +21,9 @@ public class Mention() {
Username = u.Username;
Host = u.Host;
Acct = u.Acct;
Uri = u.Uri ?? $"https://{webDomain}/users/{u.Id}";
Uri = u.Uri ?? u.GetPublicUri(webDomain);
Url = u.UserProfile != null
? u.UserProfile.Url ?? u.Uri ?? $"https://{webDomain}/@{u.Username}"
: u.Uri ?? $"https://{webDomain}/@{u.Username}";
? u.UserProfile.Url ?? u.Uri ?? u.GetPublicUrl(webDomain)
: u.Uri ?? u.GetPublicUri(webDomain);
}
}

View file

@ -49,12 +49,12 @@ public class WellKnownController(IOptions<Config.InstanceSection> config, Databa
new WebFingerLink {
Rel = "self",
Type = "application/activity+json",
Href = $"https://{config.Value.WebDomain}/users/{user.Id}"
Href = user.GetPublicUri(config.Value)
},
new WebFingerLink {
Rel = "http://webfinger.net/rel/profile-page",
Type = "text/html",
Href = $"https://{config.Value.WebDomain}/@{user.Username}"
Href = user.GetPublicUri(config.Value)
},
new WebFingerLink {
Rel = "http://ostatus.org/schema/1.0/subscribe",

View file

@ -2,6 +2,7 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
using EntityFrameworkCore.Projectables;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Helpers;
using Microsoft.EntityFrameworkCore;
using NpgsqlTypes;
@ -276,6 +277,10 @@ public class Note : IEntity {
return this;
}
public string GetPublicUri(Config.InstanceSection config) => UserHost == null
? $"https://{config.WebDomain}/notes/{Id}"
: throw new Exception("Cannot access PublicUri for remote note");
public class MentionedUser {
[J("uri")] public required string Uri { get; set; }

View file

@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using EntityFrameworkCore.Projectables;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Helpers;
using Microsoft.EntityFrameworkCore;
@ -381,7 +382,7 @@ public class User : IEntity {
[InverseProperty(nameof(NoteBookmark.User))]
public virtual ICollection<NoteBookmark> NoteBookmarks { get; set; } = new List<NoteBookmark>();
[InverseProperty(nameof(NoteReaction.User))]
public virtual ICollection<NoteLike> NoteLikes { get; set; } = new List<NoteLike>();
@ -550,4 +551,18 @@ public class User : IEntity {
return this;
}
public string GetPublicUrl(Config.InstanceSection config) => GetPublicUrl(config.WebDomain);
public string GetPublicUri(Config.InstanceSection config) => GetPublicUri(config.WebDomain);
public string GetIdenticonUrl(Config.InstanceSection config) => GetIdenticonUrl(config.WebDomain);
public string GetPublicUri(string webDomain) => Host == null
? $"https://{webDomain}/users/{Id}"
: throw new Exception("Cannot access PublicUri for remote user");
public string GetPublicUrl(string webDomain) => Host == null
? $"https://{webDomain}/@{Username}"
: throw new Exception("Cannot access PublicUrl for remote user");
public string GetIdenticonUrl(string webDomain) => $"https://{webDomain}/identicon/{Id}";
}

View file

@ -17,15 +17,15 @@ public class NoteRenderer(IOptions<Config.InstanceSection> config, MfmConverter
/// <returns>ASNote with only the Id field populated</returns>
public ASNote RenderLite(Note note) {
return new ASNote {
Id = note.Uri ?? $"https://{config.Value.WebDomain}/notes/{note.Id}"
Id = note.Uri ?? note.GetPublicUri(config.Value)
};
}
public async Task<ASNote> RenderAsync(Note note, List<Note.MentionedUser>? mentions = null) {
var id = $"https://{config.Value.WebDomain}/notes/{note.Id}";
var userId = $"https://{config.Value.WebDomain}/users/{note.User.Id}";
var id = note.GetPublicUri(config.Value);
var userId = note.User.GetPublicUri(config.Value);
var replyId = note.Reply != null
? new ASObjectBase(note.Reply.Uri ?? $"https://{config.Value.WebDomain}/notes/{note.ReplyId}")
? new ASObjectBase(note.Reply.Uri ?? note.Reply.GetPublicUri(config.Value))
: null;
mentions ??= await db.Users
@ -35,7 +35,7 @@ public class NoteRenderer(IOptions<Config.InstanceSection> config, MfmConverter
Host = p.Host ?? config.Value.AccountDomain,
Username = p.Username,
Url = p.UserProfile != null ? p.UserProfile.Url : null,
Uri = p.Uri ?? $"https://{config.Value.WebDomain}/users/{p.Id}"
Uri = p.Uri ?? p.GetPublicUri(config.Value)
})
.ToListAsync();

View file

@ -24,7 +24,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
}
return new ASActor {
Id = $"https://{config.Value.WebDomain}/users/{user.Id}"
Id = user.GetPublicUri(config.Value)
};
}
@ -40,7 +40,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
if (keypair == null) throw new GracefulException("User has no keypair");
var id = $"https://{config.Value.WebDomain}/users/{user.Id}";
var id = user.GetPublicUri(config.Value);
var type = Constants.SystemUsers.Contains(user.UsernameLower)
? "Application"
: user.IsBot
@ -55,7 +55,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
Followers = new ASCollection<ASObject>($"{id}/followers"),
Following = new ASCollection<ASObject>($"{id}/following"),
SharedInbox = new ASLink($"https://{config.Value.WebDomain}/inbox"),
Url = new ASLink($"https://{config.Value.WebDomain}/@{user.Username}"),
Url = new ASLink(user.GetPublicUrl(config.Value)),
Username = user.Username,
DisplayName = user.DisplayName ?? user.Username,
Summary = profile?.Description != null ? await mfmConverter.FromHtmlAsync(profile.Description) : null,

View file

@ -277,7 +277,7 @@ public class NoteService(
var localMentions = localUsers.Select(p => new Note.MentionedUser {
Host = config.Value.AccountDomain,
Username = p.Username,
Uri = $"https://{config.Value.WebDomain}/users/{p.Id}",
Uri = p.GetPublicUri(config.Value),
Url = $"https://{config.Value.WebDomain}/@{p.Username}"
});