mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-24 09:24:12 +00:00
Update commands to use EF queries
This commit is contained in:
parent
67decd6fb4
commit
b1b7c60211
4 changed files with 164 additions and 95 deletions
|
@ -41,8 +41,13 @@ public class BirthdayModule : BotModuleBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = await ((SocketGuildUser)Context.User).GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
await user.UpdateAsync(inmonth, inday, inzone ?? user.TimeZone).ConfigureAwait(false);
|
var user = ((SocketGuildUser)Context.User).GetUserEntryOrNew(db);
|
||||||
|
if (user.IsNew) db.UserEntries.Add(user);
|
||||||
|
user.BirthMonth = inmonth;
|
||||||
|
user.BirthDay = inday;
|
||||||
|
user.TimeZone = inzone;
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
await RespondAsync($":white_check_mark: Your birthday has been set to **{FormatDate(inmonth, inday)}**" +
|
await RespondAsync($":white_check_mark: Your birthday has been set to **{FormatDate(inmonth, inday)}**" +
|
||||||
(inzone == null ? "" : $", with time zone {inzone}") + ".").ConfigureAwait(false);
|
(inzone == null ? "" : $", with time zone {inzone}") + ".").ConfigureAwait(false);
|
||||||
|
@ -50,31 +55,35 @@ public class BirthdayModule : BotModuleBase {
|
||||||
|
|
||||||
[SlashCommand("timezone", HelpCmdSetZone)]
|
[SlashCommand("timezone", HelpCmdSetZone)]
|
||||||
public async Task CmdSetZone([Summary(description: HelpOptZone)] string zone) {
|
public async Task CmdSetZone([Summary(description: HelpOptZone)] string zone) {
|
||||||
var user = await ((SocketGuildUser)Context.User).GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
if (!user.IsKnown) {
|
|
||||||
|
var user = ((SocketGuildUser)Context.User).GetUserEntryOrNew(db);
|
||||||
|
if (user.IsNew) {
|
||||||
await RespondAsync(":x: You do not have a birthday set.", ephemeral: true).ConfigureAwait(false);
|
await RespondAsync(":x: You do not have a birthday set.", ephemeral: true).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string inzone;
|
string newzone;
|
||||||
try {
|
try {
|
||||||
inzone = ParseTimeZone(zone);
|
newzone = ParseTimeZone(zone);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
await RespondAsync(e.Message, ephemeral: true).ConfigureAwait(false);
|
await RespondAsync(e.Message, ephemeral: true).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await user.UpdateAsync(user.BirthMonth, user.BirthDay, inzone).ConfigureAwait(false);
|
user.TimeZone = newzone;
|
||||||
await RespondAsync($":white_check_mark: Your time zone has been set to **{inzone}**.").ConfigureAwait(false);
|
await db.SaveChangesAsync();
|
||||||
|
await RespondAsync($":white_check_mark: Your time zone has been set to **{newzone}**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("remove", HelpCmdRemove)]
|
[SlashCommand("remove", HelpCmdRemove)]
|
||||||
public async Task CmdRemove() {
|
public async Task CmdRemove() {
|
||||||
var user = await ((SocketGuildUser)Context.User).GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
if (user.IsKnown) {
|
var user = ((SocketGuildUser)Context.User).GetUserEntryOrNew(db);
|
||||||
await user.DeleteAsync().ConfigureAwait(false);
|
if (!user.IsNew) {
|
||||||
await RespondAsync(":white_check_mark: Your birthday in this server has been removed.")
|
db.UserEntries.Remove(user);
|
||||||
.ConfigureAwait(false);
|
await db.SaveChangesAsync();
|
||||||
|
await RespondAsync(":white_check_mark: Your birthday in this server has been removed.");
|
||||||
} else {
|
} else {
|
||||||
await RespondAsync(":white_check_mark: Your birthday is not registered.")
|
await RespondAsync(":white_check_mark: Your birthday is not registered.")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
@ -83,12 +92,15 @@ public class BirthdayModule : BotModuleBase {
|
||||||
|
|
||||||
[SlashCommand("get", "Gets a user's birthday.")]
|
[SlashCommand("get", "Gets a user's birthday.")]
|
||||||
public async Task CmdGetBday([Summary(description: "Optional: The user's birthday to look up.")] SocketGuildUser? user = null) {
|
public async Task CmdGetBday([Summary(description: "Optional: The user's birthday to look up.")] SocketGuildUser? user = null) {
|
||||||
var self = user is null;
|
using var db = new BotDatabaseContext();
|
||||||
if (self) user = (SocketGuildUser)Context.User;
|
|
||||||
var targetdata = await user!.GetConfigAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!targetdata.IsKnown) {
|
var isSelf = user is null;
|
||||||
if (self) await RespondAsync(":x: You do not have your birthday registered.", ephemeral: true).ConfigureAwait(false);
|
if (isSelf) user = (SocketGuildUser)Context.User;
|
||||||
|
|
||||||
|
var targetdata = user!.GetUserEntryOrNew(db);
|
||||||
|
|
||||||
|
if (targetdata.IsNew) {
|
||||||
|
if (isSelf) await RespondAsync(":x: You do not have your birthday registered.", ephemeral: true).ConfigureAwait(false);
|
||||||
else await RespondAsync(":x: The given user does not have their birthday registered.", ephemeral: true).ConfigureAwait(false);
|
else await RespondAsync(":x: The given user does not have their birthday registered.", ephemeral: true).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +123,7 @@ public class BirthdayModule : BotModuleBase {
|
||||||
var search = DateIndex(now.Month, now.Day) - 8; // begin search 8 days prior to current date UTC
|
var search = DateIndex(now.Month, now.Day) - 8; // begin search 8 days prior to current date UTC
|
||||||
if (search <= 0) search = 366 - Math.Abs(search);
|
if (search <= 0) search = 366 - Math.Abs(search);
|
||||||
|
|
||||||
var query = await GetSortedUsersAsync(Context.Guild).ConfigureAwait(false);
|
var query = GetSortedUserList(Context.Guild);
|
||||||
|
|
||||||
// TODO pagination instead of this workaround
|
// TODO pagination instead of this workaround
|
||||||
bool hasOutputOneLine = false;
|
bool hasOutputOneLine = false;
|
||||||
|
@ -182,7 +194,7 @@ public class BirthdayModule : BotModuleBase {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bdlist = await GetSortedUsersAsync(Context.Guild).ConfigureAwait(false);
|
var bdlist = GetSortedUserList(Context.Guild);
|
||||||
|
|
||||||
var filename = "birthdaybot-" + Context.Guild.Id;
|
var filename = "birthdaybot-" + Context.Guild.Id;
|
||||||
Stream fileoutput;
|
Stream fileoutput;
|
||||||
|
@ -201,27 +213,26 @@ public class BirthdayModule : BotModuleBase {
|
||||||
/// Fetches all guild birthdays and places them into an easily usable structure.
|
/// Fetches all guild birthdays and places them into an easily usable structure.
|
||||||
/// Users currently not in the guild are not included in the result.
|
/// Users currently not in the guild are not included in the result.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static async Task<List<ListItem>> GetSortedUsersAsync(SocketGuild guild) {
|
private static List<ListItem> GetSortedUserList(SocketGuild guild) {
|
||||||
using var db = await Database.OpenConnectionAsync();
|
using var db = new BotDatabaseContext();
|
||||||
using var c = db.CreateCommand();
|
var query = from row in db.UserEntries
|
||||||
c.CommandText = "select user_id, birth_month, birth_day from " + GuildUserConfiguration.BackingTable
|
where row.GuildId == (long)guild.Id
|
||||||
+ " where guild_id = @Gid order by birth_month, birth_day";
|
orderby row.BirthMonth, row.BirthDay
|
||||||
c.Parameters.Add("@Gid", NpgsqlTypes.NpgsqlDbType.Bigint).Value = (long)guild.Id;
|
select new {
|
||||||
c.Prepare();
|
UserId = (ulong)row.UserId,
|
||||||
using var r = await c.ExecuteReaderAsync();
|
Month = row.BirthMonth,
|
||||||
var result = new List<ListItem>();
|
Day = row.BirthDay
|
||||||
while (await r.ReadAsync()) {
|
};
|
||||||
var id = (ulong)r.GetInt64(0);
|
|
||||||
var month = r.GetInt32(1);
|
|
||||||
var day = r.GetInt32(2);
|
|
||||||
|
|
||||||
var guildUser = guild.GetUser(id);
|
var result = new List<ListItem>();
|
||||||
|
foreach (var row in query) {
|
||||||
|
var guildUser = guild.GetUser(row.UserId);
|
||||||
if (guildUser == null) continue; // Skip user not in guild
|
if (guildUser == null) continue; // Skip user not in guild
|
||||||
|
|
||||||
result.Add(new ListItem() {
|
result.Add(new ListItem() {
|
||||||
BirthMonth = month,
|
BirthMonth = row.Month,
|
||||||
BirthDay = day,
|
BirthDay = row.Day,
|
||||||
DateIndex = DateIndex(month, day),
|
DateIndex = DateIndex(row.Month, row.Day),
|
||||||
UserId = guildUser.Id,
|
UserId = guildUser.Id,
|
||||||
DisplayName = Common.FormatName(guildUser, false)
|
DisplayName = Common.FormatName(guildUser, false)
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,8 +24,12 @@ public class BirthdayOverrideModule : BotModuleBase {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = await target.GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
await user.UpdateAsync(inmonth, inday, user.TimeZone).ConfigureAwait(false);
|
var user = target.GetUserEntryOrNew(db);
|
||||||
|
if (user.IsNew) db.UserEntries.Add(user);
|
||||||
|
user.BirthMonth = inmonth;
|
||||||
|
user.BirthDay = inday;
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s birthday has been set to " +
|
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s birthday has been set to " +
|
||||||
$"**{FormatDate(inmonth, inday)}**.").ConfigureAwait(false);
|
$"**{FormatDate(inmonth, inday)}**.").ConfigureAwait(false);
|
||||||
|
@ -34,30 +38,35 @@ public class BirthdayOverrideModule : BotModuleBase {
|
||||||
[SlashCommand("set-timezone", HelpPfxModOnly + "Set a user's time zone on their behalf.")]
|
[SlashCommand("set-timezone", HelpPfxModOnly + "Set a user's time zone on their behalf.")]
|
||||||
public async Task OvSetTimezone([Summary(description: HelpOptOvTarget)]SocketGuildUser target,
|
public async Task OvSetTimezone([Summary(description: HelpOptOvTarget)]SocketGuildUser target,
|
||||||
[Summary(description: HelpOptZone)]string zone) {
|
[Summary(description: HelpOptZone)]string zone) {
|
||||||
var user = await target.GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
if (!user.IsKnown) {
|
|
||||||
|
var user = target.GetUserEntryOrNew(db);
|
||||||
|
if (user.IsNew) {
|
||||||
await RespondAsync($":x: {Common.FormatName(target, false)} does not have a birthday set.")
|
await RespondAsync($":x: {Common.FormatName(target, false)} does not have a birthday set.")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string inzone;
|
string newzone;
|
||||||
try {
|
try {
|
||||||
inzone = ParseTimeZone(zone);
|
newzone = ParseTimeZone(zone);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
await RespondAsync(e.Message, ephemeral: true).ConfigureAwait(false);
|
await RespondAsync(e.Message, ephemeral: true).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await user.UpdateAsync(user.BirthMonth, user.BirthDay, inzone).ConfigureAwait(false);
|
user.TimeZone = newzone;
|
||||||
|
await db.SaveChangesAsync();
|
||||||
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s time zone has been set to " +
|
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s time zone has been set to " +
|
||||||
$"**{inzone}**.").ConfigureAwait(false);
|
$"**{newzone}**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("remove-birthday", HelpPfxModOnly + "Remove a user's birthday information on their behalf.")]
|
[SlashCommand("remove-birthday", HelpPfxModOnly + "Remove a user's birthday information on their behalf.")]
|
||||||
public async Task OvRemove([Summary(description: HelpOptOvTarget)]SocketGuildUser target) {
|
public async Task OvRemove([Summary(description: HelpOptOvTarget)]SocketGuildUser target) {
|
||||||
var user = await target.GetConfigAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
if (user.IsKnown) {
|
var user = ((SocketGuildUser)Context.User).GetUserEntryOrNew(db);
|
||||||
await user.DeleteAsync().ConfigureAwait(false);
|
if (!user.IsNew) {
|
||||||
|
db.UserEntries.Remove(user);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s birthday in this server has been removed.")
|
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s birthday in this server has been removed.")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -53,9 +53,7 @@ public class ConfigModule : BotModuleBase {
|
||||||
|
|
||||||
[SlashCommand("set-channel", HelpPfxModOnly + HelpSubCmdChannel + HelpPofxBlankUnset)]
|
[SlashCommand("set-channel", HelpPfxModOnly + HelpSubCmdChannel + HelpPofxBlankUnset)]
|
||||||
public async Task CmdSetChannel([Summary(description: HelpOptRole)] SocketTextChannel? channel = null) {
|
public async Task CmdSetChannel([Summary(description: HelpOptRole)] SocketTextChannel? channel = null) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
await DoDatabaseUpdate(Context, s => s.ChannelAnnounceId = (long?)channel?.Id);
|
||||||
gconf.AnnounceChannelId = channel?.Id;
|
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync(":white_check_mark: The announcement channel has been " +
|
await RespondAsync(":white_check_mark: The announcement channel has been " +
|
||||||
(channel == null ? "unset." : $"set to **{channel.Name}**."));
|
(channel == null ? "unset." : $"set to **{channel.Name}**."));
|
||||||
}
|
}
|
||||||
|
@ -71,9 +69,7 @@ public class ConfigModule : BotModuleBase {
|
||||||
|
|
||||||
[SlashCommand("set-ping", HelpPfxModOnly + HelpSubCmdPing)]
|
[SlashCommand("set-ping", HelpPfxModOnly + HelpSubCmdPing)]
|
||||||
public async Task CmdSetPing([Summary(description: "Set True to ping users, False to display them normally.")]bool option) {
|
public async Task CmdSetPing([Summary(description: "Set True to ping users, False to display them normally.")]bool option) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
await DoDatabaseUpdate(Context, s => s.AnnouncePing = option);
|
||||||
gconf.AnnouncePing = option;
|
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync($":white_check_mark: Announcement pings are now **{(option ? "on" : "off")}**.").ConfigureAwait(false);
|
await RespondAsync($":white_check_mark: Announcement pings are now **{(option ? "on" : "off")}**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,17 +78,13 @@ public class ConfigModule : BotModuleBase {
|
||||||
public class SubCmdsConfigRole : BotModuleBase {
|
public class SubCmdsConfigRole : BotModuleBase {
|
||||||
[SlashCommand("set-birthday-role", HelpPfxModOnly + "Set the role given to users having a birthday.")]
|
[SlashCommand("set-birthday-role", HelpPfxModOnly + "Set the role given to users having a birthday.")]
|
||||||
public async Task CmdSetBRole([Summary(description: HelpOptRole)] SocketRole role) {
|
public async Task CmdSetBRole([Summary(description: HelpOptRole)] SocketRole role) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
await DoDatabaseUpdate(Context, s => s.RoleId = (long)role.Id);
|
||||||
gconf.RoleId = role.Id;
|
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync($":white_check_mark: The birthday role has been set to **{role.Name}**.").ConfigureAwait(false);
|
await RespondAsync($":white_check_mark: The birthday role has been set to **{role.Name}**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("set-moderator-role", HelpPfxModOnly + "Designate a role whose members can configure the bot." + HelpPofxBlankUnset)]
|
[SlashCommand("set-moderator-role", HelpPfxModOnly + "Designate a role whose members can configure the bot." + HelpPofxBlankUnset)]
|
||||||
public async Task CmdSetModRole([Summary(description: HelpOptRole)]SocketRole? role = null) {
|
public async Task CmdSetModRole([Summary(description: HelpOptRole)]SocketRole? role = null) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
await DoDatabaseUpdate(Context, s => s.ModeratorRole = (long?)role?.Id);
|
||||||
gconf.ModeratorRole = role?.Id;
|
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync(":white_check_mark: The moderator role has been " +
|
await RespondAsync(":white_check_mark: The moderator role has been " +
|
||||||
(role == null ? "unset." : $"set to **{role.Name}**."));
|
(role == null ? "unset." : $"set to **{role.Name}**."));
|
||||||
}
|
}
|
||||||
|
@ -107,26 +99,36 @@ public class ConfigModule : BotModuleBase {
|
||||||
public Task CmdDelBlock([Summary(description: "The user to unblock.")] SocketGuildUser user) => UpdateBlockAsync(user, false);
|
public Task CmdDelBlock([Summary(description: "The user to unblock.")] SocketGuildUser user) => UpdateBlockAsync(user, false);
|
||||||
|
|
||||||
private async Task UpdateBlockAsync(SocketGuildUser user, bool setting) {
|
private async Task UpdateBlockAsync(SocketGuildUser user, bool setting) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
// setting: true to add (set), false to remove (unset)
|
||||||
bool already = setting == await gconf.IsUserBlockedAsync(user.Id).ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
|
var existing = db.BlocklistEntries
|
||||||
|
.Where(bl => bl.GuildId == (long)user.Guild.Id && bl.UserId == (long)user.Id).FirstOrDefault();
|
||||||
|
|
||||||
|
bool already = (existing != null) == setting;
|
||||||
if (already) {
|
if (already) {
|
||||||
await RespondAsync($":white_check_mark: User is already {(setting ? "" : "not ")}blocked.").ConfigureAwait(false);
|
await RespondAsync($":white_check_mark: User is already {(setting ? "" : "not ")}blocked.").ConfigureAwait(false);
|
||||||
} else {
|
return;
|
||||||
if (setting) await gconf.BlockUserAsync(user.Id).ConfigureAwait(false);
|
|
||||||
else await gconf.UnblockUserAsync(user.Id).ConfigureAwait(false);
|
|
||||||
await RespondAsync($":white_check_mark: {Common.FormatName(user, false)} has been {(setting ? "" : "un")}blocked.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setting) db.BlocklistEntries.Add(new BlocklistEntry() { GuildId = (long)user.Guild.Id, UserId = (long)user.Id });
|
||||||
|
else db.Remove(existing!);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
await RespondAsync($":white_check_mark: {Common.FormatName(user, false)} has been {(setting ? "" : "un")}blocked.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("set-moderated", HelpPfxModOnly + "Set moderated mode on the server.")]
|
[SlashCommand("set-moderated", HelpPfxModOnly + "Set moderated mode on the server.")]
|
||||||
public async Task CmdAddBlock([Summary(name: "enable", description: "The moderated mode setting.")] bool setting) {
|
public async Task CmdSetModerated([Summary(name: "enable", description: "The moderated mode setting.")] bool setting) {
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
bool current = false;
|
||||||
bool already = setting == gconf.IsModerated;
|
await DoDatabaseUpdate(Context, s => {
|
||||||
|
current = s.Moderated;
|
||||||
|
s.Moderated = setting;
|
||||||
|
});
|
||||||
|
|
||||||
|
bool already = setting == current;
|
||||||
if (already) {
|
if (already) {
|
||||||
await RespondAsync($":white_check_mark: Moderated mode is already **{(setting ? "en" : "dis")}abled**.").ConfigureAwait(false);
|
await RespondAsync($":white_check_mark: Moderated mode is already **{(setting ? "en" : "dis")}abled**.");
|
||||||
} else {
|
} else {
|
||||||
gconf.IsModerated = setting;
|
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync($":white_check_mark: Moderated mode is now **{(setting ? "en" : "dis")}abled**.").ConfigureAwait(false);
|
await RespondAsync($":white_check_mark: Moderated mode is now **{(setting ? "en" : "dis")}abled**.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,15 +137,19 @@ public class ConfigModule : BotModuleBase {
|
||||||
[SlashCommand("check", HelpPfxModOnly + HelpCmdCheck)]
|
[SlashCommand("check", HelpPfxModOnly + HelpCmdCheck)]
|
||||||
public async Task CmdCheck() {
|
public async Task CmdCheck() {
|
||||||
static string DoTestFor(string label, Func<bool> test) => $"{label}: { (test() ? ":white_check_mark: Yes" : ":x: No") }";
|
static string DoTestFor(string label, Func<bool> test) => $"{label}: { (test() ? ":white_check_mark: Yes" : ":x: No") }";
|
||||||
var result = new StringBuilder();
|
|
||||||
SocketTextChannel channel = (SocketTextChannel)Context.Channel;
|
SocketTextChannel channel = (SocketTextChannel)Context.Channel;
|
||||||
var guild = Context.Guild;
|
var guild = Context.Guild;
|
||||||
var conf = await guild.GetConfigAsync().ConfigureAwait(false);
|
|
||||||
var usercfgs = await guild.GetUserConfigurationsAsync().ConfigureAwait(false);
|
using var db = new BotDatabaseContext();
|
||||||
|
var guildconf = guild.GetConfigOrNew(db);
|
||||||
|
await db.Entry(guildconf).Collection(t => t.UserEntries).LoadAsync();
|
||||||
|
|
||||||
|
var result = new StringBuilder();
|
||||||
|
|
||||||
result.AppendLine($"Server ID: `{guild.Id}` | Bot shard ID: `{Shard.ShardId:00}`");
|
result.AppendLine($"Server ID: `{guild.Id}` | Bot shard ID: `{Shard.ShardId:00}`");
|
||||||
result.AppendLine($"Number of registered birthdays: `{ usercfgs.Count() }`");
|
result.AppendLine($"Number of registered birthdays: `{ guildconf.UserEntries.Count() }`");
|
||||||
result.AppendLine($"Server time zone: `{ (conf?.TimeZone ?? "Not set - using UTC") }`");
|
result.AppendLine($"Server time zone: `{ (guildconf.TimeZone ?? "Not set - using UTC") }`");
|
||||||
result.AppendLine();
|
result.AppendLine();
|
||||||
|
|
||||||
bool hasMembers = Common.HasMostMembersDownloaded(guild);
|
bool hasMembers = Common.HasMostMembersDownloaded(guild);
|
||||||
|
@ -152,7 +158,7 @@ public class ConfigModule : BotModuleBase {
|
||||||
int bdayCount = -1;
|
int bdayCount = -1;
|
||||||
result.Append(DoTestFor("Birthday processing", delegate {
|
result.Append(DoTestFor("Birthday processing", delegate {
|
||||||
if (!hasMembers) return false;
|
if (!hasMembers) return false;
|
||||||
bdayCount = BackgroundServices.BirthdayRoleUpdate.GetGuildCurrentBirthdays(usercfgs, conf?.TimeZone).Count;
|
bdayCount = BackgroundServices.BirthdayRoleUpdate.GetGuildCurrentBirthdays(guildconf.UserEntries, guildconf.TimeZone).Count;
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
if (hasMembers) result.AppendLine($" - `{bdayCount}` user(s) currently having a birthday.");
|
if (hasMembers) result.AppendLine($" - `{bdayCount}` user(s) currently having a birthday.");
|
||||||
|
@ -160,13 +166,13 @@ public class ConfigModule : BotModuleBase {
|
||||||
result.AppendLine();
|
result.AppendLine();
|
||||||
|
|
||||||
result.AppendLine(DoTestFor("Birthday role set with `bb.config role`", delegate {
|
result.AppendLine(DoTestFor("Birthday role set with `bb.config role`", delegate {
|
||||||
if (conf == null) return false;
|
if (guildconf.IsNew) return false;
|
||||||
SocketRole? role = guild.GetRole(conf.RoleId ?? 0);
|
SocketRole? role = guild.GetRole((ulong)(guildconf.RoleId ?? 0));
|
||||||
return role != null;
|
return role != null;
|
||||||
}));
|
}));
|
||||||
result.AppendLine(DoTestFor("Birthday role can be managed by bot", delegate {
|
result.AppendLine(DoTestFor("Birthday role can be managed by bot", delegate {
|
||||||
if (conf == null) return false;
|
if (guildconf.IsNew) return false;
|
||||||
SocketRole? role = guild.GetRole(conf.RoleId ?? 0);
|
SocketRole? role = guild.GetRole((ulong)(guildconf.RoleId ?? 0));
|
||||||
if (role == null) return false;
|
if (role == null) return false;
|
||||||
return guild.CurrentUser.GuildPermissions.ManageRoles && role.Position < guild.CurrentUser.Hierarchy;
|
return guild.CurrentUser.GuildPermissions.ManageRoles && role.Position < guild.CurrentUser.Hierarchy;
|
||||||
}));
|
}));
|
||||||
|
@ -174,8 +180,8 @@ public class ConfigModule : BotModuleBase {
|
||||||
|
|
||||||
SocketTextChannel? announcech = null;
|
SocketTextChannel? announcech = null;
|
||||||
result.AppendLine(DoTestFor("(Optional) Announcement channel set with `bb.config channel`", delegate {
|
result.AppendLine(DoTestFor("(Optional) Announcement channel set with `bb.config channel`", delegate {
|
||||||
if (conf == null) return false;
|
if (guildconf.IsNew) return false;
|
||||||
announcech = guild.GetTextChannel(conf.AnnounceChannelId ?? 0);
|
announcech = guild.GetTextChannel((ulong)(guildconf.ChannelAnnounceId ?? 0));
|
||||||
return announcech != null;
|
return announcech != null;
|
||||||
}));
|
}));
|
||||||
string disp = announcech == null ? "announcement channel" : $"<#{announcech.Id}>";
|
string disp = announcech == null ? "announcement channel" : $"<#{announcech.Id}>";
|
||||||
|
@ -197,14 +203,14 @@ public class ConfigModule : BotModuleBase {
|
||||||
result.AppendLine($"> {line}");
|
result.AppendLine($"> {line}");
|
||||||
return result.ToString();
|
return result.ToString();
|
||||||
}
|
}
|
||||||
if (conf != null && (conf.AnnounceMessages.Item1 != null || conf.AnnounceMessages.Item2 != null)) {
|
if (!guildconf.IsNew && (guildconf.AnnounceMessage != null || guildconf.AnnounceMessagePl != null)) {
|
||||||
var em = new EmbedBuilder().WithAuthor(new EmbedAuthorBuilder() { Name = "Custom announce messages:" });
|
var em = new EmbedBuilder().WithAuthor(new EmbedAuthorBuilder() { Name = "Custom announce messages:" });
|
||||||
var dispAnnounces = new StringBuilder("Custom announcement message(s):\n");
|
var dispAnnounces = new StringBuilder("Custom announcement message(s):\n");
|
||||||
if (conf.AnnounceMessages.Item1 != null) {
|
if (guildconf.AnnounceMessage != null) {
|
||||||
em = em.AddField("Single", prepareAnnouncePreview(conf.AnnounceMessages.Item1));
|
em = em.AddField("Single", prepareAnnouncePreview(guildconf.AnnounceMessage));
|
||||||
}
|
}
|
||||||
if (conf.AnnounceMessages.Item2 != null) {
|
if (guildconf.AnnounceMessagePl != null) {
|
||||||
em = em.AddField("Multi", prepareAnnouncePreview(conf.AnnounceMessages.Item2));
|
em = em.AddField("Multi", prepareAnnouncePreview(guildconf.AnnounceMessagePl));
|
||||||
}
|
}
|
||||||
await ReplyAsync(embed: em.Build()).ConfigureAwait(false);
|
await ReplyAsync(embed: em.Build()).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -213,11 +219,9 @@ public class ConfigModule : BotModuleBase {
|
||||||
[SlashCommand("set-timezone", HelpPfxModOnly + "Configure the time zone to use by default in the server." + HelpPofxBlankUnset)]
|
[SlashCommand("set-timezone", HelpPfxModOnly + "Configure the time zone to use by default in the server." + HelpPofxBlankUnset)]
|
||||||
public async Task CmdSetTimezone([Summary(description: HelpOptZone)] string? zone = null) {
|
public async Task CmdSetTimezone([Summary(description: HelpOptZone)] string? zone = null) {
|
||||||
const string Response = ":white_check_mark: The server's time zone has been ";
|
const string Response = ":white_check_mark: The server's time zone has been ";
|
||||||
var gconf = await Context.Guild.GetConfigAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (zone == null) {
|
if (zone == null) {
|
||||||
gconf.TimeZone = null;
|
await DoDatabaseUpdate(Context, s => s.TimeZone = null);
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
|
||||||
await RespondAsync(Response + "unset.").ConfigureAwait(false);
|
await RespondAsync(Response + "unset.").ConfigureAwait(false);
|
||||||
} else {
|
} else {
|
||||||
string parsedZone;
|
string parsedZone;
|
||||||
|
@ -228,9 +232,22 @@ public class ConfigModule : BotModuleBase {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gconf.TimeZone = parsedZone;
|
await DoDatabaseUpdate(Context, s => s.TimeZone = parsedZone);
|
||||||
await gconf.UpdateAsync().ConfigureAwait(false);
|
await RespondAsync(Response + $"set to **{parsedZone}**.").ConfigureAwait(false);
|
||||||
await RespondAsync(Response + $"set to **{zone}**.").ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method for updating arbitrary <see cref="GuildConfig"/> values without all the boilerplate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="valueUpdater">A delegate which modifies <see cref="GuildConfig"/> properties as needed.</param>
|
||||||
|
private static async Task DoDatabaseUpdate(SocketInteractionContext context, Action<GuildConfig> valueUpdater) {
|
||||||
|
using var db = new BotDatabaseContext();
|
||||||
|
var settings = context.Guild.GetConfigOrNew(db);
|
||||||
|
|
||||||
|
valueUpdater(settings);
|
||||||
|
|
||||||
|
if (settings.IsNew) db.GuildConfigurations.Add(settings);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,9 @@ class BirthdayRoleUpdate : BackgroundService {
|
||||||
/// Gets all known users from the given guild and returns a list including only those who are
|
/// Gets all known users from the given guild and returns a list including only those who are
|
||||||
/// currently experiencing a birthday in the respective time zone.
|
/// currently experiencing a birthday in the respective time zone.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
#pragma warning disable 618
|
||||||
|
[Obsolete(Database.ObsoleteReason)]
|
||||||
|
#pragma warning restore 618
|
||||||
public static HashSet<ulong> GetGuildCurrentBirthdays(IEnumerable<GuildUserConfiguration> guildUsers, string? defaultTzStr) {
|
public static HashSet<ulong> GetGuildCurrentBirthdays(IEnumerable<GuildUserConfiguration> guildUsers, string? defaultTzStr) {
|
||||||
var tzdb = DateTimeZoneProviders.Tzdb;
|
var tzdb = DateTimeZoneProviders.Tzdb;
|
||||||
DateTimeZone defaultTz = (defaultTzStr != null ? DateTimeZoneProviders.Tzdb.GetZoneOrNull(defaultTzStr) : null) ?? tzdb.GetZoneOrNull("UTC")!;
|
DateTimeZone defaultTz = (defaultTzStr != null ? DateTimeZoneProviders.Tzdb.GetZoneOrNull(defaultTzStr) : null) ?? tzdb.GetZoneOrNull("UTC")!;
|
||||||
|
@ -102,6 +105,35 @@ class BirthdayRoleUpdate : BackgroundService {
|
||||||
return birthdayUsers;
|
return birthdayUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all known users from the given guild and returns a list including only those who are
|
||||||
|
/// currently experiencing a birthday in the respective time zone.
|
||||||
|
/// </summary>
|
||||||
|
public static HashSet<ulong> GetGuildCurrentBirthdays(IEnumerable<UserEntry> guildUsers, string? defaultTzStr) {
|
||||||
|
var tzdb = DateTimeZoneProviders.Tzdb;
|
||||||
|
DateTimeZone defaultTz = (defaultTzStr != null ? DateTimeZoneProviders.Tzdb.GetZoneOrNull(defaultTzStr) : null) ?? tzdb.GetZoneOrNull("UTC")!;
|
||||||
|
|
||||||
|
var birthdayUsers = new HashSet<ulong>();
|
||||||
|
foreach (var item in guildUsers) {
|
||||||
|
// Determine final time zone to use for calculation
|
||||||
|
DateTimeZone tz = (item.TimeZone != null ? tzdb.GetZoneOrNull(item.TimeZone) : null) ?? defaultTz;
|
||||||
|
|
||||||
|
var targetMonth = item.BirthMonth;
|
||||||
|
var targetDay = item.BirthDay;
|
||||||
|
|
||||||
|
var checkNow = SystemClock.Instance.GetCurrentInstant().InZone(tz);
|
||||||
|
// Special case: If birthday is February 29 and it's not a leap year, recognize it on March 1st
|
||||||
|
if (targetMonth == 2 && targetDay == 29 && !DateTime.IsLeapYear(checkNow.Year)) {
|
||||||
|
targetMonth = 3;
|
||||||
|
targetDay = 1;
|
||||||
|
}
|
||||||
|
if (targetMonth == checkNow.Month && targetDay == checkNow.Day) {
|
||||||
|
birthdayUsers.Add((ulong)item.UserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return birthdayUsers;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the birthday role to all applicable users. Unsets it from all others who may have it.
|
/// Sets the birthday role to all applicable users. Unsets it from all others who may have it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue