summary refs log tree commit diff
path: root/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs
diff options
context:
space:
mode:
Diffstat (limited to 'extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs')
-rw-r--r--extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs96
1 files changed, 95 insertions, 1 deletions
diff --git a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs

index 1102bec2..95998151 100644 --- a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs +++ b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs
@@ -1,6 +1,11 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text.Json; +using System.Text.Json.Serialization; +using ArcaneLibs.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Spacebar.DataMappings.Generic; using Spacebar.GatewayOffload.Extensions.Db; using Spacebar.Interop.Authentication.AspNetCore; using Spacebar.Interop.Replication.Abstractions; @@ -29,13 +34,87 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen yield break; } + var memberList = new List<IMemberListEntry>(); + // Fetch hoisted roles for the guild to define groups var hoistedRoles = await db.Roles .AsNoTracking() .Where(r => r.GuildId == payload.GuildId && r.Hoist) .OrderByDescending(r => r.Position) - .Select(r => new { r.Id }) + // .Select(r => r.Id) .ToListAsync(); + + logger.LogDebug("Got hoisted roles: {roleIds}", hoistedRoles.Select(x => x.Id).ToList()); + List<long> handledRoles = []; + foreach (var roleObj in hoistedRoles) { + var role = roleObj.Id; + var members = await db.Members.AsNoTracking() + .Include(x => x.IdNavigation) + .Where(x => + x.GuildId == payload.GuildId + && x.Roles.Any(r => r.Id == role) + && !x.Roles.Any(r => handledRoles.Contains(r.Id)) + // and finally, filter by online + && x.IdNavigation.Sessions.Any(s => s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown") + ) + .OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync(); + + logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}", + members.Count, role, roleObj.Name, string.Join("\n - ", members.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}")) + ); + + memberList.Add(new RoleEntry() { Id = role.ToString(), Count = members.Count }); + memberList.AddRange(members.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() })); + + handledRoles.Add(role); + } + + // online members + var onlineMembers = await db.Members.AsNoTracking() + .Include(x => x.IdNavigation) + // .ThenInclude(x=>x.Sessions) + .Where(x => + x.GuildId == payload.GuildId + && !x.Roles.Any(r => handledRoles.Contains(r.Id)) + // and finally, filter by online + && x.IdNavigation.Sessions.Any(s => s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown") + ) + .OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync(); + + logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}", + onlineMembers.Count, "online", "online", string.Join("\n - ", onlineMembers.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}")) + ); + + if (onlineMembers.Count > 0) { + memberList.Add(new RoleEntry() { Id = "online", Count = onlineMembers.Count }); + memberList.AddRange(onlineMembers.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() })); + } + + + if (memberList.Count < 2000) { + logger.LogInformation("Less than 2000 members, including offline members..."); + var offlineMembers = await db.Members.AsNoTracking() + .Include(x => x.IdNavigation) + // .ThenInclude(x=>x.Sessions) + .Where(x => + x.GuildId == payload.GuildId + && !x.Roles.Any(r => handledRoles.Contains(r.Id)) + // and finally, filter by online + && (x.IdNavigation.Sessions.Any(s => s.Status == "offline" || s.Status == "invisible" || s.Status == "unknown") || !x.IdNavigation.Sessions.Any()) + ) + .OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync(); + + logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}", + offlineMembers.Count, "offline", "offline", string.Join("\n - ", offlineMembers.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}")) + ); + + if (offlineMembers.Count > 0) { + memberList.Add(new RoleEntry() { Id = "offline", Count = offlineMembers.Count }); + memberList.AddRange(offlineMembers.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() })); + } + } + + logger.LogInformation("Got member list with {count} total nodes", memberList.Count); } private async Task<string?> GetMemberListIdAsync(SpacebarDbContext db, long guildId, long channelId) { @@ -48,4 +127,19 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen return null; // TODO } +} + +internal interface IMemberListEntry { } + +internal struct RoleEntry : IMemberListEntry { + [JsonPropertyName("id"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public string Id { get; set; } + + [JsonPropertyName("count")] + public int Count { get; set; } +} + +internal struct MemberEntry : IMemberListEntry { + [JsonPropertyName("member")] + public Member Member { get; set; } } \ No newline at end of file