♻️ Refactor the pub delivery service
This commit is contained in:
@@ -61,15 +61,14 @@ public class ActivityPubDeliveryService(
|
|||||||
string targetActorUri
|
string targetActorUri
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var publisher = await db.Publishers.FindAsync(publisherId);
|
var localActor = await GetLocalActorAsync(publisherId);
|
||||||
if (publisher == null)
|
if (localActor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
|
var actorUrl = localActor.Uri;
|
||||||
var targetActor = await GetOrFetchActorAsync(targetActorUri);
|
var targetActor = await GetOrFetchActorAsync(targetActorUri);
|
||||||
var localActor = await GetLocalActorAsync(publisher.Id);
|
|
||||||
|
|
||||||
if (targetActor?.InboxUri == null || localActor == null)
|
if (targetActor?.InboxUri == null)
|
||||||
{
|
{
|
||||||
logger.LogWarning("Target actor or inbox not found: {Uri}", targetActorUri);
|
logger.LogWarning("Target actor or inbox not found: {Uri}", targetActorUri);
|
||||||
return false;
|
return false;
|
||||||
@@ -114,15 +113,14 @@ public class ActivityPubDeliveryService(
|
|||||||
string targetActorUri
|
string targetActorUri
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var publisher = await db.Publishers.FindAsync(publisherId);
|
var localActor = await GetLocalActorAsync(publisherId);
|
||||||
if (publisher == null)
|
if (localActor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
|
var actorUrl = localActor.Uri;
|
||||||
var targetActor = await GetOrFetchActorAsync(targetActorUri);
|
var targetActor = await GetOrFetchActorAsync(targetActorUri);
|
||||||
var localActor = await GetLocalActorAsync(publisher.Id);
|
|
||||||
|
|
||||||
if (targetActor?.InboxUri == null || localActor == null)
|
if (targetActor?.InboxUri == null)
|
||||||
{
|
{
|
||||||
logger.LogWarning("Target actor or inbox not found: {Uri}", targetActorUri);
|
logger.LogWarning("Target actor or inbox not found: {Uri}", targetActorUri);
|
||||||
return false;
|
return false;
|
||||||
@@ -158,11 +156,13 @@ public class ActivityPubDeliveryService(
|
|||||||
|
|
||||||
public async Task<bool> SendCreateActivityAsync(SnPost post)
|
public async Task<bool> SendCreateActivityAsync(SnPost post)
|
||||||
{
|
{
|
||||||
var publisher = await db.Publishers.FindAsync(post.PublisherId);
|
if (post.PublisherId == null)
|
||||||
if (publisher == null)
|
return false;
|
||||||
|
var localActor = await GetLocalActorAsync(post.PublisherId.Value);
|
||||||
|
if (localActor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
|
var actorUrl = localActor.Uri;
|
||||||
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
||||||
|
|
||||||
var activity = new Dictionary<string, object>
|
var activity = new Dictionary<string, object>
|
||||||
@@ -211,11 +211,13 @@ public class ActivityPubDeliveryService(
|
|||||||
|
|
||||||
public async Task<bool> SendUpdateActivityAsync(SnPost post)
|
public async Task<bool> SendUpdateActivityAsync(SnPost post)
|
||||||
{
|
{
|
||||||
var publisher = await db.Publishers.FindAsync(post.PublisherId);
|
if (post.PublisherId == null)
|
||||||
if (publisher == null)
|
return false;
|
||||||
|
var localActor = await GetLocalActorAsync(post.PublisherId.Value);
|
||||||
|
if (localActor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
|
var actorUrl = localActor.Uri;
|
||||||
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
||||||
|
|
||||||
var activity = new Dictionary<string, object>
|
var activity = new Dictionary<string, object>
|
||||||
@@ -265,11 +267,13 @@ public class ActivityPubDeliveryService(
|
|||||||
|
|
||||||
public async Task<bool> SendDeleteActivityAsync(SnPost post)
|
public async Task<bool> SendDeleteActivityAsync(SnPost post)
|
||||||
{
|
{
|
||||||
var publisher = await db.Publishers.FindAsync(post.PublisherId);
|
if (post.PublisherId == null)
|
||||||
if (publisher == null)
|
return false;
|
||||||
|
var localActor = await GetLocalActorAsync(post.PublisherId.Value);
|
||||||
|
if (localActor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actorUrl = $"https://{Domain}/activitypub/actors/{publisher.Name}";
|
var actorUrl = localActor.Uri;
|
||||||
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
var postUrl = $"https://{Domain}/posts/{post.Id}";
|
||||||
|
|
||||||
var activity = new Dictionary<string, object>
|
var activity = new Dictionary<string, object>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public partial class PostService(
|
|||||||
Publisher.PublisherService ps,
|
Publisher.PublisherService ps,
|
||||||
WebReaderService reader,
|
WebReaderService reader,
|
||||||
AccountService.AccountServiceClient accounts,
|
AccountService.AccountServiceClient accounts,
|
||||||
ActivityPub.ActivityPubDeliveryService activityPubDeliveryService
|
ActivityPubDeliveryService apDelivery
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
private const string PostFileUsageIdentifier = "post";
|
private const string PostFileUsageIdentifier = "post";
|
||||||
@@ -187,7 +187,7 @@ public partial class PostService(
|
|||||||
Notification = new PushNotification
|
Notification = new PushNotification
|
||||||
{
|
{
|
||||||
Topic = "post.replies",
|
Topic = "post.replies",
|
||||||
Title = localizer["PostReplyTitle", sender.Nick],
|
Title = localizer["PostReplyTitle", sender!.Nick],
|
||||||
Body = string.IsNullOrWhiteSpace(post.Title)
|
Body = string.IsNullOrWhiteSpace(post.Title)
|
||||||
? localizer["PostReplyBody", sender.Nick, ChopPostForNotification(post).content]
|
? localizer["PostReplyBody", sender.Nick, ChopPostForNotification(post).content]
|
||||||
: localizer["PostReplyContentBody", sender.Nick, post.Title,
|
: localizer["PostReplyContentBody", sender.Nick, post.Title,
|
||||||
@@ -329,7 +329,7 @@ public partial class PostService(
|
|||||||
[GeneratedRegex(@"https?://(?!.*\.\w{1,6}(?:[#?]|$))[^\s]+", RegexOptions.IgnoreCase)]
|
[GeneratedRegex(@"https?://(?!.*\.\w{1,6}(?:[#?]|$))[^\s]+", RegexOptions.IgnoreCase)]
|
||||||
private static partial Regex GetLinkRegex();
|
private static partial Regex GetLinkRegex();
|
||||||
|
|
||||||
public async Task<SnPost> PreviewPostLinkAsync(SnPost item)
|
private async Task<SnPost> PreviewPostLinkAsync(SnPost item)
|
||||||
{
|
{
|
||||||
if (item.Type != Shared.Models.PostType.Moment || string.IsNullOrEmpty(item.Content)) return item;
|
if (item.Type != Shared.Models.PostType.Moment || string.IsNullOrEmpty(item.Content)) return item;
|
||||||
|
|
||||||
@@ -586,7 +586,7 @@ public partial class PostService(
|
|||||||
// Send ActivityPub Like/Undo activities if post's publisher has actor
|
// Send ActivityPub Like/Undo activities if post's publisher has actor
|
||||||
if (post.PublisherId.HasValue && reaction.AccountId.HasValue)
|
if (post.PublisherId.HasValue && reaction.AccountId.HasValue)
|
||||||
{
|
{
|
||||||
var publisherActor = await activityPubDeliveryService.GetLocalActorAsync(post.PublisherId.Value);
|
var publisherActor = await apDelivery.GetLocalActorAsync(post.PublisherId.Value);
|
||||||
|
|
||||||
if (publisherActor != null && reaction.Attitude == Shared.Models.PostReactionAttitude.Positive)
|
if (publisherActor != null && reaction.Attitude == Shared.Models.PostReactionAttitude.Positive)
|
||||||
{
|
{
|
||||||
@@ -716,7 +716,7 @@ public partial class PostService(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<Guid, Dictionary<string, bool>>> GetPostReactionMadeMapBatch(List<Guid> postIds,
|
private async Task<Dictionary<Guid, Dictionary<string, bool>>> GetPostReactionMadeMapBatch(List<Guid> postIds,
|
||||||
Guid accountId)
|
Guid accountId)
|
||||||
{
|
{
|
||||||
var reactions = await db.Set<SnPostReaction>()
|
var reactions = await db.Set<SnPostReaction>()
|
||||||
@@ -769,7 +769,7 @@ public partial class PostService(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<SnPost>> LoadPublishers(List<SnPost> posts)
|
private async Task<List<SnPost>> LoadPublishersAndActors(List<SnPost> posts)
|
||||||
{
|
{
|
||||||
var publisherIds = posts
|
var publisherIds = posts
|
||||||
.SelectMany<SnPost, Guid?>(e =>
|
.SelectMany<SnPost, Guid?>(e =>
|
||||||
@@ -781,24 +781,49 @@ public partial class PostService(
|
|||||||
.Where(e => e != null)
|
.Where(e => e != null)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToList();
|
.ToList();
|
||||||
if (publisherIds.Count == 0) return posts;
|
var actorIds = posts
|
||||||
|
.SelectMany<SnPost, Guid?>(e =>
|
||||||
|
[
|
||||||
|
e.ActorId,
|
||||||
|
e.RepliedPost?.ActorId,
|
||||||
|
e.ForwardedPost?.ActorId
|
||||||
|
])
|
||||||
|
.Where(e => e != null)
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
if (publisherIds.Count == 0 && actorIds.Count == 0) return posts;
|
||||||
|
|
||||||
var publishers = await db.Publishers
|
var publishers = await db.Publishers
|
||||||
.Where(e => publisherIds.Contains(e.Id))
|
.Where(e => publisherIds.Contains(e.Id))
|
||||||
.ToDictionaryAsync(e => e.Id);
|
.ToDictionaryAsync(e => e.Id);
|
||||||
|
|
||||||
|
var actors = await db.FediverseActors
|
||||||
|
.Where(e => actorIds.Contains(e.Id))
|
||||||
|
.ToDictionaryAsync(e => e.Id);
|
||||||
|
|
||||||
foreach (var post in posts)
|
foreach (var post in posts)
|
||||||
{
|
{
|
||||||
if (post.PublisherId.HasValue && publishers.TryGetValue(post.PublisherId.Value, out var publisher))
|
if (post.PublisherId.HasValue && publishers.TryGetValue(post.PublisherId.Value, out var publisher))
|
||||||
post.Publisher = publisher;
|
post.Publisher = publisher;
|
||||||
|
|
||||||
|
if (post.ActorId.HasValue && actors.TryGetValue(post.ActorId.Value, out var actor))
|
||||||
|
post.Actor = actor;
|
||||||
|
|
||||||
if (post.RepliedPost?.PublisherId != null &&
|
if (post.RepliedPost?.PublisherId != null &&
|
||||||
publishers.TryGetValue(post.RepliedPost.PublisherId.Value, out var repliedPublisher))
|
publishers.TryGetValue(post.RepliedPost.PublisherId.Value, out var repliedPublisher))
|
||||||
post.RepliedPost.Publisher = repliedPublisher;
|
post.RepliedPost.Publisher = repliedPublisher;
|
||||||
|
|
||||||
|
if (post.RepliedPost?.ActorId != null &&
|
||||||
|
actors.TryGetValue(post.RepliedPost.ActorId.Value, out var repliedActor))
|
||||||
|
post.RepliedPost.Actor = repliedActor;
|
||||||
|
|
||||||
if (post.ForwardedPost?.PublisherId != null &&
|
if (post.ForwardedPost?.PublisherId != null &&
|
||||||
publishers.TryGetValue(post.ForwardedPost.PublisherId.Value, out var forwardedPublisher))
|
publishers.TryGetValue(post.ForwardedPost.PublisherId.Value, out var forwardedPublisher))
|
||||||
post.ForwardedPost.Publisher = forwardedPublisher;
|
post.ForwardedPost.Publisher = forwardedPublisher;
|
||||||
|
|
||||||
|
if (post.ForwardedPost?.ActorId != null &&
|
||||||
|
actors.TryGetValue(post.ForwardedPost.ActorId.Value, out var forwardedActor))
|
||||||
|
post.ForwardedPost.Actor = forwardedActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ps.LoadIndividualPublisherAccounts(publishers.Values);
|
await ps.LoadIndividualPublisherAccounts(publishers.Values);
|
||||||
@@ -806,7 +831,7 @@ public partial class PostService(
|
|||||||
return posts;
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<SnPost>> LoadInteractive(List<SnPost> posts, Account? currentUser = null)
|
private async Task<List<SnPost>> LoadInteractive(List<SnPost> posts, Account? currentUser = null)
|
||||||
{
|
{
|
||||||
if (posts.Count == 0) return posts;
|
if (posts.Count == 0) return posts;
|
||||||
|
|
||||||
@@ -842,9 +867,7 @@ public partial class PostService(
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
// Set reply count
|
// Set reply count
|
||||||
post.RepliesCount = repliesCountMap.TryGetValue(post.Id, out var repliesCount)
|
post.RepliesCount = repliesCountMap.GetValueOrDefault(post.Id, 0);
|
||||||
? repliesCount
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
// Check visibility for replied post
|
// Check visibility for replied post
|
||||||
if (post.RepliedPost != null)
|
if (post.RepliedPost != null)
|
||||||
@@ -929,7 +952,7 @@ public partial class PostService(
|
|||||||
{
|
{
|
||||||
if (posts.Count == 0) return posts;
|
if (posts.Count == 0) return posts;
|
||||||
|
|
||||||
posts = await LoadPublishers(posts);
|
posts = await LoadPublishersAndActors(posts);
|
||||||
posts = await LoadInteractive(posts, currentUser);
|
posts = await LoadInteractive(posts, currentUser);
|
||||||
|
|
||||||
if (truncate)
|
if (truncate)
|
||||||
@@ -954,7 +977,7 @@ public partial class PostService(
|
|||||||
|
|
||||||
if (featuredIds is null)
|
if (featuredIds is null)
|
||||||
{
|
{
|
||||||
// The previous day highest rated posts
|
// The previous day the highest rated posts
|
||||||
var today = SystemClock.Instance.GetCurrentInstant();
|
var today = SystemClock.Instance.GetCurrentInstant();
|
||||||
var periodStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant()
|
var periodStart = today.InUtc().Date.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant()
|
||||||
.Minus(Duration.FromDays(1));
|
.Minus(Duration.FromDays(1));
|
||||||
@@ -994,8 +1017,8 @@ public partial class PostService(
|
|||||||
{
|
{
|
||||||
PostId = postId,
|
PostId = postId,
|
||||||
Count =
|
Count =
|
||||||
(reactionScores.TryGetValue(postId, out var rScore) ? rScore : 0)
|
(reactionScores.GetValueOrDefault(postId, 0))
|
||||||
+ (repliesCounts.TryGetValue(postId, out var repCount) ? repCount : 0)
|
+ (repliesCounts.GetValueOrDefault(postId, 0))
|
||||||
+ (awardsScores.TryGetValue(postId, out var awardScore) ? (int)(awardScore / 10) : 0)
|
+ (awardsScores.TryGetValue(postId, out var awardScore) ? (int)(awardScore / 10) : 0)
|
||||||
})
|
})
|
||||||
.OrderByDescending(e => e.Count)
|
.OrderByDescending(e => e.Count)
|
||||||
|
|||||||
Reference in New Issue
Block a user