Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
**/obj
appsettings.Development.json
.user
**/*.user
**/*.user
.fake
27 changes: 27 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/CosmosProposalBot/bin/Debug/net6.0/CosmosProposalBot.dll",
"args": [],
"cwd": "${workspaceFolder}/CosmosProposalBot",
"console": "integratedTerminal",
"stopAtEntry": false,
"env": {
"DOTNET_ENVIRONMENT": "Development"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files.exclude": {
".vs/**": true,
"**/bin": true,
"**/obj": true
},
}
41 changes: 41 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/CosmosProposalBot/CosmosProposalBot.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/CosmosProposalBot/CosmosProposalBot.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/CosmosProposalBot/CosmosProposalBot.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
74 changes: 9 additions & 65 deletions CosmosProposalBot/Modules/SubscribeModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,75 +30,19 @@ public SubscribeModule( ILogger<SubscribeModule> logger,

[SlashCommand("supported-chains", "Lists all chains that the bot currently supports")]
public async Task SupportedChains()
{
try
{
await DeferAsync();

await using var scope = _serviceProvider.CreateAsyncScope();
var dbContext = scope.ServiceProvider.GetRequiredService<CopsDbContext>();
var guildSpecificChains = dbContext.Chains
.Where( c => c.CustomForGuildId == Context.Guild.Id )
.Select( c => $"`{c.Name}`" )
.ToList();

var standardChains = _options.Value.SupportedChains
.Select( c => $"`{c}`" );

var eb = new EmbedBuilder()
.WithTitle( "Supported Chains" )
.WithFields(
new EmbedFieldBuilder()
.WithName("Standard")
.WithValue(string.Join(", ", standardChains)),
new EmbedFieldBuilder()
.WithName("Custom")
.WithValue(string.Join(", ", guildSpecificChains)));

await FollowupAsync($"", embed: eb.Build());
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}
=> await _serviceProvider.CreateScope().ServiceProvider
.GetRequiredService<ISubscribeModuleActions>()
.SupportedChains( Context );

[SlashCommand( "private", "Subscribes to DMs about proposals for a given chain" )]
public async Task SubscribePrivate( string chainName )
{
try
{
await DeferAsync( ephemeral: true );

await using var scope = _serviceProvider.CreateAsyncScope();
var subscriptionHelper = scope.ServiceProvider.GetRequiredService<ISubscriptionHelper>();

await subscriptionHelper.SubscribeDm( Context, chainName );
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}
=> await _serviceProvider.CreateScope().ServiceProvider
.GetRequiredService<ISubscribeModuleActions>()
.SubscribePrivate( Context, chainName );

[SlashCommand( "channel", "Subscribes to channel notifications about proposals for a given chain" )]
public async Task SubscribeChannel( string chainName )
{
try
{
await DeferAsync();

await using var scope = _serviceProvider.CreateAsyncScope();
var subscriptionHelper = scope.ServiceProvider.GetRequiredService<ISubscriptionHelper>();

await subscriptionHelper.SubscribeChannel( Context, chainName );
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}
=> await _serviceProvider.CreateScope().ServiceProvider
.GetRequiredService<ISubscribeModuleActions>()
.SubscribeChannel( Context, chainName );
}
106 changes: 106 additions & 0 deletions CosmosProposalBot/Util/SubscribeModuleActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System.Text;
using CosmosProposalBot.Configuration;
using CosmosProposalBot.Data;
using CosmosProposalBot.Data.Model;
using CosmosProposalBot.Util;
using Discord;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace CosmosProposalBot.Modules;

public interface ISubscribeModuleActions
{
Task SupportedChains(IInteractionContext context);
Task SubscribePrivate( IInteractionContext context, string chainName );
Task SubscribeChannel( IInteractionContext context, string chainName );
}

public class SubscribeModuleActions : ISubscribeModuleActions
{
private readonly ILogger<SubscribeModuleActions> _logger;
private readonly IOptions<BotOptions> _options;
private readonly IServiceProvider _serviceProvider;

public SubscribeModuleActions( ILogger<SubscribeModuleActions> logger,
IOptions<BotOptions> options,
IServiceProvider serviceProvider)
{
_logger = logger;
_options = options;
_serviceProvider = serviceProvider;
}

public async Task SupportedChains(IInteractionContext context)
{
try
{
await context.Interaction.DeferAsync();

await using var scope = _serviceProvider.CreateAsyncScope();
var dbContext = scope.ServiceProvider.GetRequiredService<CopsDbContext>();
var guildSpecificChains = dbContext.Chains
.Where( c => c.CustomForGuildId == context.Guild.Id )
.Select( c => $"`{c.Name}`" )
.ToList();

var standardChains = _options.Value.SupportedChains
.Select( c => $"`{c}`" );

var eb = new EmbedBuilder()
.WithTitle( "Supported Chains" )
.WithFields(
new EmbedFieldBuilder()
.WithName("Standard")
.WithValue(string.Join(", ", standardChains)),
new EmbedFieldBuilder()
.WithName("Custom")
.WithValue(string.Join(", ", guildSpecificChains)));

await context.Interaction.FollowupAsync($"", embed: eb.Build());
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}

public async Task SubscribePrivate( IInteractionContext context, string chainName )
{
try
{
await context.Interaction.DeferAsync( ephemeral: true );

await using var scope = _serviceProvider.CreateAsyncScope();
var subscriptionHelper = scope.ServiceProvider.GetRequiredService<ISubscriptionHelper>();

await subscriptionHelper.SubscribeDm( context, chainName );
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}

public async Task SubscribeChannel( IInteractionContext context, string chainName )
{
try
{
await context.Interaction.DeferAsync();

await using var scope = _serviceProvider.CreateAsyncScope();
var subscriptionHelper = scope.ServiceProvider.GetRequiredService<ISubscriptionHelper>();

await subscriptionHelper.SubscribeChannel( context, chainName );
}
catch( Exception e )
{
Console.WriteLine( e );
throw;
}
}
}
32 changes: 32 additions & 0 deletions Tests/Util/SubscribeModuleActionsTest
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Threading.Tasks;
using AutoFixture;
using CosmosProposalBot.Modules;
using Discord;
using Moq;
using Xunit;

namespace Tests.Util;

public class SubscribeModuleActionsTest
{
private readonly IFixture _fixture = FixtureFactory.CreateFixture();
private SubscribeModuleActions _configModuleActions;
private Mock<IDiscordInteraction> _interactionMock;
private Mock<IInteractionContext> _interactionContextMock;

public SubscribeModuleActionsTest()
{
_interactionMock = _fixture.Freeze<Mock<IDiscordInteraction>>();
_interactionContextMock = _fixture.Freeze<Mock<IInteractionContext>>();
_interactionContextMock.Setup( m => m.Interaction )
.Returns( _interactionMock.Object );

_configModuleActions = _fixture.Create<SubscribeModuleActions>();
}

[Fact]
public async Task SupportedChains_Something()
{
System.Console.WriteLine("Hello World");
}
}