forked from adam/discord-bot-shtik
Compare commits
6 Commits
master
...
unified-co
Author | SHA1 | Date | |
---|---|---|---|
2ce4656ac5 | |||
56c71ee533 | |||
a337ca8a5f | |||
fc1e44e3dc | |||
f6b0a736cd | |||
a4c2ff1ea4 |
29
Behaver.cs
29
Behaver.cs
@ -17,6 +17,7 @@ public class Behaver
|
|||||||
private List<Account> SelfAccounts { get; set; } = new List<Account>();
|
private List<Account> SelfAccounts { get; set; } = new List<Account>();
|
||||||
private User SelfUser { get; set; }
|
private User SelfUser { get; set; }
|
||||||
public static List<vassago.Behavior.Behavior> Behaviors { get; private set; } = new List<vassago.Behavior.Behavior>();
|
public static List<vassago.Behavior.Behavior> Behaviors { get; private set; } = new List<vassago.Behavior.Behavior>();
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
internal Behaver()
|
internal Behaver()
|
||||||
{
|
{
|
||||||
var subtypes = AppDomain.CurrentDomain.GetAssemblies()
|
var subtypes = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
@ -44,7 +45,7 @@ public class Behaver
|
|||||||
public async Task<bool> ActOn(Message message)
|
public async Task<bool> ActOn(Message message)
|
||||||
{
|
{
|
||||||
//TODO: this is yet another hit to the database, and a big one. cache them in memory! there needs to be a feasibly-viewable amount, anyway.
|
//TODO: this is yet another hit to the database, and a big one. cache them in memory! there needs to be a feasibly-viewable amount, anyway.
|
||||||
var matchingUACs = Rememberer.MatchUACs(message);
|
var matchingUACs = r.MatchUACs(message);
|
||||||
message.TranslatedContent = message.Content;
|
message.TranslatedContent = message.Content;
|
||||||
foreach (var uacMatch in matchingUACs)
|
foreach (var uacMatch in matchingUACs)
|
||||||
{
|
{
|
||||||
@ -79,7 +80,7 @@ public class Behaver
|
|||||||
message.ActedOn = true;
|
message.ActedOn = true;
|
||||||
behaviorsActedOn.Add("generic question fallback");
|
behaviorsActedOn.Add("generic question fallback");
|
||||||
}
|
}
|
||||||
Rememberer.RememberMessage(message);
|
r.RememberMessage(message);
|
||||||
ForwardToKafka(message, behaviorsActedOn, matchingUACs);
|
ForwardToKafka(message, behaviorsActedOn, matchingUACs);
|
||||||
return message.ActedOn;
|
return message.ActedOn;
|
||||||
}
|
}
|
||||||
@ -117,7 +118,7 @@ public class Behaver
|
|||||||
|
|
||||||
internal bool IsSelf(Guid AccountId)
|
internal bool IsSelf(Guid AccountId)
|
||||||
{
|
{
|
||||||
var acc = Rememberer.SearchAccount(a => a.Id == AccountId);
|
var acc = r.SearchAccount(a => a.Id == AccountId);
|
||||||
|
|
||||||
return SelfAccounts.Any(acc => acc.Id == AccountId);
|
return SelfAccounts.Any(acc => acc.Id == AccountId);
|
||||||
}
|
}
|
||||||
@ -132,8 +133,8 @@ public class Behaver
|
|||||||
{
|
{
|
||||||
CollapseUsers(SelfUser, selfAccount.IsUser);
|
CollapseUsers(SelfUser, selfAccount.IsUser);
|
||||||
}
|
}
|
||||||
SelfAccounts = Rememberer.SearchAccounts(a => a.IsUser == SelfUser);
|
SelfAccounts = r.SearchAccounts(a => a.IsUser == SelfUser);
|
||||||
Rememberer.RememberAccount(selfAccount);
|
r.RememberAccount(selfAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CollapseUsers(User primary, User secondary)
|
public bool CollapseUsers(User primary, User secondary)
|
||||||
@ -147,18 +148,18 @@ public class Behaver
|
|||||||
a.IsUser = primary;
|
a.IsUser = primary;
|
||||||
}
|
}
|
||||||
secondary.Accounts.Clear();
|
secondary.Accounts.Clear();
|
||||||
var uacs = Rememberer.SearchUACs(u => u.Users.FirstOrDefault(u => u.Id == secondary.Id) != null);
|
var uacs = r.SearchUACs(u => u.Users.FirstOrDefault(u => u.Id == secondary.Id) != null);
|
||||||
if (uacs.Count() > 0)
|
if (uacs.Count() > 0)
|
||||||
{
|
{
|
||||||
foreach (var uac in uacs)
|
foreach (var uac in uacs)
|
||||||
{
|
{
|
||||||
uac.Users.RemoveAll(u => u.Id == secondary.Id);
|
uac.Users.RemoveAll(u => u.Id == secondary.Id);
|
||||||
uac.Users.Add(primary);
|
uac.Users.Add(primary);
|
||||||
Rememberer.RememberUAC(uac);
|
r.RememberUAC(uac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rememberer.ForgetUser(secondary);
|
r.ForgetUser(secondary);
|
||||||
Rememberer.RememberUser(primary);
|
r.RememberUser(primary);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private ProtocolInterface fetchInterface(Channel ch)
|
private ProtocolInterface fetchInterface(Channel ch)
|
||||||
@ -177,7 +178,7 @@ public class Behaver
|
|||||||
}
|
}
|
||||||
public async Task<int> SendMessage(Guid channelId, string text)
|
public async Task<int> SendMessage(Guid channelId, string text)
|
||||||
{
|
{
|
||||||
var channel = Rememberer.ChannelDetail(channelId);
|
var channel = r.ChannelDetail(channelId);
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
return 404;
|
return 404;
|
||||||
var iprotocol = fetchInterface(channel);
|
var iprotocol = fetchInterface(channel);
|
||||||
@ -189,7 +190,7 @@ public class Behaver
|
|||||||
public async Task<int> React(Guid messageId, string reaction)
|
public async Task<int> React(Guid messageId, string reaction)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"sanity check: behaver is reacting, {messageId}, {reaction}");
|
Console.WriteLine($"sanity check: behaver is reacting, {messageId}, {reaction}");
|
||||||
var message = Rememberer.MessageDetail(messageId);
|
var message = r.MessageDetail(messageId);
|
||||||
if (message == null)
|
if (message == null)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"message {messageId} not found");
|
Console.Error.WriteLine($"message {messageId} not found");
|
||||||
@ -212,7 +213,7 @@ public class Behaver
|
|||||||
}
|
}
|
||||||
public async Task<int> Reply(Guid messageId, string text)
|
public async Task<int> Reply(Guid messageId, string text)
|
||||||
{
|
{
|
||||||
var message = Rememberer.MessageDetail(messageId);
|
var message = r.MessageDetail(messageId);
|
||||||
if (message == null)
|
if (message == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"message {messageId} not found");
|
Console.WriteLine($"message {messageId} not found");
|
||||||
@ -228,7 +229,7 @@ public class Behaver
|
|||||||
}
|
}
|
||||||
public async Task<int> SendFile(Guid channelId, string path, string accompanyingText)
|
public async Task<int> SendFile(Guid channelId, string path, string accompanyingText)
|
||||||
{
|
{
|
||||||
var channel = Rememberer.ChannelDetail(channelId);
|
var channel = r.ChannelDetail(channelId);
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
return 404;
|
return 404;
|
||||||
var iprotocol = fetchInterface(channel);
|
var iprotocol = fetchInterface(channel);
|
||||||
@ -239,7 +240,7 @@ public class Behaver
|
|||||||
}
|
}
|
||||||
public async Task<int> SendFile(Guid channelId, string base64dData, string filename, string accompanyingText)
|
public async Task<int> SendFile(Guid channelId, string base64dData, string filename, string accompanyingText)
|
||||||
{
|
{
|
||||||
var channel = Rememberer.ChannelDetail(channelId);
|
var channel = r.ChannelDetail(channelId);
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
return 404;
|
return 404;
|
||||||
var iprotocol = fetchInterface(channel);
|
var iprotocol = fetchInterface(channel);
|
||||||
|
@ -12,6 +12,7 @@ public abstract class Behavior
|
|||||||
{
|
{
|
||||||
//recommendation: set up your UACs in your constructor.
|
//recommendation: set up your UACs in your constructor.
|
||||||
public abstract Task<bool> ActOn(Message message);
|
public abstract Task<bool> ActOn(Message message);
|
||||||
|
protected static Rememberer rememberer = Rememberer.Instance;
|
||||||
|
|
||||||
public virtual bool ShouldAct(Message message, List<UAC> matchedUACs)
|
public virtual bool ShouldAct(Message message, List<UAC> matchedUACs)
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ public class Ripcord: Behavior
|
|||||||
|
|
||||||
public Ripcord()
|
public Ripcord()
|
||||||
{
|
{
|
||||||
myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == uacID);
|
myUAC = rememberer.SearchUAC(uac => uac.OwnerId == uacID);
|
||||||
if (myUAC == null)
|
if (myUAC == null)
|
||||||
{
|
{
|
||||||
myUAC = new()
|
myUAC = new()
|
||||||
@ -26,7 +26,7 @@ public class Ripcord: Behavior
|
|||||||
Description = @"matching this means you can tell the bot to shutdown, now"
|
Description = @"matching this means you can tell the bot to shutdown, now"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Rememberer.RememberUAC(myUAC);
|
rememberer.RememberUAC(myUAC);
|
||||||
}
|
}
|
||||||
public override bool ShouldAct(Message message, List<UAC> matchedUACs)
|
public override bool ShouldAct(Message message, List<UAC> matchedUACs)
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ public class TwitchSummon : Behavior
|
|||||||
|
|
||||||
public TwitchSummon()
|
public TwitchSummon()
|
||||||
{
|
{
|
||||||
myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == uacID);
|
myUAC = rememberer.SearchUAC(uac => uac.OwnerId == uacID);
|
||||||
if (myUAC == null)
|
if (myUAC == null)
|
||||||
{
|
{
|
||||||
myUAC = new()
|
myUAC = new()
|
||||||
@ -26,7 +26,7 @@ public class TwitchSummon : Behavior
|
|||||||
Description = @"matching this means you can summon the bot <i>to</i> <b>any</b> twitch channel"
|
Description = @"matching this means you can summon the bot <i>to</i> <b>any</b> twitch channel"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Rememberer.RememberUAC(myUAC);
|
rememberer.RememberUAC(myUAC);
|
||||||
}
|
}
|
||||||
internal static TwitchInterface.TwitchInterface getAnyTwitchInterface()
|
internal static TwitchInterface.TwitchInterface getAnyTwitchInterface()
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using vassago.Models;
|
using vassago.Models;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
[StaticPlz]
|
[StaticPlz]
|
||||||
public class Webhook : Behavior
|
public class Webhook : Behavior
|
||||||
@ -24,20 +25,15 @@ public class Webhook : Behavior
|
|||||||
private ConcurrentDictionary<Guid, WebhookActionOrder> authedCache = new ConcurrentDictionary<Guid, WebhookActionOrder>();
|
private ConcurrentDictionary<Guid, WebhookActionOrder> authedCache = new ConcurrentDictionary<Guid, WebhookActionOrder>();
|
||||||
private HttpClient hc = new HttpClient();
|
private HttpClient hc = new HttpClient();
|
||||||
|
|
||||||
public static void SetupWebhooks(IConfigurationSection confSection)
|
public static void SetupWebhooks(IEnumerable<string> confSection)
|
||||||
{
|
{
|
||||||
configuredWebhooks = confSection.Get<List<vassago.Behavior.WebhookConf>>();
|
//configuredWebhooks = confSection.Get<List<vassago.Behavior.WebhookConf>>();
|
||||||
|
if(confSection != null) foreach (var confLine in confSection)
|
||||||
foreach (var conf in configuredWebhooks)
|
|
||||||
{
|
{
|
||||||
|
var conf = JsonConvert.DeserializeObject<WebhookConf>(confLine);
|
||||||
var confName = $"Webhook: {conf.Trigger}";
|
var confName = $"Webhook: {conf.Trigger}";
|
||||||
Console.WriteLine($"confName: {confName}; conf.uri: {conf.Uri}, conf.uacID: {conf.uacID}, conf.Method: {conf.Method}, conf.Headers: {conf.Headers?.Count() ?? 0}, conf.Content: {conf.Content}");
|
|
||||||
foreach (var kvp in conf.Headers)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{kvp[0]}: {kvp[1]}");
|
|
||||||
}
|
|
||||||
var changed = false;
|
var changed = false;
|
||||||
var myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == conf.uacID);
|
var myUAC = rememberer.SearchUAC(uac => uac.OwnerId == conf.uacID);
|
||||||
if (myUAC == null)
|
if (myUAC == null)
|
||||||
{
|
{
|
||||||
myUAC = new()
|
myUAC = new()
|
||||||
@ -47,7 +43,7 @@ public class Webhook : Behavior
|
|||||||
Description = conf.Description
|
Description = conf.Description
|
||||||
};
|
};
|
||||||
changed = true;
|
changed = true;
|
||||||
Rememberer.RememberUAC(myUAC);
|
rememberer.RememberUAC(myUAC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -63,7 +59,7 @@ public class Webhook : Behavior
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed)
|
||||||
Rememberer.RememberUAC(myUAC);
|
rememberer.RememberUAC(myUAC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +84,7 @@ public class Webhook : Behavior
|
|||||||
{
|
{
|
||||||
var webhookableMessageContent = message.Content.Substring(message.Content.IndexOf(triggerTarget) + triggerTarget.Length + 1);
|
var webhookableMessageContent = message.Content.Substring(message.Content.IndexOf(triggerTarget) + triggerTarget.Length + 1);
|
||||||
Console.WriteLine($"webhookable content: {webhookableMessageContent}");
|
Console.WriteLine($"webhookable content: {webhookableMessageContent}");
|
||||||
var uacConf = Rememberer.SearchUAC(uac => uac.OwnerId == wh.uacID);
|
var uacConf = rememberer.SearchUAC(uac => uac.OwnerId == wh.uacID);
|
||||||
if (uacConf.Users.Contains(message.Author.IsUser) || uacConf.Channels.Contains(message.Channel) || uacConf.AccountInChannels.Contains(message.Author))
|
if (uacConf.Users.Contains(message.Author.IsUser) || uacConf.Channels.Contains(message.Channel) || uacConf.AccountInChannels.Contains(message.Author))
|
||||||
{
|
{
|
||||||
Console.WriteLine("webhook UAC passed, preparing WebhookActionOrder");
|
Console.WriteLine("webhook UAC passed, preparing WebhookActionOrder");
|
||||||
@ -190,7 +186,7 @@ public class WebhookConf
|
|||||||
public Uri Uri { get; set; }
|
public Uri Uri { get; set; }
|
||||||
//public HttpMethod Method { get; set; }
|
//public HttpMethod Method { get; set; }
|
||||||
public Enumerations.HttpVerb Method { get; set; }
|
public Enumerations.HttpVerb Method { get; set; }
|
||||||
public List<List<string>> Headers { get; set; }
|
public List<string> Headers { get; set; }
|
||||||
public string Content { get; set; }
|
public string Content { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,17 @@ namespace vassago
|
|||||||
using vassago.TwitchInterface;
|
using vassago.TwitchInterface;
|
||||||
using vassago.ProtocolInterfaces.DiscordInterface;
|
using vassago.ProtocolInterfaces.DiscordInterface;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
internal class ConsoleService : BackgroundService
|
internal class ConsoleService : BackgroundService
|
||||||
{
|
{
|
||||||
public ConsoleService(IConfiguration aspConfig)
|
public ConsoleService(IConfiguration aspConfig)
|
||||||
{
|
{
|
||||||
Shared.DBConnectionString = aspConfig["DBConnectionString"];
|
Shared.DBConnectionString = aspConfig["DBConnectionString"];
|
||||||
Shared.SetupSlashCommands = aspConfig["SetupSlashCommands"]?.ToLower() == "true";
|
|
||||||
Shared.API_URL = new Uri(aspConfig["API_URL"]);
|
|
||||||
DiscordTokens = aspConfig.GetSection("DiscordTokens").Get<IEnumerable<string>>();
|
|
||||||
TwitchConfigs = aspConfig.GetSection("TwitchConfigs").Get<IEnumerable<TwitchConfig>>();
|
|
||||||
Conversion.Converter.Load(aspConfig["ExchangePairsLocation"]);
|
|
||||||
Telefranz.Configure(aspConfig["KafkaName"], aspConfig["KafkaBootstrap"]);
|
|
||||||
Console.WriteLine($"Telefranz.Configure({aspConfig["KafkaName"]}, {aspConfig["KafkaBootstrap"]});");
|
|
||||||
vassago.Behavior.Webhook.SetupWebhooks(aspConfig.GetSection("Webhooks"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<string> DiscordTokens { get; }
|
List<string> DiscordTokens;
|
||||||
IEnumerable<TwitchConfig> TwitchConfigs { get; }
|
List<TwitchConfig> TwitchConfigs;
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -32,14 +25,31 @@ namespace vassago
|
|||||||
var dbc = new ChattingContext();
|
var dbc = new ChattingContext();
|
||||||
await dbc.Database.MigrateAsync(cancellationToken);
|
await dbc.Database.MigrateAsync(cancellationToken);
|
||||||
|
|
||||||
|
var confEntity = dbc.Configurations.FirstOrDefault() ?? new Configuration();
|
||||||
|
if (dbc.Configurations.Count() == 0)
|
||||||
|
{
|
||||||
|
dbc.Configurations.Add(confEntity);
|
||||||
|
dbc.SaveChanges();
|
||||||
|
}
|
||||||
|
dbConfig(ref confEntity);
|
||||||
|
|
||||||
if (DiscordTokens?.Any() ?? false)
|
if (DiscordTokens?.Any() ?? false)
|
||||||
foreach (var dt in DiscordTokens)
|
foreach (var dt in DiscordTokens)
|
||||||
{
|
{
|
||||||
var d = new DiscordInterface();
|
var d = new DiscordInterface();
|
||||||
initTasks.Add(d.Init(dt));
|
initTasks.Add(Task.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d.Init(dt);
|
||||||
Shared.ProtocolList.Add(d);
|
Shared.ProtocolList.Add(d);
|
||||||
}
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
Console.Error.WriteLine($"couldn't initialize discord interface with token {dt}");
|
||||||
|
Console.Error.WriteLine(e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
if (TwitchConfigs?.Any() ?? false)
|
if (TwitchConfigs?.Any() ?? false)
|
||||||
foreach (var tc in TwitchConfigs)
|
foreach (var tc in TwitchConfigs)
|
||||||
{
|
{
|
||||||
@ -49,7 +59,21 @@ namespace vassago
|
|||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(initTasks.ToArray(), cancellationToken);
|
Task.WaitAll(initTasks.ToArray(), cancellationToken);
|
||||||
|
Console.WriteLine("init tasks are done");
|
||||||
|
}
|
||||||
|
private void dbConfig(ref vassago.Models.Configuration confEntity)
|
||||||
|
{
|
||||||
|
Shared.SetupSlashCommands = confEntity.SetupDiscordSlashCommands;
|
||||||
|
Shared.API_URL = new Uri(confEntity.reportedApiUrl);
|
||||||
|
DiscordTokens = confEntity.DiscordTokens;
|
||||||
|
TwitchConfigs = new List<TwitchConfig>();
|
||||||
|
if (confEntity.TwitchConfigs != null) foreach (var twitchConfString in confEntity.TwitchConfigs)
|
||||||
|
{
|
||||||
|
TwitchConfigs.Add(JsonConvert.DeserializeObject<TwitchConfig>(twitchConfString));
|
||||||
|
}
|
||||||
|
Conversion.Converter.Load(confEntity.ExchangePairsLocation);
|
||||||
|
Telefranz.Configure(confEntity.KafkaName, confEntity.KafkaBootstrap);
|
||||||
|
vassago.Behavior.Webhook.SetupWebhooks(confEntity.Webhooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
427
Migrations/20250628034005_ConfigInDatabase.Designer.cs
generated
Normal file
427
Migrations/20250628034005_ConfigInDatabase.Designer.cs
generated
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using vassago.Models;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace vassago.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ChattingContext))]
|
||||||
|
[Migration("20250628034005_ConfigInDatabase")]
|
||||||
|
partial class ConfigInDatabase
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "7.0.5")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore");
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AccountUAC", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("AccountInChannelsId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("UACsId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("AccountInChannelsId", "UACsId");
|
||||||
|
|
||||||
|
b.HasIndex("UACsId");
|
||||||
|
|
||||||
|
b.ToTable("AccountUAC");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ChannelUAC", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("ChannelsId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("UACsId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("ChannelsId", "UACsId");
|
||||||
|
|
||||||
|
b.HasIndex("UACsId");
|
||||||
|
|
||||||
|
b.ToTable("ChannelUAC");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("UACUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("UACsId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("UsersId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("UACsId", "UsersId");
|
||||||
|
|
||||||
|
b.HasIndex("UsersId");
|
||||||
|
|
||||||
|
b.ToTable("UACUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Account", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("IsBot")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<Guid?>("IsUserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Protocol")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("SeenInChannelId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IsUserId");
|
||||||
|
|
||||||
|
b.HasIndex("SeenInChannelId");
|
||||||
|
|
||||||
|
b.ToTable("Accounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Attachment", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Content")
|
||||||
|
.HasColumnType("bytea");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<decimal?>("ExternalId")
|
||||||
|
.HasColumnType("numeric(20,0)");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("MessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("Size")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Source")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("MessageId");
|
||||||
|
|
||||||
|
b.ToTable("Attachments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("ChannelType")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int?>("LewdnessFilterLevel")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<bool?>("LinksAllowed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<decimal?>("MaxAttachmentBytes")
|
||||||
|
.HasColumnType("numeric(20,0)");
|
||||||
|
|
||||||
|
b.Property<long?>("MaxTextChars")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int?>("MeannessFilterLevel")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ParentChannelId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Protocol")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool?>("ReactionsPossible")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentChannelId");
|
||||||
|
|
||||||
|
b.ToTable("Channels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Configuration", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<List<string>>("DiscordTokens")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<string>("ExchangePairsLocation")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("KafkaBootstrap")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("KafkaName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("SetupDiscordSlashCommands")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<List<string>>("TwitchConfigs")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<List<string>>("Webhooks")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<string>("reportedApiUrl")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Configurations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<bool>("ActedOn")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<Guid?>("AuthorId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ChannelId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Content")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("MentionsMe")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("Protocol")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Timestamp")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("TranslatedContent")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AuthorId");
|
||||||
|
|
||||||
|
b.HasIndex("ChannelId");
|
||||||
|
|
||||||
|
b.ToTable("Messages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.UAC", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Dictionary<string, string>>("CommandAlterations")
|
||||||
|
.HasColumnType("hstore");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid>("OwnerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Dictionary<string, string>>("Translations")
|
||||||
|
.HasColumnType("hstore");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UACs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AccountUAC", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.Account", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AccountInChannelsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("vassago.Models.UAC", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UACsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ChannelUAC", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.Channel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ChannelsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("vassago.Models.UAC", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UACsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("UACUser", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.UAC", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UACsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("vassago.Models.User", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsersId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Account", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.User", "IsUser")
|
||||||
|
.WithMany("Accounts")
|
||||||
|
.HasForeignKey("IsUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("vassago.Models.Channel", "SeenInChannel")
|
||||||
|
.WithMany("Users")
|
||||||
|
.HasForeignKey("SeenInChannelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.Navigation("IsUser");
|
||||||
|
|
||||||
|
b.Navigation("SeenInChannel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Attachment", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.Message", "Message")
|
||||||
|
.WithMany("Attachments")
|
||||||
|
.HasForeignKey("MessageId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.Navigation("Message");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.Channel", "ParentChannel")
|
||||||
|
.WithMany("SubChannels")
|
||||||
|
.HasForeignKey("ParentChannelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.Navigation("ParentChannel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("vassago.Models.Account", "Author")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AuthorId");
|
||||||
|
|
||||||
|
b.HasOne("vassago.Models.Channel", "Channel")
|
||||||
|
.WithMany("Messages")
|
||||||
|
.HasForeignKey("ChannelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.Navigation("Author");
|
||||||
|
|
||||||
|
b.Navigation("Channel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Messages");
|
||||||
|
|
||||||
|
b.Navigation("SubChannels");
|
||||||
|
|
||||||
|
b.Navigation("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Attachments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Accounts");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
Migrations/20250628034005_ConfigInDatabase.cs
Normal file
42
Migrations/20250628034005_ConfigInDatabase.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace vassago.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class ConfigInDatabase : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Configurations",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
DiscordTokens = table.Column<List<string>>(type: "text[]", nullable: true),
|
||||||
|
TwitchConfigs = table.Column<List<string>>(type: "text[]", nullable: true),
|
||||||
|
ExchangePairsLocation = table.Column<string>(type: "text", nullable: true),
|
||||||
|
SetupDiscordSlashCommands = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
Webhooks = table.Column<List<string>>(type: "text[]", nullable: true),
|
||||||
|
KafkaBootstrap = table.Column<string>(type: "text", nullable: true),
|
||||||
|
KafkaName = table.Column<string>(type: "text", nullable: true),
|
||||||
|
reportedApiUrl = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Configurations", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Configurations");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -188,6 +188,41 @@ namespace vassago.Migrations
|
|||||||
b.ToTable("Channels");
|
b.ToTable("Channels");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("vassago.Models.Configuration", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<List<string>>("DiscordTokens")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<string>("ExchangePairsLocation")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("KafkaBootstrap")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("KafkaName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("SetupDiscordSlashCommands")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<List<string>>("TwitchConfigs")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<List<string>>("Webhooks")
|
||||||
|
.HasColumnType("text[]");
|
||||||
|
|
||||||
|
b.Property<string>("reportedApiUrl")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Configurations");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
|
@ -11,6 +11,7 @@ public class ChattingContext : DbContext
|
|||||||
public DbSet<Message> Messages { get; set; }
|
public DbSet<Message> Messages { get; set; }
|
||||||
public DbSet<Account> Accounts { get; set; }
|
public DbSet<Account> Accounts { get; set; }
|
||||||
public DbSet<User> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<Configuration> Configurations {get; set;}
|
||||||
|
|
||||||
public ChattingContext(DbContextOptions<ChattingContext> options) : base(options) { }
|
public ChattingContext(DbContextOptions<ChattingContext> options) : base(options) { }
|
||||||
public ChattingContext() : base() { }
|
public ChattingContext() : base() { }
|
||||||
|
28
Models/Configuration.cs
Normal file
28
Models/Configuration.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
namespace vassago.Models;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using vassago.TwitchInterface;
|
||||||
|
using vassago.Behavior;
|
||||||
|
|
||||||
|
//TODO: it feels gross to have a *table* in a database that's intended to hold 1 **UND EXACTLY ONE** row, ever.
|
||||||
|
//but also it feels worse to scatter my configuraiton-y data across external files and the database.
|
||||||
|
|
||||||
|
public class Configuration
|
||||||
|
{
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public List<string> DiscordTokens { get; set; }
|
||||||
|
public List<string> TwitchConfigs { get; set; }
|
||||||
|
public string ExchangePairsLocation { get; set; } = "assets/exchangepairs.json"; //TODO: have this be "exchange API key", so you can have it continually update.
|
||||||
|
public bool SetupDiscordSlashCommands { get; set; } = false; //i'm kind of idealogically opposed to these.
|
||||||
|
public List<string> Webhooks { get; set; }
|
||||||
|
public string KafkaBootstrap { get; set; } = "http://localhost:9092";
|
||||||
|
public string KafkaName { get; set; } = "vassago";
|
||||||
|
public string reportedApiUrl { get; set; } = "http://localhost:5093/api";
|
||||||
|
}
|
@ -28,10 +28,13 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
private static readonly SemaphoreSlim discordChannelSetup = new(1, 1);
|
private static readonly SemaphoreSlim discordChannelSetup = new(1, 1);
|
||||||
private Channel protocolAsChannel;
|
private Channel protocolAsChannel;
|
||||||
public override Channel SelfChannel { get => protocolAsChannel; }
|
public override Channel SelfChannel { get => protocolAsChannel; }
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
|
||||||
public async Task Init(string config)
|
public async Task Init(string config)
|
||||||
{
|
{
|
||||||
var token = config;
|
var token = config;
|
||||||
|
Console.WriteLine($"going to validate token {token}");
|
||||||
|
Discord.TokenUtils.ValidateToken(TokenType.Bot, token);//throws an exception if invalid
|
||||||
await SetupDiscordChannel();
|
await SetupDiscordChannel();
|
||||||
client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.All });
|
client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.All });
|
||||||
|
|
||||||
@ -40,12 +43,18 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
Console.WriteLine(msg.ToString());
|
Console.WriteLine(msg.ToString());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
client.Connected += () => Task.Run(SelfConnected);
|
client.Connected += this.SelfConnected;
|
||||||
client.Ready += () => Task.Run(ClientReady);
|
client.Disconnected += this.ClientDisconnected;
|
||||||
|
client.Ready += this.ClientReady;
|
||||||
|
|
||||||
await client.LoginAsync(TokenType.Bot, token);
|
await client.LoginAsync(TokenType.Bot, token);
|
||||||
await client.StartAsync();
|
await client.StartAsync();
|
||||||
}
|
}
|
||||||
|
private async Task ClientDisconnected(Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("client disconnected!");
|
||||||
|
Console.WriteLine(e?.Message);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SetupDiscordChannel()
|
private async Task SetupDiscordChannel()
|
||||||
{
|
{
|
||||||
@ -53,7 +62,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
protocolAsChannel = r.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
||||||
if (protocolAsChannel == null)
|
if (protocolAsChannel == null)
|
||||||
{
|
{
|
||||||
protocolAsChannel = new Channel()
|
protocolAsChannel = new Channel()
|
||||||
@ -75,7 +84,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
Console.WriteLine($"discord, channel with id {protocolAsChannel.Id}, already exists");
|
Console.WriteLine($"discord, channel with id {protocolAsChannel.Id}, already exists");
|
||||||
}
|
}
|
||||||
protocolAsChannel.DisplayName = "discord (itself)";
|
protocolAsChannel.DisplayName = "discord (itself)";
|
||||||
protocolAsChannel = Rememberer.RememberChannel(protocolAsChannel);
|
protocolAsChannel = r.RememberChannel(protocolAsChannel);
|
||||||
Console.WriteLine($"protocol as channel addeed; {protocolAsChannel}");
|
Console.WriteLine($"protocol as channel addeed; {protocolAsChannel}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -192,7 +201,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
}
|
}
|
||||||
internal static vassago.Models.Attachment UpsertAttachment(IAttachment dAttachment)
|
internal static vassago.Models.Attachment UpsertAttachment(IAttachment dAttachment)
|
||||||
{
|
{
|
||||||
var a = Rememberer.SearchAttachment(ai => ai.ExternalId == dAttachment.Id)
|
var a = r.SearchAttachment(ai => ai.ExternalId == dAttachment.Id)
|
||||||
?? new vassago.Models.Attachment();
|
?? new vassago.Models.Attachment();
|
||||||
|
|
||||||
a.ContentType = dAttachment.ContentType;
|
a.ContentType = dAttachment.ContentType;
|
||||||
@ -200,12 +209,12 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
a.Filename = dAttachment.Filename;
|
a.Filename = dAttachment.Filename;
|
||||||
a.Size = dAttachment.Size;
|
a.Size = dAttachment.Size;
|
||||||
a.Source = new Uri(dAttachment.Url);
|
a.Source = new Uri(dAttachment.Url);
|
||||||
Rememberer.RememberAttachment(a);
|
r.RememberAttachment(a);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
internal Message UpsertMessage(IUserMessage dMessage)
|
internal Message UpsertMessage(IUserMessage dMessage)
|
||||||
{
|
{
|
||||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == Protocol)
|
var m = r.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == Protocol)
|
||||||
?? new()
|
?? new()
|
||||||
{
|
{
|
||||||
Protocol = Protocol
|
Protocol = Protocol
|
||||||
@ -231,13 +240,13 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
m.MentionsMe = (dMessage.Author.Id != client.CurrentUser.Id
|
m.MentionsMe = (dMessage.Author.Id != client.CurrentUser.Id
|
||||||
&& (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) > 0));
|
&& (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) > 0));
|
||||||
|
|
||||||
Rememberer.RememberMessage(m);
|
r.RememberMessage(m);
|
||||||
Console.WriteLine($"received message; author: {m.Author.DisplayName}, {m.Author.Id}. messageid:{m.Id}");
|
Console.WriteLine($"received message; author: {m.Author.DisplayName}, {m.Author.Id}. messageid:{m.Id}");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
internal Channel UpsertChannel(IMessageChannel channel)
|
internal Channel UpsertChannel(IMessageChannel channel)
|
||||||
{
|
{
|
||||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
Channel c = r.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
||||||
@ -290,7 +299,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
Channel parentChannel = null;
|
Channel parentChannel = null;
|
||||||
if (channel is IGuildChannel)
|
if (channel is IGuildChannel)
|
||||||
{
|
{
|
||||||
parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == Protocol);
|
parentChannel = r.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == Protocol);
|
||||||
if (parentChannel is null)
|
if (parentChannel is null)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("why am I still null?");
|
Console.Error.WriteLine("why am I still null?");
|
||||||
@ -311,7 +320,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
parentChannel.SubChannels.Add(c);
|
parentChannel.SubChannels.Add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = Rememberer.RememberChannel(c);
|
c = r.RememberChannel(c);
|
||||||
|
|
||||||
//Console.WriteLine($"no one knows how to make good tooling. c.users.first, which needs client currentuser id tostring. c: {c}, c.Users {c.Users}, client: {client}, client.CurrentUser: {client.CurrentUser}, client.currentUser.Id: {client.CurrentUser.Id}");
|
//Console.WriteLine($"no one knows how to make good tooling. c.users.first, which needs client currentuser id tostring. c: {c}, c.Users {c.Users}, client: {client}, client.CurrentUser: {client.CurrentUser}, client.currentUser.Id: {client.CurrentUser.Id}");
|
||||||
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == client.CurrentUser.Id.ToString());
|
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == client.CurrentUser.Id.ToString());
|
||||||
@ -324,7 +333,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
}
|
}
|
||||||
internal Channel UpsertChannel(IGuild channel)
|
internal Channel UpsertChannel(IGuild channel)
|
||||||
{
|
{
|
||||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
Channel c = r.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
||||||
@ -340,11 +349,11 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
c.SubChannels ??= [];
|
c.SubChannels ??= [];
|
||||||
c.MaxAttachmentBytes = channel.MaxUploadLimit;
|
c.MaxAttachmentBytes = channel.MaxUploadLimit;
|
||||||
|
|
||||||
return Rememberer.RememberChannel(c);
|
return r.RememberChannel(c);
|
||||||
}
|
}
|
||||||
internal static Account UpsertAccount(IUser discordUser, Channel inChannel)
|
internal static Account UpsertAccount(IUser discordUser, Channel inChannel)
|
||||||
{
|
{
|
||||||
var acc = Rememberer.SearchAccount(ui => ui.ExternalId == discordUser.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id);
|
var acc = r.SearchAccount(ui => ui.ExternalId == discordUser.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id);
|
||||||
Console.WriteLine($"upserting account, retrieved {acc?.Id}.");
|
Console.WriteLine($"upserting account, retrieved {acc?.Id}.");
|
||||||
if (acc != null)
|
if (acc != null)
|
||||||
{
|
{
|
||||||
@ -352,7 +361,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
}
|
}
|
||||||
acc ??= new Account()
|
acc ??= new Account()
|
||||||
{
|
{
|
||||||
IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == discordUser.Id.ToString() && a.Protocol == Protocol))
|
IsUser = r.SearchUser(u => u.Accounts.Any(a => a.ExternalId == discordUser.Id.ToString() && a.Protocol == Protocol))
|
||||||
?? new User()
|
?? new User()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -372,12 +381,12 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
{
|
{
|
||||||
Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
||||||
}
|
}
|
||||||
Rememberer.RememberAccount(acc);
|
r.RememberAccount(acc);
|
||||||
inChannel.Users ??= [];
|
inChannel.Users ??= [];
|
||||||
if (!inChannel.Users.Contains(acc))
|
if (!inChannel.Users.Contains(acc))
|
||||||
{
|
{
|
||||||
inChannel.Users.Add(acc);
|
inChannel.Users.Add(acc);
|
||||||
Rememberer.RememberChannel(inChannel);
|
r.RememberChannel(inChannel);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
@ -385,7 +394,7 @@ public class DiscordInterface : ProtocolInterface
|
|||||||
private static async Task<int> AttemptReact(IUserMessage msg, string e)
|
private static async Task<int> AttemptReact(IUserMessage msg, string e)
|
||||||
{
|
{
|
||||||
Console.WriteLine("discord attempting to react");
|
Console.WriteLine("discord attempting to react");
|
||||||
var c = Rememberer.SearchChannel(c => c.ExternalId == msg.Channel.Id.ToString());// db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id.ToString());
|
var c = r.SearchChannel(c => c.ExternalId == msg.Channel.Id.ToString());// db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id.ToString());
|
||||||
//var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides
|
//var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides
|
||||||
var preferredEmote = e;
|
var preferredEmote = e;
|
||||||
if (Emoji.TryParse(preferredEmote, out Emoji emoji))
|
if (Emoji.TryParse(preferredEmote, out Emoji emoji))
|
||||||
|
@ -21,6 +21,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
private Channel protocolAsChannel;
|
private Channel protocolAsChannel;
|
||||||
public override Channel SelfChannel { get => protocolAsChannel;}
|
public override Channel SelfChannel { get => protocolAsChannel;}
|
||||||
private Account selfAccountInProtocol;
|
private Account selfAccountInProtocol;
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
TwitchClient client;
|
TwitchClient client;
|
||||||
|
|
||||||
private async Task SetupTwitchChannel()
|
private async Task SetupTwitchChannel()
|
||||||
@ -29,7 +30,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
protocolAsChannel = r.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
||||||
if (protocolAsChannel == null)
|
if (protocolAsChannel == null)
|
||||||
{
|
{
|
||||||
protocolAsChannel = new Channel()
|
protocolAsChannel = new Channel()
|
||||||
@ -46,7 +47,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
SubChannels = []
|
SubChannels = []
|
||||||
};
|
};
|
||||||
protocolAsChannel.DisplayName = "twitch (itself)";
|
protocolAsChannel.DisplayName = "twitch (itself)";
|
||||||
protocolAsChannel = Rememberer.RememberChannel(protocolAsChannel);
|
protocolAsChannel = r.RememberChannel(protocolAsChannel);
|
||||||
Console.WriteLine($"protocol as channle added; {protocolAsChannel}");
|
Console.WriteLine($"protocol as channle added; {protocolAsChannel}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -139,7 +140,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
private Account UpsertAccount(string username, Channel inChannel)
|
private Account UpsertAccount(string username, Channel inChannel)
|
||||||
{
|
{
|
||||||
//Console.WriteLine($"upserting twitch account. username: {username}. inChannel: {inChannel?.Id}");
|
//Console.WriteLine($"upserting twitch account. username: {username}. inChannel: {inChannel?.Id}");
|
||||||
var acc = Rememberer.SearchAccount(ui => ui.ExternalId == username && ui.SeenInChannel.ExternalId == inChannel.ExternalId);
|
var acc = r.SearchAccount(ui => ui.ExternalId == username && ui.SeenInChannel.ExternalId == inChannel.ExternalId);
|
||||||
// Console.WriteLine($"upserting twitch account, retrieved {acc?.Id}.");
|
// Console.WriteLine($"upserting twitch account, retrieved {acc?.Id}.");
|
||||||
if (acc != null)
|
if (acc != null)
|
||||||
{
|
{
|
||||||
@ -147,7 +148,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
}
|
}
|
||||||
acc ??= new Account()
|
acc ??= new Account()
|
||||||
{
|
{
|
||||||
IsUser = Rememberer.SearchUser(
|
IsUser = r.SearchUser(
|
||||||
u => u.Accounts.Any(a => a.ExternalId == username && a.Protocol == Protocol))
|
u => u.Accounts.Any(a => a.ExternalId == username && a.Protocol == Protocol))
|
||||||
?? new vassago.Models.User()
|
?? new vassago.Models.User()
|
||||||
};
|
};
|
||||||
@ -168,19 +169,19 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
// {
|
// {
|
||||||
// Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
// Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
||||||
// }
|
// }
|
||||||
Rememberer.RememberAccount(acc);
|
r.RememberAccount(acc);
|
||||||
inChannel.Users ??= [];
|
inChannel.Users ??= [];
|
||||||
if (!inChannel.Users.Contains(acc))
|
if (!inChannel.Users.Contains(acc))
|
||||||
{
|
{
|
||||||
inChannel.Users.Add(acc);
|
inChannel.Users.Add(acc);
|
||||||
Rememberer.RememberChannel(inChannel);
|
r.RememberChannel(inChannel);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Channel UpsertChannel(string channelName)
|
private Channel UpsertChannel(string channelName)
|
||||||
{
|
{
|
||||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channelName
|
Channel c = r.SearchChannel(ci => ci.ExternalId == channelName
|
||||||
&& ci.Protocol == Protocol);
|
&& ci.Protocol == Protocol);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
@ -198,7 +199,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
c.Protocol = Protocol;
|
c.Protocol = Protocol;
|
||||||
c.ParentChannel = protocolAsChannel;
|
c.ParentChannel = protocolAsChannel;
|
||||||
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
||||||
c = Rememberer.RememberChannel(c);
|
c = r.RememberChannel(c);
|
||||||
|
|
||||||
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
||||||
if (selfAccountInChannel == null)
|
if (selfAccountInChannel == null)
|
||||||
@ -210,7 +211,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
}
|
}
|
||||||
private Channel UpsertDMChannel(string whisperWith)
|
private Channel UpsertDMChannel(string whisperWith)
|
||||||
{
|
{
|
||||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
Channel c = r.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
||||||
&& ci.Protocol == Protocol);
|
&& ci.Protocol == Protocol);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
@ -228,7 +229,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
c.Protocol = Protocol;
|
c.Protocol = Protocol;
|
||||||
c.ParentChannel = protocolAsChannel;
|
c.ParentChannel = protocolAsChannel;
|
||||||
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
||||||
c = Rememberer.RememberChannel(c);
|
c = r.RememberChannel(c);
|
||||||
|
|
||||||
var selfAccountInChannel = c.Users.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
var selfAccountInChannel = c.Users.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
||||||
if (selfAccountInChannel == null)
|
if (selfAccountInChannel == null)
|
||||||
@ -244,7 +245,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
//none of the features we care about are on it!
|
//none of the features we care about are on it!
|
||||||
private Message UpsertMessage(ChatMessage chatMessage)
|
private Message UpsertMessage(ChatMessage chatMessage)
|
||||||
{
|
{
|
||||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == chatMessage.Id && mi.Protocol == Protocol)
|
var m = r.SearchMessage(mi => mi.ExternalId == chatMessage.Id && mi.Protocol == Protocol)
|
||||||
?? new()
|
?? new()
|
||||||
{
|
{
|
||||||
Protocol = Protocol,
|
Protocol = Protocol,
|
||||||
@ -255,7 +256,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
m.Channel = UpsertChannel(chatMessage.Channel);
|
m.Channel = UpsertChannel(chatMessage.Channel);
|
||||||
m.Author = UpsertAccount(chatMessage.Username, m.Channel);
|
m.Author = UpsertAccount(chatMessage.Username, m.Channel);
|
||||||
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
||||||
Rememberer.RememberMessage(m);
|
r.RememberMessage(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
//n.b., I see you future adam. "we should unify these, they're redundant".
|
//n.b., I see you future adam. "we should unify these, they're redundant".
|
||||||
@ -264,7 +265,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
private Message UpsertMessage(WhisperMessage whisperMessage)
|
private Message UpsertMessage(WhisperMessage whisperMessage)
|
||||||
{
|
{
|
||||||
//WhisperMessage.Id corresponds to chatMessage.Id. \*eye twitch*
|
//WhisperMessage.Id corresponds to chatMessage.Id. \*eye twitch*
|
||||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == whisperMessage.MessageId && mi.Protocol == Protocol)
|
var m = r.SearchMessage(mi => mi.ExternalId == whisperMessage.MessageId && mi.Protocol == Protocol)
|
||||||
?? new()
|
?? new()
|
||||||
{
|
{
|
||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
@ -276,7 +277,7 @@ public class TwitchInterface : ProtocolInterface
|
|||||||
m.Channel = UpsertDMChannel(whisperMessage.Username);
|
m.Channel = UpsertDMChannel(whisperMessage.Username);
|
||||||
m.Author = UpsertAccount(whisperMessage.Username, m.Channel);
|
m.Author = UpsertAccount(whisperMessage.Username, m.Channel);
|
||||||
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
||||||
Rememberer.RememberMessage(m);
|
r.RememberMessage(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
Rememberer.cs
125
Rememberer.cs
@ -4,18 +4,38 @@ using System.Linq.Expressions;
|
|||||||
using vassago.Models;
|
using vassago.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
public static class Rememberer
|
public class Rememberer
|
||||||
{
|
{
|
||||||
private static readonly SemaphoreSlim dbAccessSemaphore = new(1, 1);
|
private readonly SemaphoreSlim dbAccessSemaphore = new(1, 1);
|
||||||
private static readonly ChattingContext db = new();
|
private readonly ChattingContext db = new();
|
||||||
private static List<Channel> channels;
|
private List<Channel> channels;
|
||||||
private static bool channelCacheDirty = true;
|
private bool channelCacheDirty = true;
|
||||||
|
private Rememberer() { }
|
||||||
|
private static Rememberer _instance = null;
|
||||||
|
public static Rememberer Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
|
||||||
private static void cacheChannels()
|
lock (instantiationLock)
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
_instance = new Rememberer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static readonly object instantiationLock = new();
|
||||||
|
|
||||||
|
private void cacheChannels()
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
channels = db.Channels.ToList();
|
channels = db.Channels.ToList();
|
||||||
Console.WriteLine($"caching channels. {channels.Count} channels retrieved");
|
|
||||||
foreach (Channel ch in channels)
|
foreach (Channel ch in channels)
|
||||||
{
|
{
|
||||||
if (ch.ParentChannelId != null)
|
if (ch.ParentChannelId != null)
|
||||||
@ -27,17 +47,13 @@ public static class Rememberer
|
|||||||
ch.ParentChannel.SubChannels.Add(ch);
|
ch.ParentChannel.SubChannels.Add(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ch.Messages?.Count > 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{ch.DisplayName} got {ch.Messages.Count} messages");
|
|
||||||
}
|
|
||||||
ch.SubChannels ??= [];
|
ch.SubChannels ??= [];
|
||||||
}
|
}
|
||||||
channelCacheDirty = false;
|
channelCacheDirty = false;
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account SearchAccount(Expression<Func<Account, bool>> predicate)
|
public Account SearchAccount(Expression<Func<Account, bool>> predicate)
|
||||||
{
|
{
|
||||||
Account toReturn;
|
Account toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -45,7 +61,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<Account> SearchAccounts(Expression<Func<Account, bool>> predicate)
|
public List<Account> SearchAccounts(Expression<Func<Account, bool>> predicate)
|
||||||
{
|
{
|
||||||
List<Account> toReturn;
|
List<Account> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -53,7 +69,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static Attachment SearchAttachment(Expression<Func<Attachment, bool>> predicate)
|
public Attachment SearchAttachment(Expression<Func<Attachment, bool>> predicate)
|
||||||
{
|
{
|
||||||
Attachment toReturn;
|
Attachment toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -61,13 +77,13 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static Channel SearchChannel(Func<Channel, bool> predicate)
|
public Channel SearchChannel(Func<Channel, bool> predicate)
|
||||||
{
|
{
|
||||||
if (channelCacheDirty)
|
if (channelCacheDirty)
|
||||||
Task.Run(() => cacheChannels()).Wait();
|
Task.Run(() => cacheChannels()).Wait();
|
||||||
return channels.FirstOrDefault(predicate);
|
return channels.FirstOrDefault(predicate);
|
||||||
}
|
}
|
||||||
public static Message SearchMessage(Expression<Func<Message, bool>> predicate)
|
public Message SearchMessage(Expression<Func<Message, bool>> predicate)
|
||||||
{
|
{
|
||||||
Message toReturn;
|
Message toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -75,7 +91,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<Message> SearchMessages(Expression<Func<Message, bool>> predicate)
|
public List<Message> SearchMessages(Expression<Func<Message, bool>> predicate)
|
||||||
{
|
{
|
||||||
List<Message> toReturn;
|
List<Message> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -83,7 +99,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static User SearchUser(Expression<Func<User, bool>> predicate)
|
public User SearchUser(Expression<Func<User, bool>> predicate)
|
||||||
{
|
{
|
||||||
User toReturn;
|
User toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -91,7 +107,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static void RememberAccount(Account toRemember)
|
public void RememberAccount(Account toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
toRemember.IsUser ??= new User { Accounts = [toRemember] };
|
toRemember.IsUser ??= new User { Accounts = [toRemember] };
|
||||||
@ -99,7 +115,7 @@ public static class Rememberer
|
|||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void RememberAttachment(Attachment toRemember)
|
public void RememberAttachment(Attachment toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
toRemember.Message ??= new Message() { Attachments = [toRemember] };
|
toRemember.Message ??= new Message() { Attachments = [toRemember] };
|
||||||
@ -107,7 +123,7 @@ public static class Rememberer
|
|||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static Channel RememberChannel(Channel toRemember)
|
public Channel RememberChannel(Channel toRemember)
|
||||||
{
|
{
|
||||||
if (channelCacheDirty)
|
if (channelCacheDirty)
|
||||||
Task.Run(() => cacheChannels()).Wait(); //so we always do 2 db trips?
|
Task.Run(() => cacheChannels()).Wait(); //so we always do 2 db trips?
|
||||||
@ -119,7 +135,7 @@ public static class Rememberer
|
|||||||
cacheChannels();
|
cacheChannels();
|
||||||
return toRemember;
|
return toRemember;
|
||||||
}
|
}
|
||||||
public static void RememberMessage(Message toRemember)
|
public void RememberMessage(Message toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
toRemember.Channel ??= new();
|
toRemember.Channel ??= new();
|
||||||
@ -133,21 +149,21 @@ public static class Rememberer
|
|||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void RememberUser(User toRemember)
|
public void RememberUser(User toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Users.Update(toRemember);
|
db.Users.Update(toRemember);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void ForgetAccount(Account toForget)
|
public void ForgetAccount(Account toForget)
|
||||||
{
|
{
|
||||||
var user = toForget.IsUser;
|
var user = toForget.IsUser;
|
||||||
var usersOnlyAccount = user.Accounts?.Count == 1;
|
var usersOnlyAccount = user.Accounts?.Count == 1;
|
||||||
|
|
||||||
if (usersOnlyAccount)
|
if (usersOnlyAccount)
|
||||||
{
|
{
|
||||||
Rememberer.ForgetUser(user);
|
ForgetUser(user);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -157,14 +173,14 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void ForgetAttachment(Attachment toForget)
|
public void ForgetAttachment(Attachment toForget)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Attachments.Remove(toForget);
|
db.Attachments.Remove(toForget);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void ForgetChannel(Channel toForget)
|
public void ForgetChannel(Channel toForget)
|
||||||
{
|
{
|
||||||
if (toForget.SubChannels?.Count > 0)
|
if (toForget.SubChannels?.Count > 0)
|
||||||
{
|
{
|
||||||
@ -187,28 +203,28 @@ public static class Rememberer
|
|||||||
channelCacheDirty = true;
|
channelCacheDirty = true;
|
||||||
cacheChannels();
|
cacheChannels();
|
||||||
}
|
}
|
||||||
public static void ForgetMessage(Message toForget)
|
public void ForgetMessage(Message toForget)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Messages.Remove(toForget);
|
db.Messages.Remove(toForget);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void ForgetUAC(UAC toForget)
|
public void ForgetUAC(UAC toForget)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.UACs.Remove(toForget);
|
db.UACs.Remove(toForget);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static void ForgetUser(User toForget)
|
public void ForgetUser(User toForget)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Users.Remove(toForget);
|
db.Users.Remove(toForget);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
}
|
}
|
||||||
public static List<Account> AccountsOverview()
|
public List<Account> AccountsOverview()
|
||||||
{
|
{
|
||||||
List<Account> toReturn;
|
List<Account> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -216,13 +232,16 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<Channel> ChannelsOverview()
|
///<summary>
|
||||||
|
///intentionally does not include Users; to help search for orphaned accounts.
|
||||||
|
///</summary>
|
||||||
|
public List<Channel> ChannelsOverview()
|
||||||
{
|
{
|
||||||
if (channelCacheDirty)
|
if (channelCacheDirty)
|
||||||
Task.Run(() => cacheChannels()).Wait();
|
Task.Run(() => cacheChannels()).Wait();
|
||||||
return channels;
|
return channels.ToList();
|
||||||
}
|
}
|
||||||
public static Account AccountDetail(Guid Id)
|
public Account AccountDetail(Guid Id)
|
||||||
{
|
{
|
||||||
Account toReturn;
|
Account toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -230,7 +249,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static Attachment AttachmentDetail(Guid Id)
|
public Attachment AttachmentDetail(Guid Id)
|
||||||
{
|
{
|
||||||
Attachment toReturn;
|
Attachment toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -238,16 +257,18 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static Channel ChannelDetail(Guid Id, bool messages = false)
|
public Channel ChannelDetail(Guid Id, bool accounts = true, bool messages = false)
|
||||||
{
|
{
|
||||||
if (channelCacheDirty)
|
if (channelCacheDirty)
|
||||||
Task.Run(() => cacheChannels()).Wait();
|
Task.Run(() => cacheChannels()).Wait();
|
||||||
var ch = channels.Find(c => c.Id == Id);
|
var ch = channels.Find(c => c.Id == Id);
|
||||||
|
if(accounts)
|
||||||
|
ch.Users = SearchAccounts(a => a.SeenInChannel == ch);
|
||||||
if (messages)
|
if (messages)
|
||||||
ch.Messages = SearchMessages(m => m.ChannelId == ch.Id);
|
ch.Messages = SearchMessages(m => m.ChannelId == ch.Id);
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
public static Message MessageDetail(Guid Id)
|
public Message MessageDetail(Guid Id)
|
||||||
{
|
{
|
||||||
Message toReturn;
|
Message toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -256,7 +277,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static UAC UACDetail(Guid Id)
|
public UAC UACDetail(Guid Id)
|
||||||
{
|
{
|
||||||
UAC toReturn;
|
UAC toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -264,7 +285,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static User UserDetail(Guid Id)
|
public User UserDetail(Guid Id)
|
||||||
{
|
{
|
||||||
User toReturn;
|
User toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -272,7 +293,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<User> UsersOverview()
|
public List<User> UsersOverview()
|
||||||
{
|
{
|
||||||
List<User> toReturn;
|
List<User> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -280,7 +301,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<UAC> UACsOverview()
|
public List<UAC> UACsOverview()
|
||||||
{
|
{
|
||||||
List<UAC> toReturn;
|
List<UAC> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -288,7 +309,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static UAC SearchUAC(Expression<Func<UAC, bool>> predicate)
|
public UAC SearchUAC(Expression<Func<UAC, bool>> predicate)
|
||||||
{
|
{
|
||||||
UAC toReturn;
|
UAC toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -297,7 +318,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static List<UAC> MatchUACs(Message message)
|
public List<UAC> MatchUACs(Message message)
|
||||||
{
|
{
|
||||||
var msgId = message.Id;
|
var msgId = message.Id;
|
||||||
var accId = message.Author.Id;
|
var accId = message.Author.Id;
|
||||||
@ -308,7 +329,7 @@ public static class Rememberer
|
|||||||
|| uac.Users.FirstOrDefault(usr => usr.Id == usrId) != null
|
|| uac.Users.FirstOrDefault(usr => usr.Id == usrId) != null
|
||||||
|| uac.Channels.FirstOrDefault(ch => ch.Id == chId) != null);
|
|| uac.Channels.FirstOrDefault(ch => ch.Id == chId) != null);
|
||||||
}
|
}
|
||||||
public static List<UAC> SearchUACs(Expression<Func<UAC, bool>> predicate)
|
public List<UAC> SearchUACs(Expression<Func<UAC, bool>> predicate)
|
||||||
{
|
{
|
||||||
List<UAC> toReturn;
|
List<UAC> toReturn;
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
@ -317,7 +338,7 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static void RememberUAC(UAC toRemember)
|
public void RememberUAC(UAC toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Update(toRemember);
|
db.Update(toRemember);
|
||||||
@ -326,4 +347,18 @@ public static class Rememberer
|
|||||||
if (toRemember.Channels?.Count() > 0)
|
if (toRemember.Channels?.Count() > 0)
|
||||||
cacheChannels();
|
cacheChannels();
|
||||||
}
|
}
|
||||||
|
public Configuration Configuration()
|
||||||
|
{
|
||||||
|
dbAccessSemaphore.Wait();
|
||||||
|
var toReturn = db.Configurations.FirstOrDefault();
|
||||||
|
dbAccessSemaphore.Release();
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
public void RememberConfiguration(Configuration conf)
|
||||||
|
{
|
||||||
|
dbAccessSemaphore.Wait();
|
||||||
|
db.Update(conf);
|
||||||
|
db.SaveChanges();
|
||||||
|
dbAccessSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@ namespace vassago.WebInterface.Controllers;
|
|||||||
|
|
||||||
public class ChannelsController() : Controller
|
public class ChannelsController() : Controller
|
||||||
{
|
{
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
public IActionResult Details(Guid id)
|
public IActionResult Details(Guid id)
|
||||||
{
|
{
|
||||||
var allChannels = Rememberer.ChannelsOverview();
|
var channel = r.ChannelDetail(id);
|
||||||
if (allChannels == null)
|
|
||||||
return Problem("no channels.");
|
|
||||||
|
|
||||||
var channel = allChannels.FirstOrDefault(u => u.Id == id);
|
|
||||||
if (channel == null)
|
if (channel == null)
|
||||||
{
|
{
|
||||||
return Problem($"couldn't find channle {id}");
|
return Problem($"couldn't find channle {id}");
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Console.WriteLine($"details.cshtml will have a channel; {channel}.");
|
||||||
|
}
|
||||||
var walker = channel;
|
var walker = channel;
|
||||||
while (walker != null)
|
while (walker != null)
|
||||||
{
|
{
|
||||||
|
129
WebInterface/Controllers/ConfigurationController.cs
Normal file
129
WebInterface/Controllers/ConfigurationController.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using vassago;
|
||||||
|
using vassago.Behavior;
|
||||||
|
using vassago.Models;
|
||||||
|
using vassago.WebInterface.Models;
|
||||||
|
using vassago.TwitchInterface;
|
||||||
|
|
||||||
|
namespace vassago.WebInterface.Controllers;
|
||||||
|
|
||||||
|
public class ConfigurationController() : Controller
|
||||||
|
{
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
var conf = r.Configuration() ?? new Configuration();
|
||||||
|
ViewData.Add("Serialized", JsonConvert.SerializeObject(conf));
|
||||||
|
return View(conf);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult Submit(Configuration incoming)
|
||||||
|
{
|
||||||
|
var conf = r.Configuration() ?? new Configuration();
|
||||||
|
conf.DiscordTokens = incoming.DiscordTokens;
|
||||||
|
conf.TwitchConfigs = incoming.TwitchConfigs;
|
||||||
|
conf.ExchangePairsLocation = incoming.ExchangePairsLocation;
|
||||||
|
conf.SetupDiscordSlashCommands = incoming.SetupDiscordSlashCommands;
|
||||||
|
conf.Webhooks = incoming.Webhooks;
|
||||||
|
conf.KafkaBootstrap = incoming.KafkaBootstrap;
|
||||||
|
conf.KafkaName = incoming.KafkaName;
|
||||||
|
conf.reportedApiUrl = incoming.reportedApiUrl;
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public IActionResult Error()
|
||||||
|
{
|
||||||
|
return View(new ErrorPageViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult AddDiscord(string newToken)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"adding discord, {newToken}");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
conf.DiscordTokens ??= [];
|
||||||
|
conf.DiscordTokens.Add(newToken);
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RemoveDiscord(int index)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removing discord[{index}]");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
if (conf.DiscordTokens?.Count <= index)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("error removing discord {index} from configuration, only have {conf.DiscordTokens?.Count}.");
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.DiscordTokens.RemoveAt(index);
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult AddTwitch(string newUsername, string newOauth)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"adding twitch, {newUsername}/{newOauth}");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
conf.TwitchConfigs ??= [];
|
||||||
|
var thisOne = new TwitchConfig()
|
||||||
|
{
|
||||||
|
username = newUsername,
|
||||||
|
oauth = newOauth
|
||||||
|
};
|
||||||
|
conf.TwitchConfigs.Add(JsonConvert.SerializeObject(thisOne));
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RemoveTwitch(int index)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removing twitch[{index}]");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
if (conf.TwitchConfigs?.Count <= index)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("error removing twitch {index} from configuration, only have {conf.TwitchConfigs?.Count}.");
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
conf.TwitchConfigs.RemoveAt(index);
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult AddWebhook(WebhookConf newWebhook)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"adding webhook, {newWebhook}");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
conf.Webhooks??= [];
|
||||||
|
conf.Webhooks.Add(JsonConvert.SerializeObject(newWebhook));
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RemoveWebhook(int index)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removing webhook[{index}]");
|
||||||
|
var conf = r.Configuration();
|
||||||
|
if (conf.Webhooks?.Count <= index)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("error removing webhook {index} from configuration, only have {conf.Webhooks?.Count}.");
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.Webhooks.RemoveAt(index);
|
||||||
|
r.RememberConfiguration(conf);
|
||||||
|
return RedirectToAction("Index", "Configuration");
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ namespace vassago.Controllers;
|
|||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<HomeController> _logger;
|
private readonly ILogger<HomeController> _logger;
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
|
||||||
public HomeController(ILogger<HomeController> logger)
|
public HomeController(ILogger<HomeController> logger)
|
||||||
{
|
{
|
||||||
@ -20,14 +21,16 @@ public class HomeController : Controller
|
|||||||
|
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
var allAccounts = Rememberer.AccountsOverview();
|
var allAccounts = r.AccountsOverview();
|
||||||
var allChannels = Rememberer.ChannelsOverview();
|
var allChannels = r.ChannelsOverview();
|
||||||
Console.WriteLine($"accounts: {allAccounts?.Count ?? 0}, channels: {allChannels?.Count ?? 0}");
|
Console.WriteLine($"accounts: {allAccounts?.Count ?? 0}, channels: {allChannels?.Count ?? 0}");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append('[');
|
sb.Append('[');
|
||||||
|
|
||||||
|
sb.Append($"{{\"text\": \"<a href=\\\"{Url.ActionLink(action: "Index", controller: "Configuration")}\\\">Configuration</a>\"}},");
|
||||||
|
|
||||||
//UACs
|
//UACs
|
||||||
var allUACs = Rememberer.UACsOverview();
|
var allUACs = r.UACsOverview();
|
||||||
var first = true;
|
var first = true;
|
||||||
if(allUACs.Any())
|
if(allUACs.Any())
|
||||||
{
|
{
|
||||||
@ -58,13 +61,13 @@ public class HomeController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
//users
|
//users
|
||||||
var users = Rememberer.UsersOverview();
|
var users = r.UsersOverview();
|
||||||
if(users.Any())
|
if(users.Any())
|
||||||
{
|
{
|
||||||
sb.Append(",{text: \"users\", expanded:true, nodes: [");
|
sb.Append(",{text: \"users\", expanded:true, nodes: [");
|
||||||
first=true;
|
first=true;
|
||||||
//refresh list; we'll be knocking them out again in serializeUser
|
//refresh list; we'll be knocking them out again in serializeUser
|
||||||
allAccounts = Rememberer.AccountsOverview();
|
allAccounts = r.AccountsOverview();
|
||||||
foreach(var user in users)
|
foreach(var user in users)
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
@ -80,10 +83,9 @@ public class HomeController : Controller
|
|||||||
sb.Append("]}");
|
sb.Append("]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
//type error, e is not defined
|
|
||||||
//channels
|
//channels
|
||||||
sb.Append(",{text: \"channels\", expanded:true, nodes: [");
|
sb.Append(",{text: \"channels\", expanded:true, nodes: [");
|
||||||
var topLevelChannels = Rememberer.ChannelsOverview().Where(x => x.ParentChannel == null).ToList();
|
var topLevelChannels = r.ChannelsOverview().Where(x => x.ParentChannel == null).ToList();
|
||||||
first = true;
|
first = true;
|
||||||
foreach (var topLevelChannel in topLevelChannels)
|
foreach (var topLevelChannel in topLevelChannels)
|
||||||
{
|
{
|
||||||
|
@ -10,11 +10,11 @@ public class UACsController() : Controller
|
|||||||
{
|
{
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
return View(Rememberer.UACsOverview());
|
return View(Rememberer.Instance.UACsOverview());
|
||||||
}
|
}
|
||||||
public IActionResult Details(Guid id)
|
public IActionResult Details(Guid id)
|
||||||
{
|
{
|
||||||
return View(Rememberer.SearchUAC(uac => uac.Id == id));
|
return View(Rememberer.Instance.SearchUAC(uac => uac.Id == id));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
@ -11,6 +11,7 @@ namespace vassago.Controllers.api;
|
|||||||
public class AccountsController : ControllerBase
|
public class AccountsController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<AccountsController> _logger;
|
private readonly ILogger<AccountsController> _logger;
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
|
||||||
public AccountsController(ILogger<AccountsController> logger)
|
public AccountsController(ILogger<AccountsController> logger)
|
||||||
{
|
{
|
||||||
@ -29,14 +30,14 @@ public class AccountsController : ControllerBase
|
|||||||
public IActionResult UnlinkUser([FromBody] extraSpecialObjectReadGlorifiedTupleFor_UnlinkUser req)
|
public IActionResult UnlinkUser([FromBody] extraSpecialObjectReadGlorifiedTupleFor_UnlinkUser req)
|
||||||
{
|
{
|
||||||
var acc_guid = req.acc_guid;
|
var acc_guid = req.acc_guid;
|
||||||
var accFromDb = Rememberer.SearchAccount(acc => acc.Id == acc_guid);
|
var accFromDb = r.SearchAccount(acc => acc.Id == acc_guid);
|
||||||
if (accFromDb == null)
|
if (accFromDb == null)
|
||||||
{
|
{
|
||||||
var err = $"attempt to unlink user for acc {acc_guid}, not found";
|
var err = $"attempt to unlink user for acc {acc_guid}, not found";
|
||||||
_logger.LogError(err);
|
_logger.LogError(err);
|
||||||
return NotFound(err);
|
return NotFound(err);
|
||||||
}
|
}
|
||||||
var userFromDb = Rememberer.SearchUser(c => c.Id == accFromDb.IsUser.Id);
|
var userFromDb = r.SearchUser(c => c.Id == accFromDb.IsUser.Id);
|
||||||
if (userFromDb == null)
|
if (userFromDb == null)
|
||||||
{
|
{
|
||||||
var err = $"attempt to unlink user for {acc_guid}, doesn't have a user";
|
var err = $"attempt to unlink user for {acc_guid}, doesn't have a user";
|
||||||
@ -46,7 +47,7 @@ public class AccountsController : ControllerBase
|
|||||||
|
|
||||||
accFromDb.IsUser = null;
|
accFromDb.IsUser = null;
|
||||||
|
|
||||||
Rememberer.RememberAccount(accFromDb);
|
r.RememberAccount(accFromDb);
|
||||||
return Ok(accFromDb);
|
return Ok(accFromDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ namespace vassago.Controllers.api;
|
|||||||
public class RemembererController : ControllerBase
|
public class RemembererController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<RemembererController> _logger;
|
private readonly ILogger<RemembererController> _logger;
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
|
||||||
public RemembererController(ILogger<RemembererController> logger)
|
public RemembererController(ILogger<RemembererController> logger)
|
||||||
{
|
{
|
||||||
@ -22,42 +23,42 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Account CreateAccount(Guid id)
|
public Account CreateAccount(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.AccountDetail(id);
|
return r.AccountDetail(id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("Attachment")]
|
[Route("Attachment")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Attachment CreateAttachment(Guid id)
|
public Attachment CreateAttachment(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.AttachmentDetail(id);
|
return r.AttachmentDetail(id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("Channels")]
|
[Route("Channels")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Channel CreateChannel(Guid id)
|
public Channel CreateChannel(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.ChannelDetail(id);
|
return r.ChannelDetail(id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("Message")]
|
[Route("Message")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Message CreateMessage(Guid id)
|
public Message CreateMessage(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.MessageDetail(id);
|
return r.MessageDetail(id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("UAC")]
|
[Route("UAC")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public UAC CreateUAC(Guid id)
|
public UAC CreateUAC(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.UACDetail(id);
|
return r.UACDetail(id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("User")]
|
[Route("User")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public User CreateUser(Guid id)
|
public User CreateUser(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.UserDetail(id);
|
return r.UserDetail(id);
|
||||||
}
|
}
|
||||||
//Read
|
//Read
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -65,42 +66,42 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Account GetAccount(Guid id)
|
public Account GetAccount(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.AccountDetail(id);
|
return r.AccountDetail(id);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Attachment")]
|
[Route("Attachment")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Attachment GetAttachment(Guid id)
|
public Attachment GetAttachment(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.AttachmentDetail(id);
|
return r.AttachmentDetail(id);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Channels")]
|
[Route("Channels")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Channel GetChannel(Guid id)
|
public Channel GetChannel(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.ChannelDetail(id);
|
return r.ChannelDetail(id);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Message")]
|
[Route("Message")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public Message GetMessage(Guid id)
|
public Message GetMessage(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.MessageDetail(id);
|
return r.MessageDetail(id);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("UAC")]
|
[Route("UAC")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public UAC GetUAC(Guid id)
|
public UAC GetUAC(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.UACDetail(id);
|
return r.UACDetail(id);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("User")]
|
[Route("User")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public User GetUser(Guid id)
|
public User GetUser(Guid id)
|
||||||
{
|
{
|
||||||
return Rememberer.UserDetail(id);
|
return r.UserDetail(id);
|
||||||
}
|
}
|
||||||
//Update
|
//Update
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
@ -108,7 +109,7 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult Patch([FromBody] Channel channel)
|
public IActionResult Patch([FromBody] Channel channel)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.ChannelDetail(channel.Id);
|
var fromDb = r.ChannelDetail(channel.Id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to update channel {channel.Id}, not found");
|
_logger.LogError($"attempt to update channel {channel.Id}, not found");
|
||||||
@ -121,7 +122,7 @@ public class RemembererController : ControllerBase
|
|||||||
//settable values: lewdness filter level, meanness filter level. maybe i could decorate them...
|
//settable values: lewdness filter level, meanness filter level. maybe i could decorate them...
|
||||||
fromDb.LewdnessFilterLevel = channel.LewdnessFilterLevel;
|
fromDb.LewdnessFilterLevel = channel.LewdnessFilterLevel;
|
||||||
fromDb.MeannessFilterLevel = channel.MeannessFilterLevel;
|
fromDb.MeannessFilterLevel = channel.MeannessFilterLevel;
|
||||||
Rememberer.RememberChannel(fromDb);
|
r.RememberChannel(fromDb);
|
||||||
return Ok(fromDb);
|
return Ok(fromDb);
|
||||||
}
|
}
|
||||||
//Delete
|
//Delete
|
||||||
@ -130,13 +131,13 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteAccount(Guid id)
|
public IActionResult DeleteAccount(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.AccountDetail(id);
|
var fromDb = r.AccountDetail(id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete account {id}, not found");
|
_logger.LogError($"attempt to delete account {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetAccount(fromDb);
|
r.ForgetAccount(fromDb);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
@ -144,13 +145,13 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteAttachment(Guid id)
|
public IActionResult DeleteAttachment(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.AttachmentDetail(id);
|
var fromDb = r.AttachmentDetail(id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete attachment {id}, not found");
|
_logger.LogError($"attempt to delete attachment {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetAttachment(fromDb);
|
r.ForgetAttachment(fromDb);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
@ -158,14 +159,14 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteChannel(Guid id)
|
public IActionResult DeleteChannel(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.ChannelDetail(id);
|
var fromDb = r.ChannelDetail(id);
|
||||||
_logger.LogDebug($"delete channel {id}");
|
_logger.LogDebug($"delete channel {id}");
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete channel {id}, not found");
|
_logger.LogError($"attempt to delete channel {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetChannel(fromDb);
|
r.ForgetChannel(fromDb);
|
||||||
_logger.LogDebug($"delete channel {id} success");
|
_logger.LogDebug($"delete channel {id} success");
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
@ -174,13 +175,13 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteMessage(Guid id)
|
public IActionResult DeleteMessage(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.MessageDetail(id);
|
var fromDb = r.MessageDetail(id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete message {id}, not found");
|
_logger.LogError($"attempt to delete message {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetMessage(fromDb);
|
r.ForgetMessage(fromDb);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
@ -188,13 +189,13 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteUAC(Guid id)
|
public IActionResult DeleteUAC(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.UACDetail(id);
|
var fromDb = r.UACDetail(id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete uac {id}, not found");
|
_logger.LogError($"attempt to delete uac {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetUAC(fromDb);
|
r.ForgetUAC(fromDb);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
@ -202,13 +203,13 @@ public class RemembererController : ControllerBase
|
|||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult DeleteUser(Guid id)
|
public IActionResult DeleteUser(Guid id)
|
||||||
{
|
{
|
||||||
var fromDb = Rememberer.UserDetail(id);
|
var fromDb = r.UserDetail(id);
|
||||||
if (fromDb == null)
|
if (fromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to delete user {id}, not found");
|
_logger.LogError($"attempt to delete user {id}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
Rememberer.ForgetUser(fromDb);
|
r.ForgetUser(fromDb);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ namespace vassago.Controllers.api;
|
|||||||
public class UACController : ControllerBase
|
public class UACController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<UACController> _logger;
|
private readonly ILogger<UACController> _logger;
|
||||||
|
private static Rememberer r = Rememberer.Instance;
|
||||||
|
|
||||||
public UACController(ILogger<UACController> logger)
|
public UACController(ILogger<UACController> logger)
|
||||||
{
|
{
|
||||||
@ -31,14 +32,14 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var channel_guid = req.channel_guid;
|
var channel_guid = req.channel_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
var err = $"attempt to link channel for uac {uac_guid}, not found";
|
var err = $"attempt to link channel for uac {uac_guid}, not found";
|
||||||
_logger.LogError(err);
|
_logger.LogError(err);
|
||||||
return NotFound(err);
|
return NotFound(err);
|
||||||
}
|
}
|
||||||
var channelFromDb = Rememberer.SearchChannel(c => c.Id == channel_guid);
|
var channelFromDb = r.SearchChannel(c => c.Id == channel_guid);
|
||||||
if (channelFromDb == null)
|
if (channelFromDb == null)
|
||||||
{
|
{
|
||||||
var err = $"attempt to link channel for channel {channel_guid}, not found";
|
var err = $"attempt to link channel for channel {channel_guid}, not found";
|
||||||
@ -52,7 +53,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("channel already linked");
|
return BadRequest("channel already linked");
|
||||||
}
|
}
|
||||||
uacFromDb.Channels.Add(channelFromDb);
|
uacFromDb.Channels.Add(channelFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
public class extraSpecialObjectReadGlorifiedTupleFor_LinkUser
|
public class extraSpecialObjectReadGlorifiedTupleFor_LinkUser
|
||||||
@ -67,13 +68,13 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var user_guid = req.user_guid;
|
var user_guid = req.user_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to link channal for uac {uac_guid}, not found");
|
_logger.LogError($"attempt to link channal for uac {uac_guid}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
var userFromDb = Rememberer.SearchUser(c => c.Id == user_guid);
|
var userFromDb = r.SearchUser(c => c.Id == user_guid);
|
||||||
if (userFromDb == null)
|
if (userFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to link user for user {user_guid}, not found");
|
_logger.LogError($"attempt to link user for user {user_guid}, not found");
|
||||||
@ -86,7 +87,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("user already linked");
|
return BadRequest("user already linked");
|
||||||
}
|
}
|
||||||
uacFromDb.Users.Add(userFromDb);
|
uacFromDb.Users.Add(userFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
public class extraSpecialObjectReadGlorifiedTupleFor_LinkAccount
|
public class extraSpecialObjectReadGlorifiedTupleFor_LinkAccount
|
||||||
@ -101,13 +102,13 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var account_guid = req.account_guid;
|
var account_guid = req.account_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to link channal for uac {uac_guid}, not found");
|
_logger.LogError($"attempt to link channal for uac {uac_guid}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
var accountFromDb = Rememberer.SearchAccount(c => c.Id == account_guid);
|
var accountFromDb = r.SearchAccount(c => c.Id == account_guid);
|
||||||
if (accountFromDb == null)
|
if (accountFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to link account for user {account_guid}, not found");
|
_logger.LogError($"attempt to link account for user {account_guid}, not found");
|
||||||
@ -120,7 +121,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("account already linked");
|
return BadRequest("account already linked");
|
||||||
}
|
}
|
||||||
uacFromDb.AccountInChannels.Add(accountFromDb);
|
uacFromDb.AccountInChannels.Add(accountFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
@ -130,13 +131,13 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var user_guid = req.user_guid;
|
var user_guid = req.user_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink uac for uac {uac_guid}, not found");
|
_logger.LogError($"attempt to unlink uac for uac {uac_guid}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
var userFromDb = Rememberer.SearchUser(c => c.Id == user_guid);
|
var userFromDb = r.SearchUser(c => c.Id == user_guid);
|
||||||
if (userFromDb == null)
|
if (userFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink user for user {user_guid}, not found");
|
_logger.LogError($"attempt to unlink user for user {user_guid}, not found");
|
||||||
@ -149,7 +150,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("user not linked");
|
return BadRequest("user not linked");
|
||||||
}
|
}
|
||||||
uacFromDb.Users.Remove(userFromDb);
|
uacFromDb.Users.Remove(userFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
@ -159,13 +160,13 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var account_guid = req.account_guid;
|
var account_guid = req.account_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink uac for uac {uac_guid}, not found");
|
_logger.LogError($"attempt to unlink uac for uac {uac_guid}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
var accountFromDb = Rememberer.SearchAccount(a => a.Id == account_guid);
|
var accountFromDb = r.SearchAccount(a => a.Id == account_guid);
|
||||||
if (accountFromDb == null)
|
if (accountFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink account for user {account_guid}, not found");
|
_logger.LogError($"attempt to unlink account for user {account_guid}, not found");
|
||||||
@ -178,7 +179,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("account not linked");
|
return BadRequest("account not linked");
|
||||||
}
|
}
|
||||||
uacFromDb.AccountInChannels.Remove(accountFromDb);
|
uacFromDb.AccountInChannels.Remove(accountFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
@ -188,13 +189,13 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
var uac_guid = req.uac_guid;
|
var uac_guid = req.uac_guid;
|
||||||
var channel_guid = req.channel_guid;
|
var channel_guid = req.channel_guid;
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == uac_guid);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == uac_guid);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink channal for uac {uac_guid}, not found");
|
_logger.LogError($"attempt to unlink channal for uac {uac_guid}, not found");
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
var channelFromDb = Rememberer.SearchChannel(c => c.Id == channel_guid);
|
var channelFromDb = r.SearchChannel(c => c.Id == channel_guid);
|
||||||
if (channelFromDb == null)
|
if (channelFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to unlink user for user {channel_guid}, not found");
|
_logger.LogError($"attempt to unlink user for user {channel_guid}, not found");
|
||||||
@ -207,7 +208,7 @@ public class UACController : ControllerBase
|
|||||||
return BadRequest("user not linked");
|
return BadRequest("user not linked");
|
||||||
}
|
}
|
||||||
uacFromDb.Channels.Remove(channelFromDb);
|
uacFromDb.Channels.Remove(channelFromDb);
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb);
|
return Ok(uacFromDb);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
@ -216,7 +217,7 @@ public class UACController : ControllerBase
|
|||||||
public IActionResult CreateForChannels(Guid Id)
|
public IActionResult CreateForChannels(Guid Id)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"made it to controller. creating for channel {Id}");
|
_logger.LogDebug($"made it to controller. creating for channel {Id}");
|
||||||
var targetChannel = Rememberer.ChannelDetail(Id);
|
var targetChannel = r.ChannelDetail(Id);
|
||||||
if (targetChannel == null)
|
if (targetChannel == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -225,8 +226,8 @@ public class UACController : ControllerBase
|
|||||||
{
|
{
|
||||||
Channels = [targetChannel]
|
Channels = [targetChannel]
|
||||||
};
|
};
|
||||||
Rememberer.RememberUAC(newUAC);
|
r.RememberUAC(newUAC);
|
||||||
Rememberer.RememberChannel(targetChannel);
|
r.RememberChannel(targetChannel);
|
||||||
return Ok(newUAC.Id);
|
return Ok(newUAC.Id);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
@ -235,7 +236,7 @@ public class UACController : ControllerBase
|
|||||||
public IActionResult AddTranslation(Guid Id)
|
public IActionResult AddTranslation(Guid Id)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"made it to controller. creating translation for uac {Id}");
|
_logger.LogDebug($"made it to controller. creating translation for uac {Id}");
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == Id);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == Id);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to create translation for uac {Id}, not found");
|
_logger.LogError($"attempt to create translation for uac {Id}, not found");
|
||||||
@ -243,7 +244,7 @@ public class UACController : ControllerBase
|
|||||||
}
|
}
|
||||||
uacFromDb.Translations ??= [];
|
uacFromDb.Translations ??= [];
|
||||||
uacFromDb.Translations.Add(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
|
uacFromDb.Translations.Add(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb.Translations.Count);
|
return Ok(uacFromDb.Translations.Count);
|
||||||
}
|
}
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
@ -252,7 +253,7 @@ public class UACController : ControllerBase
|
|||||||
public IActionResult AddCommandAlteration(Guid Id)
|
public IActionResult AddCommandAlteration(Guid Id)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"made it to controller. creating command alteration for uac {Id}");
|
_logger.LogDebug($"made it to controller. creating command alteration for uac {Id}");
|
||||||
var uacFromDb = Rememberer.SearchUAC(uac => uac.Id == Id);
|
var uacFromDb = r.SearchUAC(uac => uac.Id == Id);
|
||||||
if (uacFromDb == null)
|
if (uacFromDb == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"attempt to create command alteration for uac {Id}, not found");
|
_logger.LogError($"attempt to create command alteration for uac {Id}, not found");
|
||||||
@ -260,7 +261,7 @@ public class UACController : ControllerBase
|
|||||||
}
|
}
|
||||||
uacFromDb.CommandAlterations ??= [];
|
uacFromDb.CommandAlterations ??= [];
|
||||||
uacFromDb.CommandAlterations.Add(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
|
uacFromDb.CommandAlterations.Add(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
|
||||||
Rememberer.RememberUAC(uacFromDb);
|
r.RememberUAC(uacFromDb);
|
||||||
return Ok(uacFromDb.CommandAlterations.Count);
|
return Ok(uacFromDb.CommandAlterations.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,8 @@
|
|||||||
|
|
||||||
sb.Append("[{text: \"accounts\", \"expanded\":true, nodes: [");
|
sb.Append("[{text: \"accounts\", \"expanded\":true, nodes: [");
|
||||||
var first = true;
|
var first = true;
|
||||||
foreach (var acc in ThisChannel.Users?.OrderBy(a => a?.SeenInChannel?.LineageSummary))
|
Console.WriteLine($"{ThisChannel.DisplayName} has {ThisChannel.Users?.Count ?? 0} users.");
|
||||||
|
foreach (var acc in ThisChannel.Users?.OrderBy(a => a?.SeenInChannel?.LineageSummary ?? " ERROR"))
|
||||||
{
|
{
|
||||||
if(!first)
|
if(!first)
|
||||||
sb.Append(',');
|
sb.Append(',');
|
||||||
|
283
WebInterface/Views/Configuration/Index.cshtml
Normal file
283
WebInterface/Views/Configuration/Index.cshtml
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
@model vassago.Models.Configuration
|
||||||
|
@using Newtonsoft.Json;
|
||||||
|
@using vassago.Behavior;
|
||||||
|
@using vassago.TwitchInterface;
|
||||||
|
@using System.Text;
|
||||||
|
|
||||||
|
<a href="/">home</a>/configuration
|
||||||
|
<form action="@Url.Action("submit", "Configuration")" method="post" id="theForm">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Discord (@(Model?.DiscordTokens?.Count ?? 0) accounts)</th>
|
||||||
|
</tr>
|
||||||
|
@{
|
||||||
|
if(Model.DiscordTokens != null) for(var i = 0; i < Model.DiscordTokens.Count; i++)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<th><label for="DiscordTokens[@i]"></label></th>
|
||||||
|
<td>
|
||||||
|
<input type="text" class="form-control" name="DiscordTokens[@i]" value="@Model.DiscordTokens[i]"/>
|
||||||
|
<button type="button" onclick="removeDiscord(@i)" class="btn btn-danger">del</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" onclick="addDiscord.showModal()">add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><label class="form-check-label" for="SetupDiscordSlashCommands">Setup Discord Slash Commands</label>
|
||||||
|
<td><input type="checkbox" class="form-check-input position-static" name="SetupDiscordSlashCommands" checked="@Model.SetupDiscordSlashCommands" value="true"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Twitch (@(Model?.TwitchConfigs?.Count ?? 0) accounts)</th>
|
||||||
|
</tr>
|
||||||
|
@{
|
||||||
|
if(Model.TwitchConfigs != null) for(var i = 0; i < Model.TwitchConfigs.Count; i++)
|
||||||
|
{
|
||||||
|
var tc = JsonConvert.DeserializeObject<TwitchConfig>(Model.TwitchConfigs[i]);
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th><label for="TwitchConfigs[@i]"></label></th>
|
||||||
|
<td>
|
||||||
|
<input type="hidden" name="TwitchConfigs[@i]" id="TwitchConfigs_@i" value="@Model.TwitchConfigs[i]" />
|
||||||
|
<input type="text" class="form-control" data-name="username" value="@tc.username"/>
|
||||||
|
<input type="text" class="form-control" data-name="oauth" value="@tc.oauth"/>
|
||||||
|
<button type="button" onclick="removeTwitch(@i);" class="btn btn-danger">del</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" onclick="addTwitch.showModal()">add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="form-text">
|
||||||
|
<th><label for="ExchangePairsLocation">Exchange Pairs Location</label></th>
|
||||||
|
<td><input type="text" class="form-control" name="ExchangePairsLocation" value="@Model.ExchangePairsLocation"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Webhooks</th>
|
||||||
|
</tr>
|
||||||
|
@{
|
||||||
|
if(Model.Webhooks != null) for(var i = 0; i < Model.Webhooks.Count; i++)
|
||||||
|
{
|
||||||
|
if(Model.Webhooks[i] == null) continue;
|
||||||
|
Console.WriteLine(Model.Webhooks[i]);
|
||||||
|
var wh = JsonConvert.DeserializeObject<WebhookConf>(Model.Webhooks[i]);
|
||||||
|
if(wh == null) continue;
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
if(wh.Headers != null) foreach(var header in wh.Headers)
|
||||||
|
{
|
||||||
|
sb.Append($"{header[0]}:");
|
||||||
|
if(header.Count == 2)
|
||||||
|
sb.Append(header[1]);
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<th><label for="Webhooks[@i]">@wh.Trigger</label></th>
|
||||||
|
<td>
|
||||||
|
<input type="hidden" name="Webhooks[@i]" id="Webhooks_@i" value="@Model.Webhooks[i]" />
|
||||||
|
<input type="text" class="form-control" data-name="Trigger" value="@wh.Trigger"/>
|
||||||
|
<input type="text" class="form-control" data-name="Uri" value="@wh.Uri"/>
|
||||||
|
<input type="text" class="form-control" data-name="Method" value="@wh.Method"/>
|
||||||
|
<input type="textarea" class="form-control" data-name="Headers" value="@sb.ToString()"/>
|
||||||
|
<input type="text" class="form-control" data-name="Content" value="@wh.Content"/>
|
||||||
|
<input type="text" class="form-control" data-name="Description" value="@wh.Description"/>
|
||||||
|
<button type="button" onclick="removeWebhook(@i);" class="btn btn-danger">del</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" onclick="addWebhookDialog.showModal()">add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="form-text">
|
||||||
|
<th><label for="KafkaBootstrap">Kafka Bootstrap Server</label></th>
|
||||||
|
<td><input type="text" class="form-control" name="KafkaBootstrap" value="@Model.KafkaBootstrap"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="form-text">
|
||||||
|
<th><label for="KafkaName">Kafka Name</label></th>
|
||||||
|
<td><input type="text" class="form-control" name="KafkaName" value="@Model.KafkaName"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="form-text">
|
||||||
|
<th><label for="reportedApiUrl">reportedApiUrl</label></th>
|
||||||
|
<td><input type="text" class="form-control" name="reportedApiUrl" value="@Model.reportedApiUrl"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="form-text">
|
||||||
|
<td colspan="2"><button class="btn btn-success" type="button" onclick="complexSubmit()">save</button></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
<dialog id="addDiscord">
|
||||||
|
<form action="@Url.Action("AddDiscord", "Configuration")" method="post">
|
||||||
|
<input type="text" class="form-control" name="newToken" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="addDiscord.close()">cancel</button>
|
||||||
|
<button class="btn btn-success" type="submit">save</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="removeDiscordDialog">
|
||||||
|
<form action="@Url.Action("RemoveDiscord", "Configuration")" method="post">
|
||||||
|
Are you sure?
|
||||||
|
<input type="hidden" name="index" id="removeDiscordTarget" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="removeDiscordDialog.close()">cancel</button>
|
||||||
|
<button class="btn btn-danger" type="submit">delete</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="addTwitch">
|
||||||
|
<form action="@Url.Action("AddTwitch", "Configuration")" method="post">
|
||||||
|
username: <input type="text" class="form-control" name="newUsername" />
|
||||||
|
oauth: <input type="text" class="form-control" name="newOauth" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="addTwitch.close()">cancel</button>
|
||||||
|
<button class="btn btn-success" type="submit">save</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="removeTwitchDialog">
|
||||||
|
<form action="@Url.Action("RemoveTwitch", "Configuration")" method="post">
|
||||||
|
Are you sure?
|
||||||
|
<input type="hidden" name="id" id="removeTwitchTarget" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="removeTwitchDialog.close()">cancel</button>
|
||||||
|
<button class="btn btn-danger" type="submit">delete</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="addWebhookDialog">
|
||||||
|
<form action="@Url.Action("AddWebhook", "Configuration")" method="post">
|
||||||
|
trigger
|
||||||
|
<input type="text" class="form-control" name="Trigger" />
|
||||||
|
Uri
|
||||||
|
<input type="text" class="form-control" name="Uri" />
|
||||||
|
Method
|
||||||
|
<input type="text" class="form-control" name="Method" />
|
||||||
|
Headers
|
||||||
|
<input type="textarea" class="form-control" id="newWebhookHeaders" />
|
||||||
|
<input type="hidden" name="Headers" />
|
||||||
|
Content
|
||||||
|
<input type="text" class="form-control" name="Content" />
|
||||||
|
Description
|
||||||
|
<input type="text" class="form-control" name="Description" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="addWebhookDialog.close()">cancel</button>
|
||||||
|
<button class="btn btn-success" type="button" onclick="addWebhookComplexSubmit()">save</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="removeWebhookDialog">
|
||||||
|
<form action="@Url.Action("RemoveWebhook", "Configuration")" method="post">
|
||||||
|
Are you sure?
|
||||||
|
<input type="hidden" name="id" id="removeWebhookTarget" />
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="removeWebhookDialog.close()">cancel</button>
|
||||||
|
<button class="btn btn-danger" type="submit">delete</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
@section scripts{
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function removeDiscord(idx){
|
||||||
|
removeDiscordTarget.Value = idx;
|
||||||
|
console.log("removeDiscordTarget is now " + idx);
|
||||||
|
removeDiscordDialog.showModal();
|
||||||
|
}
|
||||||
|
function removeTwitch(idx){
|
||||||
|
removeTwitchTarget.value = idx;
|
||||||
|
removeTwitchDialog.showModal();
|
||||||
|
}
|
||||||
|
function removeWebhook(idx){
|
||||||
|
removeWebhookTarget.value = idx;
|
||||||
|
removeWebhookDialog.showModal();
|
||||||
|
}
|
||||||
|
function complexSubmit()
|
||||||
|
{
|
||||||
|
for (let i = 0; true; i++)
|
||||||
|
{
|
||||||
|
let thisCell = document.querySelector("td>#TwitchConfigs_" + i);
|
||||||
|
if(thisCell !== null)
|
||||||
|
{
|
||||||
|
let usernameElem = thisCell.nextElementSibling;
|
||||||
|
let oauthElem = usernameElem.nextElementSibling;
|
||||||
|
let asObj = {username: usernameElem.value, oauth: oauthElem.value};
|
||||||
|
thisCell.value = JSON.stringify(asObj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; true; i++)
|
||||||
|
{
|
||||||
|
let thisCell = document.querySelector("td>#Webhooks_" + i);
|
||||||
|
if(thisCell !== null)
|
||||||
|
{
|
||||||
|
let nextCell = thisCell;
|
||||||
|
let asObj = {};
|
||||||
|
while(true){
|
||||||
|
nextCell = nextCell.nextElementSibling;
|
||||||
|
if(nextCell == null)
|
||||||
|
break;
|
||||||
|
if(!nextCell.hasAttribute("data-name"))
|
||||||
|
continue;
|
||||||
|
let dataname = nextCell.attributes["data-name"].value;
|
||||||
|
if(nextCell.value != "")
|
||||||
|
{
|
||||||
|
if(dataname == "Headers")
|
||||||
|
{
|
||||||
|
asObj["Headers"] = [];
|
||||||
|
let headerArray = nextCell.value.split('\n');
|
||||||
|
headerArray.forEach((elem) => {
|
||||||
|
if(elem.indexOf(":") > -1)
|
||||||
|
{
|
||||||
|
asObj["Headers"].push(elem.split(":"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asObj[dataname] = nextCell.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thisCell.value = JSON.stringify(asObj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
theForm.submit();
|
||||||
|
}
|
||||||
|
function addWebhookComplexSubmit()
|
||||||
|
{
|
||||||
|
let headersInput = document.querySelector("#newWebhookHeaders");
|
||||||
|
if(headersInput.value != "")
|
||||||
|
{
|
||||||
|
if(headersInput.value.indexOf("\n") == -1)
|
||||||
|
{
|
||||||
|
headersInput.value += "\n";
|
||||||
|
}
|
||||||
|
let headers = headersInput.value.split("\n");
|
||||||
|
let i = 0;
|
||||||
|
headers.forEach((headerInputLine) => {
|
||||||
|
console.log(headerInputLine);
|
||||||
|
if(headerInputLine.indexOf(":") > -1)
|
||||||
|
{
|
||||||
|
var newElem = document.createElement("input");
|
||||||
|
newElem.setAttribute("type", "hidden");
|
||||||
|
newElem.setAttribute("name", "Headers[" + i + "]");
|
||||||
|
newElem.value = JSON.stringify(headerInputLine.split(":"));
|
||||||
|
headersInput.parentElement.appendChild(newElem);
|
||||||
|
console.log(newElem.value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
document.querySelector("#addWebhookDialog form").submit();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
@ -18,7 +18,7 @@
|
|||||||
"Webhooks": [
|
"Webhooks": [
|
||||||
{
|
{
|
||||||
"uacID": "9a94855a-e5a2-43b5-8420-ce670472ce95",
|
"uacID": "9a94855a-e5a2-43b5-8420-ce670472ce95",
|
||||||
"Trigger": "test",
|
"Trigger": "!test",
|
||||||
"Description": "<i>test</i>",
|
"Description": "<i>test</i>",
|
||||||
"Uri": "http://localhost",
|
"Uri": "http://localhost",
|
||||||
"Method": "POST",
|
"Method": "POST",
|
||||||
|
@ -19,6 +19,14 @@ case "$1" in
|
|||||||
dotnet ef migrations add "$2"
|
dotnet ef migrations add "$2"
|
||||||
dotnet ef database update --connection "$connnectionstr"
|
dotnet ef database update --connection "$connnectionstr"
|
||||||
;;
|
;;
|
||||||
|
"remove-migration")
|
||||||
|
echo "ef migrations will tell you you can use dotnet ef migrations remove."
|
||||||
|
echo ""
|
||||||
|
echo "LIES."
|
||||||
|
echo ""
|
||||||
|
echo "it doesn't have a way to specify the connection string. can't be done."
|
||||||
|
echo "edit the db the hard way."
|
||||||
|
;;
|
||||||
|
|
||||||
"dbupdate")
|
"dbupdate")
|
||||||
dotnet ef database update --connection "$connnectionstr"
|
dotnet ef database update --connection "$connnectionstr"
|
||||||
|
Loading…
Reference in New Issue
Block a user