mirror of
https://github.com/NoiTheCat/WorldTime.git
synced 2024-11-21 06:34:36 +00:00
Add 12-hour time format (implements #2)
This commit is contained in:
parent
7a7bc097e8
commit
09ba9644dc
8 changed files with 184 additions and 15 deletions
|
@ -25,16 +25,20 @@ public class CommandsBase : InteractionModuleBase<ShardedInteractionContext> {
|
|||
|
||||
/// <summary>
|
||||
/// Returns a string displaying the current time in the given time zone.
|
||||
/// The result begins with four numbers for sorting purposes. Must be trimmed before output.
|
||||
/// The result begins with six numbers for sorting purposes. Must be trimmed before output.
|
||||
/// </summary>
|
||||
protected static string TzPrint(string zone) {
|
||||
protected static string TzPrint(string zone, bool use12hr) {
|
||||
var tzdb = DateTimeZoneProviders.Tzdb;
|
||||
DateTimeZone tz = tzdb.GetZoneOrNull(zone)!;
|
||||
if (tz == null) throw new Exception("Encountered unknown time zone: " + zone);
|
||||
|
||||
var now = SystemClock.Instance.GetCurrentInstant().InZone(tz);
|
||||
var sortpfx = now.ToString("MMdd", DateTimeFormatInfo.InvariantInfo);
|
||||
var fullstr = now.ToString("dd'-'MMM' 'HH':'mm' 'x' (UTC'o<g>')'", DateTimeFormatInfo.InvariantInfo);
|
||||
var sortpfx = now.ToString("MMddHH", DateTimeFormatInfo.InvariantInfo);
|
||||
string fullstr;
|
||||
if (use12hr) {
|
||||
var ap = now.ToString("tt", DateTimeFormatInfo.InvariantInfo).ToLowerInvariant();
|
||||
fullstr = now.ToString($"MMM' 'dd', 'hh':'mm'{ap} 'x' (UTC'o<g>')'", DateTimeFormatInfo.InvariantInfo);
|
||||
} else fullstr = now.ToString("dd'-'MMM', 'HH':'mm' 'x' (UTC'o<g>')'", DateTimeFormatInfo.InvariantInfo);
|
||||
return $"{sortpfx}● `{fullstr}`";
|
||||
}
|
||||
|
||||
|
|
28
Commands/ConfigCommands.cs
Normal file
28
Commands/ConfigCommands.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using Discord.Interactions;
|
||||
|
||||
namespace WorldTime.Commands;
|
||||
[Group("config", HelpSettings)]
|
||||
public class ConfigCommands : CommandsBase {
|
||||
internal const string HelpSettings = "Configuration commands for World Time.";
|
||||
internal const string HelpUse12 = "Sets whether to use the 12-hour (AM/PM) format in time zone listings.";
|
||||
|
||||
[RequireGuildContext]
|
||||
[SlashCommand("use-12hour", HelpUse12)]
|
||||
public async Task Cmd12Hour([Summary(description: "True to enable, False to disable.")] bool setting) {
|
||||
if (!IsUserAdmin((SocketGuildUser)Context.User)) {
|
||||
await RespondAsync(ErrNotAllowed, ephemeral: true);
|
||||
return;
|
||||
}
|
||||
|
||||
using var db = DbContext;
|
||||
var gs = db.GuildSettings.Where(r => r.GuildId == Context.Guild.Id).SingleOrDefault();
|
||||
if (gs == null) {
|
||||
gs = new() { GuildId = Context.Guild.Id };
|
||||
db.Add(gs);
|
||||
}
|
||||
|
||||
gs.Use12HourTime = setting;
|
||||
await db.SaveChangesAsync();
|
||||
await RespondAsync($":white_check_mark: Time listing set to **{(setting ? "AM/PM" : "24 hour")}** format.");
|
||||
}
|
||||
}
|
|
@ -2,12 +2,16 @@
|
|||
using System.Text;
|
||||
|
||||
namespace WorldTime.Commands;
|
||||
public class ApplicationCommands : CommandsBase {
|
||||
const string EmbedHelpField1 = $"`/help` - {HelpHelp}\n"
|
||||
public class UserCommands : CommandsBase {
|
||||
const string EmbedHelpField1 =
|
||||
$"`/help` - {HelpHelp}\n"
|
||||
+ $"`/list` - {HelpList}\n"
|
||||
+ $"`/set` - {HelpSet}\n"
|
||||
+ $"`/remove` - {HelpRemove}";
|
||||
const string EmbedHelpField2 = $"`/set-for` - {HelpSetFor}\n`/remove-for` - {HelpRemoveFor}";
|
||||
const string EmbedHelpField2 =
|
||||
$"`/config use-12hour` - {ConfigCommands.HelpUse12}\n"
|
||||
+ $"`/set-for` - {HelpSetFor}\n"
|
||||
+ $"`/remove-for` - {HelpRemoveFor}";
|
||||
|
||||
#region Help strings
|
||||
const string HelpHelp = "Displays a list of available bot commands.";
|
||||
|
@ -67,23 +71,25 @@ public class ApplicationCommands : CommandsBase {
|
|||
await RespondAsync(":x: Nothing to show. Register your time zones with the bot using the `/set` command.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Order times by popularity to limit how many are shown, group by printed name
|
||||
var sortedlist = new SortedDictionary<string, List<ulong>>();
|
||||
var ampm = db.GuildSettings.Where(s => s.GuildId == Context.Guild.Id).SingleOrDefault()?.Use12HourTime ?? false;
|
||||
foreach ((string area, List<ulong> users) in userlist.OrderByDescending(o => o.Value.Count).Take(20)) {
|
||||
// Filter further to top 20 distinct timezones, even if they are not displayed in the final result
|
||||
var areaprint = TzPrint(area);
|
||||
var areaprint = TzPrint(area, ampm);
|
||||
if (!sortedlist.ContainsKey(areaprint)) sortedlist.Add(areaprint, new List<ulong>());
|
||||
sortedlist[areaprint].AddRange(users);
|
||||
}
|
||||
|
||||
const int MaxSingleLineLength = 750;
|
||||
const int MaxSingleOutputLength = 900;
|
||||
const int MaxSingleOutputLength = 3000;
|
||||
|
||||
// Build zone listings with users
|
||||
var outputlines = new List<string>();
|
||||
foreach ((string area, List<ulong> users) in sortedlist) {
|
||||
var buffer = new StringBuilder();
|
||||
buffer.Append(area[4..] + ": ");
|
||||
buffer.Append(area[6..] + ": ");
|
||||
bool empty = true;
|
||||
foreach (var userid in users) {
|
||||
var userinstance = Context.Guild.GetUser(userid);
|
||||
|
@ -137,7 +143,8 @@ public class ApplicationCommands : CommandsBase {
|
|||
return;
|
||||
}
|
||||
|
||||
var resulttext = TzPrint(result)[4..] + ": " + FormatName(parameter);
|
||||
var ampm = db.GuildSettings.Where(s => s.GuildId == Context.Guild.Id).SingleOrDefault()?.Use12HourTime ?? false;
|
||||
var resulttext = TzPrint(result, ampm)[6..] + ": " + FormatName(parameter);
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDescription(resulttext).Build());
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ public class BotDatabaseContext : DbContext {
|
|||
}
|
||||
|
||||
public DbSet<UserEntry> UserEntries { get; set; } = null!;
|
||||
public DbSet<GuildConfiguration> GuildSettings { get; set; } = null!;
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder
|
||||
|
@ -24,9 +25,8 @@ public class BotDatabaseContext : DbContext {
|
|||
.UseSnakeCaseNamingConvention();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||
modelBuilder.Entity<UserEntry>(entity => {
|
||||
entity.HasKey(e => new { e.GuildId, e.UserId }).HasName("userdata_pkey");
|
||||
});
|
||||
modelBuilder.Entity<UserEntry>().HasKey(e => new { e.GuildId, e.UserId }).HasName("userdata_pkey");
|
||||
modelBuilder.Entity<GuildConfiguration>().Property(p => p.Use12HourTime).HasDefaultValue(false);
|
||||
}
|
||||
|
||||
#region Helper methods / abstractions
|
||||
|
|
9
Data/GuildConfiguration.cs
Normal file
9
Data/GuildConfiguration.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace WorldTime.Data;
|
||||
public class GuildConfiguration {
|
||||
[Key]
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public bool Use12HourTime { get; set; }
|
||||
}
|
69
Data/Migrations/20230115041447_Add12HrSetting.Designer.cs
generated
Normal file
69
Data/Migrations/20230115041447_Add12HrSetting.Designer.cs
generated
Normal file
|
@ -0,0 +1,69 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using WorldTime.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WorldTime.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(BotDatabaseContext))]
|
||||
[Migration("20230115041447_Add12HrSetting")]
|
||||
partial class Add12HrSetting
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.1")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WorldTime.Data.GuildConfiguration", b =>
|
||||
{
|
||||
b.Property<decimal>("GuildId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("guild_id");
|
||||
|
||||
b.Property<bool>("Use12HourTime")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("use12hour_time");
|
||||
|
||||
b.HasKey("GuildId")
|
||||
.HasName("pk_guild_settings");
|
||||
|
||||
b.ToTable("guild_settings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WorldTime.Data.UserEntry", b =>
|
||||
{
|
||||
b.Property<long>("GuildId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("guild_id");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("user_id");
|
||||
|
||||
b.Property<string>("TimeZone")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("zone");
|
||||
|
||||
b.HasKey("GuildId", "UserId")
|
||||
.HasName("userdata_pkey");
|
||||
|
||||
b.ToTable("userdata", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
33
Data/Migrations/20230115041447_Add12HrSetting.cs
Normal file
33
Data/Migrations/20230115041447_Add12HrSetting.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WorldTime.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Add12HrSetting : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "guild_settings",
|
||||
columns: table => new
|
||||
{
|
||||
guildid = table.Column<decimal>(name: "guild_id", type: "numeric(20,0)", nullable: false),
|
||||
use12hourtime = table.Column<bool>(name: "use12hour_time", type: "boolean", nullable: false, defaultValue: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_guild_settings", x => x.guildid);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "guild_settings");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,11 +16,30 @@ namespace WorldTime.Data.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.6")
|
||||
.HasAnnotation("ProductVersion", "7.0.1")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WorldTime.Data.GuildConfiguration", b =>
|
||||
{
|
||||
b.Property<decimal>("GuildId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("guild_id");
|
||||
|
||||
b.Property<bool>("Use12HourTime")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("use12hour_time");
|
||||
|
||||
b.HasKey("GuildId")
|
||||
.HasName("pk_guild_settings");
|
||||
|
||||
b.ToTable("guild_settings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WorldTime.Data.UserEntry", b =>
|
||||
{
|
||||
b.Property<long>("GuildId")
|
||||
|
|
Loading…
Reference in a new issue