Skip to content

Commit

Permalink
Record guild member count (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pasi4K5 authored Dec 7, 2024
2 parents e0fe521 + 6f6f121 commit b2732be
Show file tree
Hide file tree
Showing 40 changed files with 1,154 additions and 30 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@ logs/
*.conf
*.json
.env

DesignTimeNumerousDbContextFactory.cs
4 changes: 3 additions & 1 deletion src/Numerous.Bot/BotServiceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using Microsoft.Extensions.DependencyInjection;
using Numerous.Bot.Discord;
using Numerous.Bot.Discord.Events;
using Numerous.Bot.Discord.Interactions;
using Numerous.Bot.Discord.Services;
using Numerous.Bot.Discord.Services.Attachments;
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Exclusive;
using Numerous.Bot.Osu;
Expand All @@ -28,6 +29,7 @@ public static void Configure(IServiceCollection services)
services.AddSingleton<DiscordEventHandler>();
services.AddTransient<EmbedBuilders>();
services.AddSingleton<IFileService, FileService>();
services.AddTransient<GuildStatsService>();
services.AddHostedService<InteractionHandler>();
services.AddHostedService<MapFeedService>();
services.AddHostedService<MessageResponder>();
Expand Down
2 changes: 2 additions & 0 deletions src/Numerous.Bot/Discord/Events/DiscordEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using Discord.WebSocket;
using Numerous.Bot.Discord.Services;
using Numerous.Bot.Discord.Services.Attachments;
using Numerous.Bot.Util;
using Numerous.Bot.Web.Osu;
using Numerous.Common.Config;
Expand Down
1 change: 1 addition & 0 deletions src/Numerous.Bot/Discord/Events/EventHandler.Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using Discord.WebSocket;
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Util;
using Serilog;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System.Net;
using Discord;
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Util;
using Refit;

Expand Down
1 change: 1 addition & 0 deletions src/Numerous.Bot/Discord/Events/MessageResponder.Ban.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Discord;
using Discord.Net;
using Discord.WebSocket;
using Numerous.Bot.Discord.Util;
using Numerous.Common.Util;

namespace Numerous.Bot.Discord.Events;
Expand Down
2 changes: 1 addition & 1 deletion src/Numerous.Bot/Discord/Events/MessageResponder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using Discord.WebSocket;
using Numerous.Common;
using Numerous.Common.Services;

namespace Numerous.Bot.Discord.Events;

Expand Down
3 changes: 2 additions & 1 deletion src/Numerous.Bot/Discord/Events/MudaeMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

using Discord;
using Discord.WebSocket;
using Numerous.Common;
using Numerous.Bot.Discord.Util;
using Numerous.Common.Services;

namespace Numerous.Bot.Discord.Events;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Util;
using Numerous.Common.Util;

namespace Numerous.Bot.Discord.Interactions.Commands.Admin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Util;
using Numerous.Database.Context;

namespace Numerous.Bot.Discord.Interactions.Commands.Config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Services;
using Numerous.Common.Enums;

namespace Numerous.Bot.Discord.Interactions.Commands.Config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Services;
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Util;
using Numerous.Database.Context;
using Numerous.Database.Dtos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Util;
using Numerous.Database.Context;

namespace Numerous.Bot.Discord.Interactions.Commands;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Services.Attachments;
using Numerous.Bot.Util;
using Numerous.Common.Util;
using Numerous.Database.Context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Discord.Interactions;
using Discord.WebSocket;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Util;
using Numerous.Common.Util;
using Numerous.Database.Context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Discord;
using Discord.Interactions;
using JetBrains.Annotations;
using Numerous.Bot.Discord.Services;
using Numerous.Common.Config;
using Numerous.Common.Enums;
using Numerous.Database.Context;
Expand Down
3 changes: 2 additions & 1 deletion src/Numerous.Bot/Discord/Interactions/InteractionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
using Discord;
using Discord.Interactions;
using Discord.WebSocket;
using Numerous.Common;
using Numerous.Bot.Discord.Util;
using Numerous.Common.Config;
using Numerous.Common.Services;
using Numerous.Common.Util;
using Serilog;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Numerous.Bot.Services;
using Numerous.Common.Config;

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Services.Attachments;

public sealed class AttachmentService(IConfigProvider cfgProvider, IFileService files)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using Discord;

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Services.Attachments;

public readonly record struct FileAttachmentInfo(string Path, string FileName)
{
Expand Down
38 changes: 38 additions & 0 deletions src/Numerous.Bot/Discord/Services/GuildStatsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) Pasi4K5 <https://www.github.com/Pasi4K5>
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using Discord.WebSocket;
using Numerous.Database.Context;

namespace Numerous.Bot.Discord.Services;

public sealed class GuildStatsService(
DiscordSocketClient client,
IUnitOfWorkFactory uowFactory
)
{
public void Start()
{
client.UserJoined += async gu => await UpdateStatsAsync(gu.Guild);
client.UserLeft += async (g, _) => await UpdateStatsAsync(g);
}

private async Task UpdateStatsAsync(SocketGuild guild)
{
var now = DateTimeOffset.UtcNow;
await guild.DownloadUsersAsync();

await using var uow = uowFactory.Create();

await uow.GuildStats.InsertAsync(new()
{
GuildId = guild.Id,
Timestamp = now,
MemberCount = guild.DownloadedMemberCount,
});

await uow.CommitAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
using osu.Game.Beatmaps;
using Serilog;

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Services;

public sealed class OsuVerifier(
IHost host,
Expand All @@ -24,7 +24,7 @@ public sealed class OsuVerifier(
IOsuApiRepository osuApi
)
{
public Task StartAsync(CancellationToken ct)
public void Start(CancellationToken ct)
{
host.Services.UseScheduler(scheduler => scheduler.ScheduleAsync(async () => await AssignAllRolesAsync(ct))
.EveryMinute()
Expand All @@ -34,8 +34,6 @@ public Task StartAsync(CancellationToken ct)
await GetOsuUsersAsync(user, ct),
await GetGroupRoleMappingsAsync(user.Guild, ct)
);

return Task.CompletedTask;
}

public async Task AssignAllRolesAsync(SocketGuild guild, CancellationToken ct = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
using Numerous.Database.Dtos;
using Timer = System.Timers.Timer;

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Services;

public sealed class ReminderService(IHost host, IUnitOfWorkFactory uowFactory, DiscordSocketClient client)
{
private static readonly TimeSpan _cacheInterval = TimeSpan.FromHours(1) + TimeSpan.FromMinutes(1);

private readonly Dictionary<uint, Timer> _timerCache = new();

public void StartAsync(CancellationToken ct)
public void Start(CancellationToken ct)
{
host.Services.UseScheduler(s =>
s.ScheduleAsync(() => CacheRemindersAsync(ct)).Hourly().RunOnceAtStart().PreventOverlapping(nameof(ReminderService))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Util;

internal static class Constants
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Discord;
using Discord.WebSocket;

namespace Numerous.Bot.Discord;
namespace Numerous.Bot.Discord.Util;

public static partial class DiscordExtensions
{
Expand Down
2 changes: 1 addition & 1 deletion src/Numerous.Bot/Exclusive/StarReactPreventionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

using Discord;
using Discord.WebSocket;
using Numerous.Common;
using Numerous.Common.Config;
using Numerous.Common.Services;

namespace Numerous.Bot.Exclusive;

Expand Down
2 changes: 1 addition & 1 deletion src/Numerous.Bot/Osu/MapFeedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Numerous.Bot.Discord.Util;
using Numerous.Bot.Util;
using Numerous.Bot.Web.Osu;
using Numerous.Common;
using Numerous.Common.Services;
using Numerous.Common.Util;
using Numerous.Database.Context;
using osu.Game.Beatmaps;
Expand Down
12 changes: 7 additions & 5 deletions src/Numerous.Bot/Services/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

using Discord;
using Discord.WebSocket;
using Numerous.Bot.Discord;
using Numerous.Bot.Discord.Events;
using Numerous.Common;
using Numerous.Bot.Discord.Services;
using Numerous.Common.Config;
using Numerous.Common.Services;
using Numerous.Database.Context;

namespace Numerous.Bot.Services;
Expand All @@ -19,7 +19,8 @@ public sealed class Startup(
IUnitOfWorkFactory uowFactory,
ReminderService reminderService,
OsuVerifier verifier,
DiscordEventHandler eventHandler
DiscordEventHandler eventHandler,
GuildStatsService guildStatsService
) : HostedService
{
private Config Cfg => cfgProvider.Get();
Expand All @@ -46,9 +47,10 @@ await uow.Guilds.InsertAsync(new()

await uow.CommitAsync(ct);

reminderService.StartAsync(ct);
await verifier.StartAsync(ct);
reminderService.Start(ct);
verifier.Start(ct);
eventHandler.Start();
guildStatsService.Start();
}

public override async Task StopAsync(CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using Microsoft.Extensions.Hosting;

namespace Numerous.Common;
namespace Numerous.Common.Services;

public abstract class HostedService : IHostedService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

using DotNetEnv;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
Expand All @@ -12,13 +13,18 @@ namespace Numerous.Database.Context;
[UsedImplicitly]
public sealed class DesignTimeNumerousDbContextFactory : IDesignTimeDbContextFactory<NumerousDbContext>
{
private const string ConnectionString =
"Host=YOUR_HOST;Username=YOUR_USERNAME;Password=YOUR_PASSWORD;Database=numerous";

public NumerousDbContext CreateDbContext(string[] args)
{
Env.TraversePath().Load(".env");

var connectionString =
$"Host=localhost;"
+ $"Username={Env.GetString("POSTGRES_USER")};"
+ $"Password={Env.GetString("POSTGRES_PASSWORD")};"
+ $"Database={Env.GetString("POSTGRES_DB")}";

var optionsBuilder = new DbContextOptionsBuilder<NumerousDbContext>()
.UseNpgsql(ConnectionString);
.UseNpgsql(connectionString);

return new NumerousDbContext(optionsBuilder.Options);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Numerous.Database/Context/UnitOfWork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface IUnitOfWork : IDisposable, IAsyncDisposable
IDiscordUserRepository DiscordUsers { get; }
IGroupRoleMappingRepository GroupRoleMappings { get; }
IGuildRepository Guilds { get; }
IGuildStatsEntryRepository GuildStats { get; }
IIdRepository<LocalBeatmapDto, Guid> LocalBeatmaps { get; }
IIdRepository<JoinMessageDto, ulong> JoinMessages { get; }
IOnlineBeatmapRepository OnlineBeatmaps { get; }
Expand All @@ -45,6 +46,7 @@ public sealed class UnitOfWork(IDbContextFactory<NumerousDbContext> contextProvi
public IDiscordUserRepository DiscordUsers => new DiscordUserRepository(_context, mapper);
public IGroupRoleMappingRepository GroupRoleMappings => new GroupRoleMappingRepository(_context, mapper);
public IGuildRepository Guilds => new GuildRepository(_context, mapper);
public IGuildStatsEntryRepository GuildStats => new GuildStatsEntryRepository(_context, mapper);
public IIdRepository<LocalBeatmapDto, Guid> LocalBeatmaps => new IdRepository<DbLocalBeatmap, LocalBeatmapDto, Guid>(_context, mapper);
public IIdRepository<JoinMessageDto, ulong> JoinMessages => new IdRepository<DbJoinMessage, JoinMessageDto, ulong>(_context, mapper);
public IOnlineBeatmapRepository OnlineBeatmaps => new OnlineBeatmapRepository(_context, mapper);
Expand Down
3 changes: 3 additions & 0 deletions src/Numerous.Database/DbMapperProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public DbMapperProfile()
CreateMap<DbGuild, GuildDto>();
CreateMap<GuildDto, DbGuild>();

CreateMap<DbGuildStatsEntry, GuildStatsEntryDto>();
CreateMap<GuildStatsEntryDto, DbGuildStatsEntry>();

CreateMap<DbJoinMessage, JoinMessageDto>();
CreateMap<JoinMessageDto, DbJoinMessage>();

Expand Down
Loading

0 comments on commit b2732be

Please sign in to comment.