diff --git a/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs b/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
index e69de29b..f98d62b7 100644
--- a/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
+++ b/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
@@ -0,0 +1,139 @@
+using System.Text.Json.Serialization;
+
+namespace Spacebar.Models.AdminApi;
+
+public class DiscoverableGuildModel {
+ [JsonPropertyName("id")]
+ public string Id { get; set; } = null!;
+
+ [JsonPropertyName("afk_channel_id")]
+ public string? AfkChannelId { get; set; }
+
+ [JsonPropertyName("afk_timeout")]
+ public int? AfkTimeout { get; set; }
+
+ [JsonPropertyName("banner")]
+ public string? Banner { get; set; }
+
+ [JsonPropertyName("default_message_notifications")]
+ public int? DefaultMessageNotifications { get; set; }
+
+ [JsonPropertyName("description")]
+ public string? Description { get; set; }
+
+ [JsonPropertyName("discovery_splash")]
+ public string? DiscoverySplash { get; set; }
+
+ [JsonPropertyName("explicit_content_filter")]
+ public int? ExplicitContentFilter { get; set; }
+
+ [JsonPropertyName("features")]
+ public List<string> Features { get; set; }
+
+ [JsonPropertyName("primary_category_id")]
+ public string? PrimaryCategoryId { get; set; }
+
+ [JsonPropertyName("icon")]
+ public string? Icon { get; set; }
+
+ [JsonPropertyName("large")]
+ public bool Large { get; set; }
+
+ [JsonPropertyName("max_members")]
+ public int? MaxMembers { get; set; }
+
+ [JsonPropertyName("max_presences")]
+ public int? MaxPresences { get; set; }
+
+ [JsonPropertyName("max_video_channel_users")]
+ public int? MaxVideoChannelUsers { get; set; }
+
+ [JsonPropertyName("member_count")]
+ public int? MemberCount { get; set; }
+
+ [JsonPropertyName("presence_count")]
+ public int? PresenceCount { get; set; }
+
+ [JsonPropertyName("template_id")]
+ public string? TemplateId { get; set; }
+
+ [JsonPropertyName("mfa_level")]
+ public int? MfaLevel { get; set; }
+
+ [JsonPropertyName("name")]
+ public string Name { get; set; } = null!;
+
+ [JsonPropertyName("owner_id")]
+ public string? OwnerId { get; set; }
+
+ [JsonPropertyName("preferred_locale")]
+ public string? PreferredLocale { get; set; }
+
+ [JsonPropertyName("premium_subscription_count")]
+ public int? PremiumSubscriptionCount { get; set; }
+
+ [JsonPropertyName("premium_tier")]
+ public int PremiumTier { get; set; }
+
+ [JsonPropertyName("public_updates_channel_id")]
+ public string? PublicUpdatesChannelId { get; set; }
+
+ [JsonPropertyName("rules_channel_id")]
+ public string? RulesChannelId { get; set; }
+
+ [JsonPropertyName("region")]
+ public string? Region { get; set; }
+
+ [JsonPropertyName("splash")]
+ public string? Splash { get; set; }
+
+ [JsonPropertyName("system_channel_id")]
+ public string? SystemChannelId { get; set; }
+
+ [JsonPropertyName("system_channel_flags")]
+ public int? SystemChannelFlags { get; set; }
+
+ [JsonPropertyName("unavailable")]
+ public bool Unavailable { get; set; }
+
+ [JsonPropertyName("verification_level")]
+ public int? VerificationLevel { get; set; }
+
+ [JsonPropertyName("welcome_screen")]
+ public string WelcomeScreen { get; set; } = null!;
+
+ [JsonPropertyName("widget_channel_id")]
+ public string? WidgetChannelId { get; set; }
+
+ [JsonPropertyName("widget_enabled")]
+ public bool WidgetEnabled { get; set; }
+
+ [JsonPropertyName("nsfw_level")]
+ public int? NsfwLevel { get; set; }
+
+ [JsonPropertyName("nsfw")]
+ public bool Nsfw { get; set; }
+
+ [JsonPropertyName("parent")]
+ public string? Parent { get; set; }
+
+ [JsonPropertyName("premium_progress_bar_enabled")]
+ public bool? PremiumProgressBarEnabled { get; set; }
+
+ [JsonPropertyName("channel_ordering")]
+ public List<string> ChannelOrdering { get; set; }
+
+ [JsonPropertyName("discovery_weight")]
+ public int DiscoveryWeight { get; set; }
+
+ [JsonPropertyName("discovery_excluded")]
+ public bool DiscoveryExcluded { get; set; }
+}
+
+public class DiscoverableGuildUpdateModel {
+ [JsonPropertyName("discovery_weight")]
+ public int? DiscoveryWeight { get; set; }
+
+ [JsonPropertyName("discovery_excluded")]
+ public bool? DiscoveryExcluded { get; set; }
+}
\ No newline at end of file
diff --git a/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs b/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
index 39d72b45..3f38b3a8 100644
--- a/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
+++ b/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
@@ -19,9 +19,180 @@ public class DiscoveryController(
ISpacebarReplication replication
) : ControllerBase {
[HttpGet]
- public async Task GetDiscoverableGuilds() {
+ public async IAsyncEnumerable<DiscoverableGuildModel> GetDiscoverableGuilds(bool includeExcluded = false) {
(await auth.GetCurrentUserAsync(Request)).GetRights().AssertHasAllRights(SpacebarRights.Rights.OPERATOR);
- // var discoverableGuilds = db.Guilds
- // .Where(x=>x.)
+ var discoverableGuilds = db.Guilds
+ .AsNoTracking()
+ .Where(x => (!x.DiscoveryExcluded || includeExcluded) && x.Features.Contains("DISCOVERABLE"))
+ .OrderByDescending(x => x.DiscoveryWeight)
+ .ThenByDescending(x => x.MemberCount);
+ await foreach (var guild in discoverableGuilds.AsAsyncEnumerable()) {
+ yield return new DiscoverableGuildModel() {
+ Id = guild.Id,
+ Features = guild.Features.Split(",").ToList(),
+ Banner = guild.Banner,
+ DiscoveryExcluded = guild.DiscoveryExcluded,
+ DiscoveryWeight = guild.DiscoveryWeight,
+ MemberCount = guild.MemberCount,
+ Name = guild.Name,
+ SystemChannelFlags = guild.SystemChannelFlags,
+ AfkChannelId = guild.AfkChannelId,
+ AfkTimeout = guild.AfkTimeout,
+ ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ DefaultMessageNotifications = guild.DefaultMessageNotifications,
+ Description = guild.Description,
+ DiscoverySplash = guild.DiscoverySplash,
+ ExplicitContentFilter = guild.ExplicitContentFilter,
+ Icon = guild.Icon,
+ Large = guild.Large,
+ MaxMembers = guild.MaxMembers,
+ MaxPresences = guild.MaxPresences,
+ MaxVideoChannelUsers = guild.MaxVideoChannelUsers,
+ MfaLevel = guild.MfaLevel,
+ Nsfw = guild.Nsfw,
+ NsfwLevel = guild.NsfwLevel,
+ OwnerId = guild.OwnerId,
+ Parent = guild.Parent,
+ PreferredLocale = guild.PreferredLocale,
+ PremiumProgressBarEnabled = guild.PremiumProgressBarEnabled,
+ PremiumTier = guild.PremiumTier,
+ PremiumSubscriptionCount = guild.PremiumSubscriptionCount,
+ PresenceCount = guild.PresenceCount,
+ PrimaryCategoryId = guild.PrimaryCategoryId,
+ PublicUpdatesChannelId = guild.PublicUpdatesChannelId,
+ Region = guild.Region,
+ RulesChannelId = guild.RulesChannelId,
+ Splash = guild.Splash,
+ SystemChannelId = guild.SystemChannelId,
+ TemplateId = guild.TemplateId,
+ Unavailable = guild.Unavailable,
+ VerificationLevel = guild.VerificationLevel,
+ WelcomeScreen = guild.WelcomeScreen,
+ WidgetChannelId = guild.WidgetChannelId,
+ WidgetEnabled = guild.WidgetEnabled
+ };
+ }
+ }
+
+ [HttpGet("{guildId}")]
+ public async Task<DiscoverableGuildModel> GetDiscoverableGuild(string guildId, bool includeExcluded = false) {
+ (await auth.GetCurrentUserAsync(Request)).GetRights().AssertHasAllRights(SpacebarRights.Rights.OPERATOR);
+ var discoverableGuilds = db.Guilds
+ .AsNoTracking()
+ .Where(x => x.Id == guildId)
+ .Where(x => (!x.DiscoveryExcluded || includeExcluded) && x.Features.Contains("DISCOVERABLE"))
+ .OrderByDescending(x => x.DiscoveryWeight)
+ .ThenByDescending(x => x.MemberCount);
+ var guild = await discoverableGuilds.SingleAsync();
+ return new DiscoverableGuildModel() {
+ Id = guild.Id,
+ Features = guild.Features.Split(",").ToList(),
+ Banner = guild.Banner,
+ DiscoveryExcluded = guild.DiscoveryExcluded,
+ DiscoveryWeight = guild.DiscoveryWeight,
+ MemberCount = guild.MemberCount,
+ Name = guild.Name,
+ SystemChannelFlags = guild.SystemChannelFlags,
+ AfkChannelId = guild.AfkChannelId,
+ AfkTimeout = guild.AfkTimeout,
+ ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ DefaultMessageNotifications = guild.DefaultMessageNotifications,
+ Description = guild.Description,
+ DiscoverySplash = guild.DiscoverySplash,
+ ExplicitContentFilter = guild.ExplicitContentFilter,
+ Icon = guild.Icon,
+ Large = guild.Large,
+ MaxMembers = guild.MaxMembers,
+ MaxPresences = guild.MaxPresences,
+ MaxVideoChannelUsers = guild.MaxVideoChannelUsers,
+ MfaLevel = guild.MfaLevel,
+ Nsfw = guild.Nsfw,
+ NsfwLevel = guild.NsfwLevel,
+ OwnerId = guild.OwnerId,
+ Parent = guild.Parent,
+ PreferredLocale = guild.PreferredLocale,
+ PremiumProgressBarEnabled = guild.PremiumProgressBarEnabled,
+ PremiumTier = guild.PremiumTier,
+ PremiumSubscriptionCount = guild.PremiumSubscriptionCount,
+ PresenceCount = guild.PresenceCount,
+ PrimaryCategoryId = guild.PrimaryCategoryId,
+ PublicUpdatesChannelId = guild.PublicUpdatesChannelId,
+ Region = guild.Region,
+ RulesChannelId = guild.RulesChannelId,
+ Splash = guild.Splash,
+ SystemChannelId = guild.SystemChannelId,
+ TemplateId = guild.TemplateId,
+ Unavailable = guild.Unavailable,
+ VerificationLevel = guild.VerificationLevel,
+ WelcomeScreen = guild.WelcomeScreen,
+ WidgetChannelId = guild.WidgetChannelId,
+ WidgetEnabled = guild.WidgetEnabled
+ };
+ }
+
+ [HttpPatch("{guildId}")]
+ public async Task<DiscoverableGuildModel> UpdateDiscoverableGuild(string guildId, [FromBody] DiscoverableGuildUpdateModel guildUpdateModel, bool includeExcluded = false) {
+ (await auth.GetCurrentUserAsync(Request)).GetRights().AssertHasAllRights(SpacebarRights.Rights.OPERATOR);
+ var guild = await db.Guilds
+ .AsNoTracking()
+ .Where(x => x.Id == guildId)
+ .Where(x => (!x.DiscoveryExcluded || includeExcluded) && x.Features.Contains("DISCOVERABLE"))
+ .OrderByDescending(x => x.DiscoveryWeight)
+ .ThenByDescending(x => x.MemberCount)
+ .SingleAsync();
+
+ if (guildUpdateModel.DiscoveryExcluded != null)
+ guild.DiscoveryExcluded = guildUpdateModel.DiscoveryExcluded.Value;
+
+ if (guildUpdateModel.DiscoveryWeight != null)
+ guild.DiscoveryWeight = guildUpdateModel.DiscoveryWeight.Value;
+
+ db.Guilds.Update(guild);
+ await db.SaveChangesAsync();
+
+ return new DiscoverableGuildModel() {
+ Id = guild.Id,
+ Features = guild.Features.Split(",").ToList(),
+ Banner = guild.Banner,
+ DiscoveryExcluded = guild.DiscoveryExcluded,
+ DiscoveryWeight = guild.DiscoveryWeight,
+ MemberCount = guild.MemberCount,
+ Name = guild.Name,
+ SystemChannelFlags = guild.SystemChannelFlags,
+ AfkChannelId = guild.AfkChannelId,
+ AfkTimeout = guild.AfkTimeout,
+ ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ DefaultMessageNotifications = guild.DefaultMessageNotifications,
+ Description = guild.Description,
+ DiscoverySplash = guild.DiscoverySplash,
+ ExplicitContentFilter = guild.ExplicitContentFilter,
+ Icon = guild.Icon,
+ Large = guild.Large,
+ MaxMembers = guild.MaxMembers,
+ MaxPresences = guild.MaxPresences,
+ MaxVideoChannelUsers = guild.MaxVideoChannelUsers,
+ MfaLevel = guild.MfaLevel,
+ Nsfw = guild.Nsfw,
+ NsfwLevel = guild.NsfwLevel,
+ OwnerId = guild.OwnerId,
+ Parent = guild.Parent,
+ PreferredLocale = guild.PreferredLocale,
+ PremiumProgressBarEnabled = guild.PremiumProgressBarEnabled,
+ PremiumTier = guild.PremiumTier,
+ PremiumSubscriptionCount = guild.PremiumSubscriptionCount,
+ PresenceCount = guild.PresenceCount,
+ PrimaryCategoryId = guild.PrimaryCategoryId,
+ PublicUpdatesChannelId = guild.PublicUpdatesChannelId,
+ Region = guild.Region,
+ RulesChannelId = guild.RulesChannelId,
+ Splash = guild.Splash,
+ SystemChannelId = guild.SystemChannelId,
+ TemplateId = guild.TemplateId,
+ Unavailable = guild.Unavailable,
+ VerificationLevel = guild.VerificationLevel,
+ WelcomeScreen = guild.WelcomeScreen,
+ WidgetChannelId = guild.WidgetChannelId,
+ WidgetEnabled = guild.WidgetEnabled
+ };
}
}
\ No newline at end of file
diff --git a/extra/admin-api/Spacebar.AdminApi/Spacebar.AdminApi.http b/extra/admin-api/Spacebar.AdminApi/Spacebar.AdminApi.http
index 06d9d174..bdb509e9 100644
--- a/extra/admin-api/Spacebar.AdminApi/Spacebar.AdminApi.http
+++ b/extra/admin-api/Spacebar.AdminApi/Spacebar.AdminApi.http
@@ -1,4 +1,4 @@
-@Spacebar.AdminApi_HostAddress = http://localhost:5112
+@SpacebarAdminApi_HostAddress = http://localhost:5112
POST {{Spacebar.AdminApi_HostAddress}}/_spacebar/admin/guilds/1473141782615941382/force_join
Content-Type: application/json
@@ -10,3 +10,10 @@ Accept: application/json
}
###
+
+GET {{SpacebarAdminApi_HostAddress}}/_spacebar/admin/discovery
+Content-Type: application/json
+Accept: application/json
+Authorization: null null
+
+###
diff --git a/extra/admin-api/update-deps.cs b/extra/admin-api/update-deps.cs
index bf0516f8..0ec7bd21 100755
--- a/extra/admin-api/update-deps.cs
+++ b/extra/admin-api/update-deps.cs
@@ -16,7 +16,8 @@ if (args.Length > 0) {
Console.WriteLine($"==> Updating dependencies for {outs.Length} projects...");
-foreach (var outp in outs) {
+var ss = new SemaphoreSlim(1, 1);
+var tasks = outs.Select(outp => Task.Run(async () => {
Console.WriteLine(ConsoleUtils.ColoredString($" ==> Updating {outp}...", 0x80, 0x80, 0xff));
Console.Write(ConsoleUtils.ColoredString($" ==> Getting project root directory... ", 0x80, 0xff, 0xff));
var rootDir = JsonSerializer.Deserialize<string>(Util.GetCommandOutputSync("nix", $"eval --json .#packages.x86_64-linux.{outp}.srcRoot", silent: true, stderr: false)).Split("/extra/admin-api/",2)[1];
@@ -27,18 +28,22 @@ foreach (var outp in outs) {
Console.WriteLine(ConsoleUtils.ColoredString($" ==> {nugetDepsFilePath} exists: {File.Exists(nugetDepsFilePath)}", 0x80, 0xff, 0xff));
if (!File.Exists(nugetDepsFilePath)) {
Console.WriteLine(ConsoleUtils.ColoredString($" ==> No NuGet deps file, skipping!", 0xff, 0x80, 0x80));
- continue;
+ return;
}
- Console.WriteLine(ConsoleUtils.ColoredString($" ==> Building fetch-deps script...", 0x80, 0xff, 0x80));
- Util.RunCommandSync("nix", $"build .#{outp}.passthru.fetch-deps");
+ var fname = $"./update-deps-{outp}";
+ Console.WriteLine(ConsoleUtils.ColoredString($" ==> Building fetch-deps script {fname}...", 0x80, 0xff, 0x80));
+ Util.RunCommandSync("nix", $"build .#{outp}.passthru.fetch-deps --out-link {fname}");
Console.WriteLine(ConsoleUtils.ColoredString($" ==> Running fetch-deps script...", 0x80, 0xff, 0x80));
- Util.RunCommandSync("./result", nugetDepsFilePath);
+ Util.RunCommandSync(fname, nugetDepsFilePath);
- var deps = JsonSerializer.Deserialize<object[]>(File.ReadAllText(nugetDepsFilePath));
+ var deps = JsonSerializer.Deserialize<object[]>(await File.ReadAllTextAsync(nugetDepsFilePath));
Console.WriteLine(ConsoleUtils.ColoredString($" ==> Locked {deps.Length} dependencies...", (byte)(deps.Length == 0 ? 0xff : 0x80), (byte)(deps.Length == 0 ? 0x80 : 0xff), 0x80));
+ File.Delete(fname);
// await Task.Delay(250);
-}
\ No newline at end of file
+})).ToList();
+
+await Task.WhenAll(tasks);
|