From 1ec205155c920f900646541d92e393a0a1e32751 Mon Sep 17 00:00:00 2001
From: Zechiax <106590288+Zechiax@users.noreply.github.com>
Date: Thu, 18 Apr 2024 20:25:29 +0200
Subject: [PATCH 1/3] add custom ping role to db model
---
Asterion/Database/Models/ModrinthEntry.cs | 1 +
...418182429_add custom ping role.Designer.cs | 312 ++++++++++++++++++
.../20240418182429_add custom ping role.cs | 28 ++
3 files changed, 341 insertions(+)
create mode 100644 Asterion/Migrations/20240418182429_add custom ping role.Designer.cs
create mode 100644 Asterion/Migrations/20240418182429_add custom ping role.cs
diff --git a/Asterion/Database/Models/ModrinthEntry.cs b/Asterion/Database/Models/ModrinthEntry.cs
index b191acf..40494ab 100644
--- a/Asterion/Database/Models/ModrinthEntry.cs
+++ b/Asterion/Database/Models/ModrinthEntry.cs
@@ -13,6 +13,7 @@ public class ModrinthEntry
public virtual Array Array { get; set; } = null!;
public ulong? CustomUpdateChannel { get; set; }
+ public ulong? CustomPingRole { get; set; }
[Required] public string ProjectId { get; set; } = null!;
diff --git a/Asterion/Migrations/20240418182429_add custom ping role.Designer.cs b/Asterion/Migrations/20240418182429_add custom ping role.Designer.cs
new file mode 100644
index 0000000..623a815
--- /dev/null
+++ b/Asterion/Migrations/20240418182429_add custom ping role.Designer.cs
@@ -0,0 +1,312 @@
+//
+using System;
+using Asterion.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Asterion.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ [Migration("20240418182429_add custom ping role")]
+ partial class addcustompingrole
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
+
+ modelBuilder.Entity("Asterion.Database.Models.Array", b =>
+ {
+ b.Property("ArrayId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("GuildId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("ArrayId");
+
+ b.ToTable("Arrays");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.Guild", b =>
+ {
+ b.Property("GuildId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Active")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.Property("Created")
+ .HasColumnType("TEXT");
+
+ b.Property("GuildSettingsId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ManageRole")
+ .HasColumnType("INTEGER");
+
+ b.Property("ModrinthArrayId")
+ .HasColumnType("INTEGER");
+
+ b.Property("PingRole")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("GuildId");
+
+ b.HasIndex("ModrinthArrayId")
+ .IsUnique();
+
+ b.ToTable("Guilds");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.GuildSettings", b =>
+ {
+ b.Property("GuildSettingsId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChangeLogMaxLength")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(2000L);
+
+ b.Property("ChangelogStyle")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(0);
+
+ b.Property("CheckMessagesForModrinthLink")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false);
+
+ b.Property("GuildId")
+ .HasColumnType("INTEGER");
+
+ b.Property("MessageStyle")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(0);
+
+ b.Property("RemoveOnLeave")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.Property("ShowChannelSelection")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.Property("ShowSubscribeButton")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.HasKey("GuildSettingsId");
+
+ b.HasIndex("GuildId")
+ .IsUnique();
+
+ b.ToTable("GuildSettings");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.ModrinthEntry", b =>
+ {
+ b.Property("EntryId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ArrayId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Created")
+ .HasColumnType("TEXT");
+
+ b.Property("CustomPingRole")
+ .HasColumnType("INTEGER");
+
+ b.Property("CustomUpdateChannel")
+ .HasColumnType("INTEGER");
+
+ b.Property("GuildId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProjectId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("EntryId");
+
+ b.HasIndex("ArrayId");
+
+ b.HasIndex("GuildId");
+
+ b.HasIndex("ProjectId");
+
+ b.ToTable("ModrinthEntries");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.ModrinthInstanceStatistics", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Authors")
+ .HasColumnType("INTEGER");
+
+ b.Property("Files")
+ .HasColumnType("INTEGER");
+
+ b.Property("Projects")
+ .HasColumnType("INTEGER");
+
+ b.Property("Versions")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("ModrinthInstanceStatistics");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.ModrinthProject", b =>
+ {
+ b.Property("ProjectId")
+ .HasColumnType("TEXT");
+
+ b.Property("Created")
+ .HasColumnType("TEXT");
+
+ b.Property("LastCheckVersion")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("LastUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("Title")
+ .HasColumnType("TEXT");
+
+ b.HasKey("ProjectId");
+
+ b.ToTable("ModrinthProjects");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.TotalDownloads", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Downloads")
+ .HasColumnType("INTEGER");
+
+ b.Property("Followers")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProjectId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Timestamp")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProjectId");
+
+ b.ToTable("TotalDownloads");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.Guild", b =>
+ {
+ b.HasOne("Asterion.Database.Models.Array", "ModrinthArray")
+ .WithOne("Guild")
+ .HasForeignKey("Asterion.Database.Models.Guild", "ModrinthArrayId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ModrinthArray");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.GuildSettings", b =>
+ {
+ b.HasOne("Asterion.Database.Models.Guild", "Guild")
+ .WithOne("GuildSettings")
+ .HasForeignKey("Asterion.Database.Models.GuildSettings", "GuildId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Guild");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.ModrinthEntry", b =>
+ {
+ b.HasOne("Asterion.Database.Models.Array", "Array")
+ .WithMany()
+ .HasForeignKey("ArrayId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Asterion.Database.Models.Guild", "Guild")
+ .WithMany()
+ .HasForeignKey("GuildId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Asterion.Database.Models.ModrinthProject", "Project")
+ .WithMany()
+ .HasForeignKey("ProjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Array");
+
+ b.Navigation("Guild");
+
+ b.Navigation("Project");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.TotalDownloads", b =>
+ {
+ b.HasOne("Asterion.Database.Models.ModrinthProject", "Project")
+ .WithMany("TotalDownloads")
+ .HasForeignKey("ProjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Project");
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.Array", b =>
+ {
+ b.Navigation("Guild")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.Guild", b =>
+ {
+ b.Navigation("GuildSettings")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Asterion.Database.Models.ModrinthProject", b =>
+ {
+ b.Navigation("TotalDownloads");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Asterion/Migrations/20240418182429_add custom ping role.cs b/Asterion/Migrations/20240418182429_add custom ping role.cs
new file mode 100644
index 0000000..2f27a7b
--- /dev/null
+++ b/Asterion/Migrations/20240418182429_add custom ping role.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Asterion.Migrations
+{
+ ///
+ public partial class addcustompingrole : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "CustomPingRole",
+ table: "ModrinthEntries",
+ type: "INTEGER",
+ nullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "CustomPingRole",
+ table: "ModrinthEntries");
+ }
+ }
+}
From 8a22e497c0a318d8c5c69f9be595f649135072a1 Mon Sep 17 00:00:00 2001
From: Zechiax <106590288+Zechiax@users.noreply.github.com>
Date: Thu, 18 Apr 2024 20:25:39 +0200
Subject: [PATCH 2/3] update migration
---
Asterion/Migrations/DataContextModelSnapshot.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Asterion/Migrations/DataContextModelSnapshot.cs b/Asterion/Migrations/DataContextModelSnapshot.cs
index 8a05216..65753d3 100644
--- a/Asterion/Migrations/DataContextModelSnapshot.cs
+++ b/Asterion/Migrations/DataContextModelSnapshot.cs
@@ -15,7 +15,7 @@ partial class DataContextModelSnapshot : ModelSnapshot
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
- modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
modelBuilder.Entity("Asterion.Database.Models.Array", b =>
{
@@ -131,6 +131,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property("Created")
.HasColumnType("TEXT");
+ b.Property("CustomPingRole")
+ .HasColumnType("INTEGER");
+
b.Property("CustomUpdateChannel")
.HasColumnType("INTEGER");
From f2549cce4a68a63580a59a71dc0cdf41c82ac5d6 Mon Sep 17 00:00:00 2001
From: Zechiax <106590288+Zechiax@users.noreply.github.com>
Date: Thu, 18 Apr 2024 20:41:04 +0200
Subject: [PATCH 3/3] implement setting custom ping role
---
Asterion/Interfaces/IDataService.cs | 4 +--
Asterion/Modules/GuildManagement.cs | 27 ++++++++++++----
Asterion/Services/DataService.cs | 32 ++++++++++++++++---
.../Modrinth/SendDiscordNotificationJob.cs | 6 ++++
4 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/Asterion/Interfaces/IDataService.cs b/Asterion/Interfaces/IDataService.cs
index 5ec4475..04336ef 100644
--- a/Asterion/Interfaces/IDataService.cs
+++ b/Asterion/Interfaces/IDataService.cs
@@ -133,6 +133,6 @@ public Task UpdateModrinthProjectAsync(string projectId, string? newVersio
///
public Task ChangeModrinthEntryChannel(ulong guildId, string projectId, ulong newChannelId);
- public Task SetPingRoleAsync(ulong guildId, ulong? roleId);
- public Task GetPingRoleIdAsync(ulong guildId);
+ public Task SetPingRoleAsync(ulong guildId, ulong? roleId, string? projectId = null);
+ public Task GetPingRoleIdAsync(ulong guildId, string? projectId = null);
}
\ No newline at end of file
diff --git a/Asterion/Modules/GuildManagement.cs b/Asterion/Modules/GuildManagement.cs
index e4cd412..4c570c5 100644
--- a/Asterion/Modules/GuildManagement.cs
+++ b/Asterion/Modules/GuildManagement.cs
@@ -1,5 +1,6 @@
using System.Text;
using Asterion.Attributes;
+using Asterion.AutocompleteHandlers;
using Asterion.Common;
using Asterion.Interfaces;
using Discord;
@@ -78,25 +79,37 @@ await ModifyOriginalResponseAsync(x =>
[RequireUserPermission(GuildPermission.Administrator, Group = "ManageSubs")]
[DoManageSubsRoleCheck(Group = "ManageSubs")]
[SlashCommand("set-ping-role", "Sets the role, which will be notified every time a project gets an update")]
- public async Task SetPingRole(IRole role)
+ public async Task SetPingRole(IRole role, [Autocomplete(typeof(SubscribedIdAutocompletionHandler))]
+ string? projectId = null)
{
await DeferAsync(true);
- var success = await _dataService.SetPingRoleAsync(Context.Guild.Id, role.Id);
+ var success = await _dataService.SetPingRoleAsync(Context.Guild.Id, role.Id, projectId);
if (success)
- await FollowupAsync(
- $"Ping role set to role {role.Mention} :white_check_mark: This role will be notified with each update");
+ {
+ if (projectId is not null)
+ await FollowupAsync(
+ $"Ping role set to role {role.Mention} for project {projectId} :white_check_mark: This role will be notified with each update");
+ else
+ {
+ await FollowupAsync(
+ $"Ping role set to role {role.Mention} :white_check_mark: This role will be notified with each update");
+ }
+ }
else
+ {
await FollowupAsync("There was an error while setting the ping role, please try again later");
+ }
}
[RequireUserPermission(GuildPermission.Administrator, Group = "ManageSubs")]
[DoManageSubsRoleCheck(Group = "ManageSubs")]
[SlashCommand("remove-ping-role", "Removes the ping role")]
- public async Task RemovePingRole()
+ public async Task RemovePingRole([Autocomplete(typeof(SubscribedIdAutocompletionHandler))]
+ string? projectId = null)
{
await DeferAsync(true);
- var oldRole = await _dataService.GetPingRoleIdAsync(Context.Guild.Id);
+ var oldRole = await _dataService.GetPingRoleIdAsync(Context.Guild.Id, projectId);
if (oldRole.HasValue == false)
{
@@ -104,7 +117,7 @@ public async Task RemovePingRole()
return;
}
- var success = await _dataService.SetPingRoleAsync(Context.Guild.Id, null);
+ var success = await _dataService.SetPingRoleAsync(Context.Guild.Id, null, projectId);
if (success)
await FollowupAsync(
diff --git a/Asterion/Services/DataService.cs b/Asterion/Services/DataService.cs
index cd55172..648204b 100644
--- a/Asterion/Services/DataService.cs
+++ b/Asterion/Services/DataService.cs
@@ -362,7 +362,7 @@ public async Task ChangeModrinthEntryChannel(ulong guildId, string project
return true;
}
- public async Task SetPingRoleAsync(ulong guildId, ulong? roleId)
+ public async Task SetPingRoleAsync(ulong guildId, ulong? roleId, string? projectId = null)
{
using var scope = _services.CreateScope();
await using var db = scope.ServiceProvider.GetRequiredService();
@@ -371,22 +371,44 @@ public async Task SetPingRoleAsync(ulong guildId, ulong? roleId)
if (guild is null) return false;
- guild.PingRole = roleId;
+ if (projectId is null)
+ {
+ guild.PingRole = roleId;
+ }
+ else
+ {
+ var entry = db.ModrinthEntries.FirstOrDefault(x => x.GuildId == guildId && x.ProjectId == projectId);
+
+ if (entry is null) return false;
+
+ entry.CustomPingRole = roleId;
+ }
await db.SaveChangesAsync();
return true;
}
- public async Task GetPingRoleIdAsync(ulong guildId)
+ public async Task GetPingRoleIdAsync(ulong guildId, string? projectId = null)
{
using var scope = _services.CreateScope();
await using var db = scope.ServiceProvider.GetRequiredService();
var guild = await GetGuildByIdAsync(guildId);
- // Return null if guild does not exists, otherwise return ManageRole value
- return guild?.PingRole;
+ if (projectId is not null)
+ {
+ var entry = db.ModrinthEntries.FirstOrDefault(x => x.GuildId == guildId && x.ProjectId == projectId);
+
+ if (entry is null) return null;
+
+ return entry.CustomPingRole;
+ }
+ else
+ {
+ // Return null if guild does not exists, otherwise return ManageRole value
+ return guild?.PingRole;
+ }
}
private async Task JoinGuild(SocketGuild guild)
diff --git a/Asterion/Services/Modrinth/SendDiscordNotificationJob.cs b/Asterion/Services/Modrinth/SendDiscordNotificationJob.cs
index 1f21314..8754aa5 100644
--- a/Asterion/Services/Modrinth/SendDiscordNotificationJob.cs
+++ b/Asterion/Services/Modrinth/SendDiscordNotificationJob.cs
@@ -99,6 +99,12 @@ private async Task SendNotifications(Project project, Version[] versions)
}
var pingRole = guild.PingRole is null ? null : channel.Guild.GetRole((ulong) guild.PingRole);
+ var customPingRole = entry.CustomPingRole;
+
+ if (customPingRole.HasValue)
+ {
+ pingRole = channel.Guild.GetRole(customPingRole.Value);
+ }
foreach (var version in versions.OrderBy(x => x.DatePublished))
{