✨ Rewind service basis and sphere service rewind
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
namespace DysonNetwork.Pass.Account.Rewind;
|
||||
|
||||
public class AccountRewindController
|
||||
{
|
||||
|
||||
}
|
||||
6
DysonNetwork.Pass/Account/Rewind/AccountRewindService.cs
Normal file
6
DysonNetwork.Pass/Account/Rewind/AccountRewindService.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace DysonNetwork.Pass.Account.Rewind;
|
||||
|
||||
public class AccountRewindService(AppDatabase db)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -63,6 +63,8 @@ public class AppDatabase(
|
||||
|
||||
public DbSet<SnAffiliationSpell> AffiliationSpells { get; set; } = null!;
|
||||
public DbSet<SnAffiliationResult> AffiliationResults { get; set; } = null!;
|
||||
|
||||
public DbSet<SnRewindPoint> RewindPoints { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
|
||||
14
DysonNetwork.Shared/Models/SnRewindPoint.cs
Normal file
14
DysonNetwork.Shared/Models/SnRewindPoint.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
|
||||
public class SnRewindPoint
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public int Year { get; set; } = DateTime.UtcNow.Year;
|
||||
|
||||
[Column(TypeName = "jsonb")] public Dictionary<string, string> Data { get; set; } = new();
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
public SnAccount Account { get; set; } = null!;
|
||||
}
|
||||
19
DysonNetwork.Shared/Proto/rewind.proto
Normal file
19
DysonNetwork.Shared/Proto/rewind.proto
Normal file
@@ -0,0 +1,19 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
|
||||
option csharp_namespace = "DysonNetwork.Shared.Proto";
|
||||
|
||||
message RewindEvent {
|
||||
string account_id = 1;
|
||||
optional bytes data = 2;
|
||||
string service_id = 3;
|
||||
}
|
||||
|
||||
message RequestRewindEvent {
|
||||
string account_id = 1;
|
||||
}
|
||||
|
||||
service RewindService {
|
||||
rpc GetRewindEvent(RequestRewindEvent) returns (RewindEvent) {}
|
||||
}
|
||||
@@ -20,6 +20,14 @@ public class PublisherService(
|
||||
RemoteAccountService remoteAccounts
|
||||
)
|
||||
{
|
||||
public async Task<SnPublisher?> GetPublisherLoaded(Guid id)
|
||||
{
|
||||
var publisher = await db.Publishers
|
||||
.Where(p => p.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
return publisher is null ? null : (await LoadIndividualPublisherAccounts([publisher])).First();
|
||||
}
|
||||
|
||||
public async Task<SnPublisher?> GetPublisherByName(string name)
|
||||
{
|
||||
return await db.Publishers
|
||||
@@ -453,7 +461,7 @@ public class PublisherService(
|
||||
public async Task<List<SnPublisher>> LoadIndividualPublisherAccounts(ICollection<SnPublisher> publishers)
|
||||
{
|
||||
var accountIds = publishers
|
||||
.Where(p => p.AccountId.HasValue && p.Type == PublisherType.Individual)
|
||||
.Where(p => p is { AccountId: not null, Type: PublisherType.Individual })
|
||||
.Select(p => p.AccountId!.Value)
|
||||
.ToList();
|
||||
if (accountIds.Count == 0) return publishers.ToList();
|
||||
@@ -638,7 +646,7 @@ public class PublisherService(
|
||||
|
||||
if (!publisherAccounts.TryGetValue(publisherId, out var receivers) || receivers.Count == 0)
|
||||
continue;
|
||||
|
||||
|
||||
var publisherName = publishers.TryGetValue(publisherId, out var pub) ? pub.Name : "unknown";
|
||||
|
||||
// Set social credit for receivers, expired before next settle
|
||||
|
||||
97
DysonNetwork.Sphere/Rewind/SphereRewindServiceGrpc.cs
Normal file
97
DysonNetwork.Sphere/Rewind/SphereRewindServiceGrpc.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.Globalization;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Grpc.Core;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DysonNetwork.Sphere.Rewind;
|
||||
|
||||
public class SphereRewindServiceGrpc(
|
||||
AppDatabase db,
|
||||
RemoteAccountService remoteAccounts,
|
||||
Publisher.PublisherService ps
|
||||
) : RewindService.RewindServiceBase
|
||||
{
|
||||
public override async Task<RewindEvent> GetRewindEvent(RequestRewindEvent request, ServerCallContext context)
|
||||
{
|
||||
var accountId = Guid.Parse(request.AccountId);
|
||||
|
||||
// Audience data
|
||||
var mostLovedPublisherClue =
|
||||
await db.PostReactions
|
||||
.Where(p => p.AccountId == accountId && p.Attitude == Shared.Models.PostReactionAttitude.Positive)
|
||||
.GroupBy(p => p.Post.PublisherId)
|
||||
.OrderByDescending(g => g.Count())
|
||||
.Select(g => new { PublisherId = g.Key, ReactionCount = g.Count() })
|
||||
.FirstOrDefaultAsync();
|
||||
var mostLovedPublisher = mostLovedPublisherClue is not null
|
||||
? ps.GetPublisherLoaded(mostLovedPublisherClue.PublisherId)
|
||||
: null;
|
||||
|
||||
// Creator data
|
||||
var publishers = await db.PublisherMembers
|
||||
.Where(pm => pm.AccountId == accountId)
|
||||
.Select(pm => pm.PublisherId)
|
||||
.ToListAsync();
|
||||
|
||||
var mostLovedAudienceClue =
|
||||
await db.PostReactions
|
||||
.Where(pr =>
|
||||
pr.Attitude == Shared.Models.PostReactionAttitude.Positive &&
|
||||
publishers.Contains(pr.Post.PublisherId))
|
||||
.GroupBy(pr => pr.AccountId)
|
||||
.OrderByDescending(g => g.Count())
|
||||
.Select(g => new { AccountId = g.Key, ReactionCount = g.Count() })
|
||||
.FirstOrDefaultAsync();
|
||||
var mostLovedAudience = mostLovedAudienceClue is not null
|
||||
? await remoteAccounts.GetAccount(mostLovedAudienceClue.AccountId)
|
||||
: null;
|
||||
|
||||
var posts = await db.Posts
|
||||
.Where(p => publishers.Contains(p.PublisherId))
|
||||
.ToListAsync();
|
||||
var postTotalCount = posts.Count;
|
||||
var mostPopularPost = posts
|
||||
.OrderByDescending(p => p.Upvotes - p.Downvotes)
|
||||
.FirstOrDefault();
|
||||
var mostProductiveDay = posts
|
||||
.GroupBy(p => p.CreatedAt.ToDateTimeUtc().Date)
|
||||
.OrderByDescending(g => g.Count())
|
||||
.Select(g => new { Date = g.Key, PostCount = g.Count() })
|
||||
.FirstOrDefault();
|
||||
|
||||
var data = new Dictionary<string, object?>
|
||||
{
|
||||
["total_count"] = postTotalCount,
|
||||
["most_popular_post"] = mostPopularPost,
|
||||
["most_productive_day"] = mostProductiveDay is not null
|
||||
? new Dictionary<string, object?>
|
||||
{
|
||||
["date"] = mostProductiveDay.Date.ToString(CultureInfo.InvariantCulture),
|
||||
["post_count"] = mostProductiveDay.PostCount,
|
||||
}
|
||||
: null,
|
||||
["most_loved_publisher"] = mostLovedPublisherClue is not null
|
||||
? new Dictionary<string, object?>
|
||||
{
|
||||
["publisher"] = mostLovedPublisher,
|
||||
["upvote_counts"] = mostLovedPublisherClue.ReactionCount,
|
||||
}
|
||||
: null,
|
||||
["most_loved_audience"] = mostLovedAudienceClue is not null
|
||||
? new Dictionary<string, object?>
|
||||
{
|
||||
["account"] = mostLovedAudience,
|
||||
["upvote_counts"] = mostLovedAudienceClue.ReactionCount,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
|
||||
return new RewindEvent
|
||||
{
|
||||
ServiceId = "sphere",
|
||||
AccountId = request.AccountId,
|
||||
Data = GrpcTypeHelper.ConvertObjectToByteString(data)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Http;
|
||||
using DysonNetwork.Sphere.Post;
|
||||
using DysonNetwork.Sphere.Publisher;
|
||||
using DysonNetwork.Sphere.Rewind;
|
||||
|
||||
namespace DysonNetwork.Sphere.Startup;
|
||||
|
||||
@@ -23,6 +24,7 @@ public static class ApplicationConfiguration
|
||||
// Map gRPC services
|
||||
app.MapGrpcService<PostServiceGrpc>();
|
||||
app.MapGrpcService<PublisherServiceGrpc>();
|
||||
app.MapGrpcService<SphereRewindServiceGrpc>();
|
||||
app.MapGrpcReflectionService();
|
||||
|
||||
return app;
|
||||
|
||||
Reference in New Issue
Block a user