forked from adam/discord-bot-shtik
Compare commits
6 Commits
0580a9d21f
...
7c10b00110
Author | SHA1 | Date | |
---|---|---|---|
7c10b00110 | |||
bbf94d215f | |||
0c1370bd04 | |||
ee8cc96f71 | |||
e3c9a65f04 | |||
e0283e87f5 |
20
Behaver.cs
20
Behaver.cs
@ -20,7 +20,7 @@ public class Behaver
|
|||||||
var subtypes = AppDomain.CurrentDomain.GetAssemblies()
|
var subtypes = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
.SelectMany(domainAssembly => domainAssembly.GetTypes())
|
.SelectMany(domainAssembly => domainAssembly.GetTypes())
|
||||||
.Where(type => type.IsSubclassOf(typeof(vassago.Behavior.Behavior)) && !type.IsAbstract &&
|
.Where(type => type.IsSubclassOf(typeof(vassago.Behavior.Behavior)) && !type.IsAbstract &&
|
||||||
type.GetCustomAttributes(typeof(StaticPlzAttribute),false)?.Any() == true)
|
type.GetCustomAttributes(typeof(StaticPlzAttribute), false)?.Any() == true)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach (var subtype in subtypes)
|
foreach (var subtype in subtypes)
|
||||||
@ -72,7 +72,7 @@ public class Behaver
|
|||||||
|
|
||||||
public void MarkSelf(Account selfAccount)
|
public void MarkSelf(Account selfAccount)
|
||||||
{
|
{
|
||||||
if(SelfUser == null)
|
if (SelfUser == null)
|
||||||
{
|
{
|
||||||
SelfUser = selfAccount.IsUser;
|
SelfUser = selfAccount.IsUser;
|
||||||
}
|
}
|
||||||
@ -86,15 +86,25 @@ public class Behaver
|
|||||||
|
|
||||||
public bool CollapseUsers(User primary, User secondary)
|
public bool CollapseUsers(User primary, User secondary)
|
||||||
{
|
{
|
||||||
if(primary.Accounts == null)
|
if (primary.Accounts == null)
|
||||||
primary.Accounts = new List<Account>();
|
primary.Accounts = new List<Account>();
|
||||||
if(secondary.Accounts != null)
|
if (secondary.Accounts != null)
|
||||||
primary.Accounts.AddRange(secondary.Accounts);
|
primary.Accounts.AddRange(secondary.Accounts);
|
||||||
foreach(var a in secondary.Accounts)
|
foreach (var a in secondary.Accounts)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
if (uacs.Count() > 0)
|
||||||
|
{
|
||||||
|
foreach (var uac in uacs)
|
||||||
|
{
|
||||||
|
uac.Users.RemoveAll(u => u.Id == secondary.Id);
|
||||||
|
uac.Users.Add(primary);
|
||||||
|
Rememberer.RememberUAC(uac);
|
||||||
|
}
|
||||||
|
}
|
||||||
Rememberer.ForgetUser(secondary);
|
Rememberer.ForgetUser(secondary);
|
||||||
Rememberer.RememberUser(primary);
|
Rememberer.RememberUser(primary);
|
||||||
return true;
|
return true;
|
||||||
|
@ -24,7 +24,6 @@ public class TwitchSummon : Behavior
|
|||||||
OwnerId = uacID,
|
OwnerId = uacID,
|
||||||
DisplayName = Name
|
DisplayName = Name
|
||||||
};
|
};
|
||||||
Rememberer.RememberUAC(myUAC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override bool ShouldAct(Message message)
|
public override bool ShouldAct(Message message)
|
||||||
|
@ -14,7 +14,7 @@ public class TwitchDismiss : Behavior
|
|||||||
public override bool ShouldAct(Message message)
|
public override bool ShouldAct(Message message)
|
||||||
{
|
{
|
||||||
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
|
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
|
||||||
Console.WriteLine($"TwitchDismiss checking. menions me? {message.MentionsMe}");
|
// Console.WriteLine($"TwitchDismiss checking. menions me? {message.MentionsMe}");
|
||||||
if(message.MentionsMe &&
|
if(message.MentionsMe &&
|
||||||
(Regex.IsMatch(message.Content.ToLower(), "\\bbegone\\b") || Regex.IsMatch(message.Content.ToLower(), "\\bfuck off\\b")))
|
(Regex.IsMatch(message.Content.ToLower(), "\\bbegone\\b") || Regex.IsMatch(message.Content.ToLower(), "\\bfuck off\\b")))
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@ public class UnitConvert : Behavior
|
|||||||
decimal asNumeric = 0;
|
decimal asNumeric = 0;
|
||||||
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
|
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("let's try and convert...");
|
||||||
await message.Channel.SendMessage(Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));
|
await message.Channel.SendMessage(Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -31,4 +32,4 @@ public class UnitConvert : Behavior
|
|||||||
await message.Channel.SendMessage( "unparsable");
|
await message.Channel.SendMessage( "unparsable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
187
Behavior/Webhook.cs
Normal file
187
Behavior/Webhook.cs
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
namespace vassago.Behavior;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using vassago.Models;
|
||||||
|
|
||||||
|
[StaticPlz]
|
||||||
|
public class Webhook : Behavior
|
||||||
|
{
|
||||||
|
public override string Name => "Webhook";
|
||||||
|
|
||||||
|
public override string Trigger => "!hook";
|
||||||
|
|
||||||
|
public override string Description => "call a webhook";
|
||||||
|
|
||||||
|
private static List<WebhookConf> configuredWebhooks = new List<WebhookConf>();
|
||||||
|
private ConcurrentDictionary<Guid, WebhookActionOrder> authedCache = new ConcurrentDictionary<Guid, WebhookActionOrder>();
|
||||||
|
private HttpClient hc = new HttpClient();
|
||||||
|
|
||||||
|
public static void SetupWebhooks(IConfigurationSection confSection)
|
||||||
|
{
|
||||||
|
configuredWebhooks = confSection.Get<List<vassago.Behavior.WebhookConf>>();
|
||||||
|
|
||||||
|
foreach (var conf in configuredWebhooks)
|
||||||
|
{
|
||||||
|
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 myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == conf.uacID);
|
||||||
|
if (myUAC == null)
|
||||||
|
{
|
||||||
|
myUAC = new()
|
||||||
|
{
|
||||||
|
OwnerId = conf.uacID,
|
||||||
|
DisplayName = confName
|
||||||
|
};
|
||||||
|
Rememberer.RememberUAC(myUAC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (myUAC.DisplayName != confName)
|
||||||
|
{
|
||||||
|
myUAC.DisplayName = confName;
|
||||||
|
Rememberer.RememberUAC(myUAC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ShouldAct(Message message)
|
||||||
|
{
|
||||||
|
if (!base.ShouldAct(message))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Console.WriteLine("webhook checking");
|
||||||
|
|
||||||
|
if (configuredWebhooks?.Count() < 1)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("no webhooks configured!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var webhookableMessageContent = message.Content.Substring(message.Content.IndexOf(Trigger) + Trigger.Length + 1);
|
||||||
|
Console.WriteLine($"webhookable content: {webhookableMessageContent}");
|
||||||
|
foreach (var wh in configuredWebhooks)
|
||||||
|
{
|
||||||
|
if (webhookableMessageContent.StartsWith(wh.Trigger))
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
Console.WriteLine("webhook UAC passed, preparing WebhookActionOrder");
|
||||||
|
authedCache.TryAdd(message.Id, new WebhookActionOrder()
|
||||||
|
{
|
||||||
|
Conf = wh,
|
||||||
|
webhookContent = webhookableMessageContent.Substring(wh.Trigger.Length + 1),
|
||||||
|
});
|
||||||
|
Console.WriteLine($"added {message.Id} to authedcache");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public override async Task<bool> ActOn(Message message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"hi i'm ActOn. acting on {message.Id}");
|
||||||
|
WebhookActionOrder actionOrder;
|
||||||
|
if (!authedCache.TryRemove(message.Id, out actionOrder))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"{message.Id} was supposed to act, but authedCache doesn't have it! it has {authedCache?.Count()} other stuff, though.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var msg = translate(actionOrder, message);
|
||||||
|
var req = new HttpRequestMessage(new HttpMethod(actionOrder.Conf.Method.ToString()), actionOrder.Conf.Uri);
|
||||||
|
var theContentHeader = actionOrder.Conf.Headers?.FirstOrDefault(h => h[0]?.ToLower() == "content-type");
|
||||||
|
if (theContentHeader != null)
|
||||||
|
{
|
||||||
|
switch (theContentHeader[1]?.ToLower())
|
||||||
|
{
|
||||||
|
//json content is constructed some other weird way.
|
||||||
|
case "multipart/form-data":
|
||||||
|
req.Content = new System.Net.Http.MultipartFormDataContent(msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
req.Content = new System.Net.Http.StringContent(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(theContentHeader[1]?.ToLower());
|
||||||
|
}
|
||||||
|
if (req.Content == null)
|
||||||
|
{
|
||||||
|
req.Content = new System.Net.Http.StringContent(msg);
|
||||||
|
}
|
||||||
|
Console.WriteLine($"survived translating string content. request content: {req.Content}");
|
||||||
|
if (actionOrder.Conf.Headers?.ToList().Count > 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("will add headers.");
|
||||||
|
foreach (var kvp in actionOrder.Conf.Headers.ToList())
|
||||||
|
{
|
||||||
|
if (kvp[0] == theContentHeader[0])
|
||||||
|
{
|
||||||
|
Console.WriteLine("content header; skipping.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"adding header; {kvp[0]}: {kvp[1]}");
|
||||||
|
req.Headers.Add(kvp[0], kvp[1]);
|
||||||
|
Console.WriteLine("survived.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("no headers to add.");
|
||||||
|
}
|
||||||
|
Console.WriteLine("about to Send.");
|
||||||
|
var response = hc.Send(req);
|
||||||
|
Console.WriteLine($"{response.StatusCode} - {response.ReasonPhrase}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var tragedy = $"{response.StatusCode} - {response.ReasonPhrase} - {await response.Content.ReadAsStringAsync()}";
|
||||||
|
Console.Error.WriteLine(tragedy);
|
||||||
|
await message.Reply(tragedy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await message.Reply(await response.Content.ReadAsStringAsync());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private string translate(WebhookActionOrder actionOrder, Message message)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(actionOrder.Conf.Content))
|
||||||
|
return "";
|
||||||
|
var msgContent = actionOrder.Conf.Content.Replace("{text}", actionOrder.webhookContent);
|
||||||
|
msgContent = msgContent.Replace("{msgid}", message.Id.ToString());
|
||||||
|
msgContent = msgContent.Replace("{account}", message.Author.DisplayName.ToString());
|
||||||
|
msgContent = msgContent.Replace("{user}", message.Author.IsUser.DisplayName.ToString());
|
||||||
|
return msgContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WebhookConf
|
||||||
|
{
|
||||||
|
public Guid uacID { get; set; }
|
||||||
|
public string Trigger { get; set; }
|
||||||
|
public Uri Uri { get; set; }
|
||||||
|
//public HttpMethod Method { get; set; }
|
||||||
|
public Enumerations.HttpVerb Method { get; set; }
|
||||||
|
public List<List<string>> Headers { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
}
|
||||||
|
public class WebhookActionOrder
|
||||||
|
{
|
||||||
|
public WebhookConf Conf { get; set; }
|
||||||
|
public string webhookContent { get; set; }
|
||||||
|
}
|
@ -16,6 +16,7 @@ namespace vassago
|
|||||||
DiscordTokens = aspConfig.GetSection("DiscordTokens").Get<IEnumerable<string>>();
|
DiscordTokens = aspConfig.GetSection("DiscordTokens").Get<IEnumerable<string>>();
|
||||||
TwitchConfigs = aspConfig.GetSection("TwitchConfigs").Get<IEnumerable<TwitchConfig>>();
|
TwitchConfigs = aspConfig.GetSection("TwitchConfigs").Get<IEnumerable<TwitchConfig>>();
|
||||||
Conversion.Converter.Load(aspConfig["ExchangePairsLocation"]);
|
Conversion.Converter.Load(aspConfig["ExchangePairsLocation"]);
|
||||||
|
vassago.Behavior.Webhook.SetupWebhooks(aspConfig.GetSection("Webhooks"));
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<string> DiscordTokens { get; }
|
IEnumerable<string> DiscordTokens { get; }
|
||||||
@ -51,4 +52,4 @@ namespace vassago
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,25 +16,37 @@ namespace vassago.Conversion
|
|||||||
{
|
{
|
||||||
public static class Converter
|
public static class Converter
|
||||||
{
|
{
|
||||||
public static string DebugInfo(){
|
|
||||||
var convertibles = knownConversions.Select(kc => kc.Item1).Union(knownConversions.Select(kc => kc.Item2)).Union(
|
|
||||||
knownAliases.Keys.SelectMany(k => k)).Distinct();
|
|
||||||
return $"{convertibles.Count()} convertibles; {string.Join(", ", convertibles)}";
|
|
||||||
}
|
|
||||||
private delegate decimal Convert1Way(decimal input);
|
private delegate decimal Convert1Way(decimal input);
|
||||||
private static string currencyPath;
|
private static string currencyPath;
|
||||||
private static ExchangePairs currencyConf = null;
|
private static ExchangePairs currencyConf = null;
|
||||||
private static DateTime lastUpdatedCurrency = DateTime.UnixEpoch;
|
private static DateTime lastUpdatedCurrency = DateTime.UnixEpoch;
|
||||||
private static List<Tuple<string, string, Convert1Way, Convert1Way>> knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>()
|
private static List<Tuple<string, string, Convert1Way, Convert1Way>> knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>();
|
||||||
{
|
|
||||||
new Tuple<string, string, Convert1Way, Convert1Way>("℉", "°C", (f => {return(f- 32.0m) / 1.8m;}), (c => {return 1.8m*c + 32.0m;})),
|
|
||||||
};
|
|
||||||
private static Dictionary<List<string>, string> knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
|
private static Dictionary<List<string>, string> knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
|
||||||
|
public static string DebugInfo()
|
||||||
|
{
|
||||||
|
var convertibles = knownConversions.Select(kc => kc.Item1).Union(knownConversions.Select(kc => kc.Item2)).Union(
|
||||||
|
knownAliases.Keys.SelectMany(k => k)).Distinct();
|
||||||
|
return $"{convertibles.Count()} convertibles; {string.Join(", ", convertibles)}";
|
||||||
|
}
|
||||||
|
|
||||||
public static void Load(string currencyPath)
|
public static void Load(string currencyPath)
|
||||||
{
|
{
|
||||||
Converter.currencyPath = currencyPath;
|
Converter.currencyPath = currencyPath;
|
||||||
var convConf = JsonConvert.DeserializeObject<ConversionConfig>(File.ReadAllText("assets/conversion.json"));
|
loadStatic();
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromHours(8));
|
||||||
|
loadCurrency();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private static void loadStatic()
|
||||||
|
{
|
||||||
|
knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>();
|
||||||
|
knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
|
||||||
|
var convConf = JsonConvert.DeserializeObject<ConversionConfig>(File.ReadAllText("assets/conversion.json").ToLower());
|
||||||
foreach (var unit in convConf.Units)
|
foreach (var unit in convConf.Units)
|
||||||
{
|
{
|
||||||
knownAliases.Add(unit.Aliases.ToList(), unit.Canonical);
|
knownAliases.Add(unit.Aliases.ToList(), unit.Canonical);
|
||||||
@ -43,63 +55,119 @@ namespace vassago.Conversion
|
|||||||
{
|
{
|
||||||
AddLinearPair(lp.item1, lp.item2, lp.factor);
|
AddLinearPair(lp.item1, lp.item2, lp.factor);
|
||||||
}
|
}
|
||||||
Task.Run(async () => {
|
loadCurrency();
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
loadCurrency();
|
|
||||||
await Task.Delay(TimeSpan.FromHours(8));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
private static void loadCurrency()
|
private static void loadCurrency()
|
||||||
{
|
{
|
||||||
Console.WriteLine("loading currency exchange data.");
|
Console.WriteLine("loading currency exchange data.");
|
||||||
if(currencyConf != null)
|
if (currencyConf != null)
|
||||||
{
|
{
|
||||||
knownConversions.RemoveAll(kc => kc.Item1 == currencyConf.Base);
|
knownConversions.RemoveAll(kc => kc.Item1 == currencyConf.Base);
|
||||||
}
|
}
|
||||||
if (File.Exists(currencyPath))
|
if (File.Exists(currencyPath))
|
||||||
{
|
{
|
||||||
currencyConf = JsonConvert.DeserializeObject<ExchangePairs>(File.ReadAllText(currencyPath));
|
currencyConf = JsonConvert.DeserializeObject<ExchangePairs>(File.ReadAllText(currencyPath).ToLower());
|
||||||
|
|
||||||
if(!knownAliases.ContainsValue(currencyConf.Base))
|
if (!knownAliases.ContainsValue(currencyConf.Base))
|
||||||
{
|
{
|
||||||
knownAliases.Add(new List<string>() { currencyConf.Base.ToLower() }, currencyConf.Base);
|
knownAliases.Add(new List<string>() { }, currencyConf.Base);
|
||||||
}
|
}
|
||||||
foreach (var rate in currencyConf.rates)
|
foreach (var rate in currencyConf.rates)
|
||||||
{
|
{
|
||||||
if(!knownAliases.ContainsValue(rate.Key))
|
if (!knownAliases.ContainsValue(rate.Key))
|
||||||
{
|
{
|
||||||
knownAliases.Add(new List<string>() { rate.Key.ToLower() }, rate.Key);
|
knownAliases.Add(new List<string>() { rate.Key.ToLower() }, rate.Key);
|
||||||
}
|
}
|
||||||
AddLinearPair(currencyConf.Base, rate.Key, rate.Value);
|
AddLinearPair(currencyConf.Base, rate.Key, rate.Value);
|
||||||
Console.WriteLine($"{rate.Key.ToLower()} alias of {rate.Key}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Convert(decimal numericTerm, string sourceunit, string destinationUnit)
|
public static string Convert(decimal numericTerm, string sourceunit, string destinationUnit)
|
||||||
{
|
{
|
||||||
var normalizedSourceUnit = NormalizeUnit(sourceunit);
|
//normalize units
|
||||||
if (string.IsNullOrWhiteSpace(normalizedSourceUnit))
|
var normalizationAttemptSource = NormalizeUnit(sourceunit.ToLower());
|
||||||
|
if (normalizationAttemptSource?.Count() == 0)
|
||||||
{
|
{
|
||||||
return $"parse failure: what's {sourceunit}?";
|
return $"can't find {sourceunit}";
|
||||||
}
|
}
|
||||||
var normalizedDestUnit = NormalizeUnit(destinationUnit);
|
var normalizedSourceUnit = normalizationAttemptSource.First();
|
||||||
if (string.IsNullOrWhiteSpace(normalizedDestUnit))
|
|
||||||
|
var normalizationAttemptDest = NormalizeUnit(destinationUnit.ToLower());
|
||||||
|
if (normalizationAttemptDest?.Count() == 0)
|
||||||
{
|
{
|
||||||
return $"parse failure: what's {destinationUnit}?";
|
return $"can't find {destinationUnit}";
|
||||||
}
|
}
|
||||||
|
var normalizedDestUnit = normalizationAttemptDest.First();
|
||||||
if (normalizedSourceUnit == normalizedDestUnit)
|
if (normalizedSourceUnit == normalizedDestUnit)
|
||||||
{
|
{
|
||||||
return $"source and dest are the same, so... {numericTerm} {normalizedDestUnit}?";
|
return $"source and dest are the same, so... {numericTerm} {normalizedDestUnit}?";
|
||||||
}
|
}
|
||||||
var foundPath = exhaustiveBreadthFirst(normalizedDestUnit, new List<string>() { normalizedSourceUnit })?.ToList();
|
var foundPath = exhaustiveBreadthFirst(normalizedDestUnit, new List<string>() { normalizedSourceUnit })?.ToList();
|
||||||
|
|
||||||
|
//resolve ambiguity
|
||||||
|
var disambiguationPaths = new List<List<string>>();
|
||||||
|
if (normalizationAttemptSource.Count() > 1 && normalizationAttemptDest.Count() > 1)
|
||||||
|
{
|
||||||
|
foreach (var possibleSourceUnit in normalizationAttemptSource)
|
||||||
|
{
|
||||||
|
foreach (var possibleDestUnit in normalizationAttemptDest)
|
||||||
|
{
|
||||||
|
foundPath = exhaustiveBreadthFirst(possibleDestUnit, new List<string>() { possibleSourceUnit })?.ToList();
|
||||||
|
if (foundPath != null)
|
||||||
|
{
|
||||||
|
disambiguationPaths.Add(foundPath.ToList());
|
||||||
|
normalizedSourceUnit = possibleSourceUnit;
|
||||||
|
normalizedDestUnit = possibleDestUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (normalizationAttemptSource.Count() > 1)
|
||||||
|
{
|
||||||
|
foreach (var possibleSourceUnit in normalizationAttemptSource)
|
||||||
|
{
|
||||||
|
foundPath = exhaustiveBreadthFirst(normalizedDestUnit, new List<string>() { possibleSourceUnit })?.ToList();
|
||||||
|
if (foundPath != null)
|
||||||
|
{
|
||||||
|
disambiguationPaths.Add(foundPath.ToList());
|
||||||
|
normalizedSourceUnit = possibleSourceUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (normalizationAttemptDest.Count() > 1)
|
||||||
|
{
|
||||||
|
foreach (var possibleDestUnit in normalizationAttemptDest)
|
||||||
|
{
|
||||||
|
foundPath = exhaustiveBreadthFirst(possibleDestUnit, new List<string>() { normalizedSourceUnit })?.ToList();
|
||||||
|
if (foundPath != null)
|
||||||
|
{
|
||||||
|
disambiguationPaths.Add(foundPath.ToList());
|
||||||
|
normalizedDestUnit = possibleDestUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disambiguationPaths.Count() > 1)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append("unresolvable ambiguity.");
|
||||||
|
foreach(var possibility in disambiguationPaths)
|
||||||
|
{
|
||||||
|
sb.Append($" {possibility.First()} -> {possibility.Last()}?");
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disambiguationPaths.Count() == 1)
|
||||||
|
{
|
||||||
|
//TODO: I'm not entirely sure this is necessary.
|
||||||
|
foundPath = disambiguationPaths.First();
|
||||||
|
}
|
||||||
|
//actually do the math.
|
||||||
if (foundPath != null)
|
if (foundPath != null)
|
||||||
{
|
{
|
||||||
var accumulator = numericTerm;
|
var accumulator = numericTerm;
|
||||||
for (int j = 0; j < foundPath.Count - 1; j++)
|
for (int j = 0; j < foundPath.Count() - 1; j++)
|
||||||
{
|
{
|
||||||
var forwardConversion = knownConversions.FirstOrDefault(kc => kc.Item1 == foundPath[j] && kc.Item2 == foundPath[j + 1]);
|
var forwardConversion = knownConversions.FirstOrDefault(kc => kc.Item1 == foundPath[j] && kc.Item2 == foundPath[j + 1]);
|
||||||
if (forwardConversion != null)
|
if (forwardConversion != null)
|
||||||
@ -118,7 +186,7 @@ namespace vassago.Conversion
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(String.Format("{0:G3}", accumulator).Contains("E-"))
|
if (String.Format("{0:G3}", accumulator).Contains("E-"))
|
||||||
{
|
{
|
||||||
return $"{accumulator} {normalizedDestUnit}";
|
return $"{accumulator} {normalizedDestUnit}";
|
||||||
}
|
}
|
||||||
@ -130,21 +198,34 @@ namespace vassago.Conversion
|
|||||||
}
|
}
|
||||||
return "dimensional analysis failure - I know those units but can't find a path between them.";
|
return "dimensional analysis failure - I know those units but can't find a path between them.";
|
||||||
}
|
}
|
||||||
private static string NormalizeUnit(string unit)
|
private static List<string> NormalizeUnit(string unit)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(unit))
|
if (string.IsNullOrWhiteSpace(unit))
|
||||||
return null;
|
return new();
|
||||||
var normalizedUnit = unit.ToLower();
|
var normalizedUnit = unit;
|
||||||
|
//first, if it does exist in conversions, that's the canonical name.
|
||||||
if (knownConversions.FirstOrDefault(c => c.Item1 == normalizedUnit || c.Item2 == normalizedUnit) != null)
|
if (knownConversions.FirstOrDefault(c => c.Item1 == normalizedUnit || c.Item2 == normalizedUnit) != null)
|
||||||
{
|
{
|
||||||
return normalizedUnit;
|
return new List<string>() { normalizedUnit };
|
||||||
}
|
}
|
||||||
|
//if "unit" isn't a canonical name... actually it never should be; a conversion should use it.
|
||||||
if (!knownAliases.ContainsValue(normalizedUnit))
|
if (!knownAliases.ContainsValue(normalizedUnit))
|
||||||
{
|
{
|
||||||
var key = knownAliases.Keys.FirstOrDefault(listkey => listkey.Contains(normalizedUnit));
|
//then we look through aliases...
|
||||||
if (key != null)
|
var keys = knownAliases.Keys.Where(listkey => listkey.Contains(normalizedUnit));
|
||||||
|
if (keys?.Count() > 1)
|
||||||
{
|
{
|
||||||
return knownAliases[key];
|
var toReturn = new List<string>();
|
||||||
|
foreach (var key in keys)
|
||||||
|
{
|
||||||
|
toReturn.Add(knownAliases[key]);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
else if (keys.Count() == 1)
|
||||||
|
{
|
||||||
|
//for the canonical name.
|
||||||
|
return new List<string>() { knownAliases[keys.First()] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (normalizedUnit.EndsWith("es"))
|
if (normalizedUnit.EndsWith("es"))
|
||||||
@ -155,7 +236,7 @@ namespace vassago.Conversion
|
|||||||
{
|
{
|
||||||
return NormalizeUnit(normalizedUnit.Substring(0, normalizedUnit.Length - 1));
|
return NormalizeUnit(normalizedUnit.Substring(0, normalizedUnit.Length - 1));
|
||||||
}
|
}
|
||||||
return null;
|
return new();
|
||||||
}
|
}
|
||||||
private static IEnumerable<string> exhaustiveBreadthFirst(string dest, IEnumerable<string> currentPath)
|
private static IEnumerable<string> exhaustiveBreadthFirst(string dest, IEnumerable<string> currentPath)
|
||||||
{
|
{
|
||||||
@ -170,9 +251,9 @@ namespace vassago.Conversion
|
|||||||
{
|
{
|
||||||
if (conv.Item1 == last && currentPath.Contains(conv.Item2) == false && conv.Item3 != null)
|
if (conv.Item1 == last && currentPath.Contains(conv.Item2) == false && conv.Item3 != null)
|
||||||
{
|
{
|
||||||
var test = exhaustiveBreadthFirst(dest, currentPath.Append(conv.Item2));
|
var test = exhaustiveBreadthFirst(dest, currentPath.Append(conv.Item2));
|
||||||
if (test != null)
|
if (test != null)
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
if (conv.Item2 == last && currentPath.Contains(conv.Item1) == false && conv.Item4 != null)
|
if (conv.Item2 == last && currentPath.Contains(conv.Item1) == false && conv.Item4 != null)
|
||||||
{
|
{
|
||||||
@ -191,4 +272,4 @@ namespace vassago.Conversion
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,20 @@ public static class Enumerations
|
|||||||
[Description("organizational psuedo-channel")]
|
[Description("organizational psuedo-channel")]
|
||||||
OU
|
OU
|
||||||
}
|
}
|
||||||
|
///<summary>
|
||||||
|
///bro. don't even get me started. tl;dr: hashtag microsoft.
|
||||||
|
///</summary>
|
||||||
|
public enum HttpVerb
|
||||||
|
{
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Delete,
|
||||||
|
Head,
|
||||||
|
Patch,
|
||||||
|
Options
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string GetDescription<T>(this T enumerationValue)
|
public static string GetDescription<T>(this T enumerationValue)
|
||||||
where T : struct
|
where T : struct
|
||||||
@ -64,4 +78,4 @@ public static class Enumerations
|
|||||||
//If we have no description attribute, just return the ToString of the enum
|
//If we have no description attribute, just return the ToString of the enum
|
||||||
return enumerationValue.ToString();
|
return enumerationValue.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ app.UseSwaggerUI(c =>
|
|||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "api");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "api");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseExceptionHandler();
|
//app.UseExceptionHandler();
|
||||||
app.UseStatusCodePages();
|
app.UseStatusCodePages();
|
||||||
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
|
@ -233,7 +233,7 @@ public class DiscordInterface
|
|||||||
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));
|
||||||
|
|
||||||
m.Reply = (t) => { return dMessage.ReplyAsync(t); };
|
m.Reply = (t) => { return dMessage.ReplyAsync(TruncateText(t, m.Channel.MaxTextChars)); };
|
||||||
m.React = (e) => { return AttemptReact(dMessage, e); };
|
m.React = (e) => { return AttemptReact(dMessage, e); };
|
||||||
Rememberer.RememberMessage(m);
|
Rememberer.RememberMessage(m);
|
||||||
return m;
|
return m;
|
||||||
@ -314,7 +314,7 @@ public class DiscordInterface
|
|||||||
parentChannel.SubChannels.Add(c);
|
parentChannel.SubChannels.Add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
c.SendMessage = (t) => { return channel.SendMessageAsync(t); };
|
c.SendMessage = (t) => { return channel.SendMessageAsync(TruncateText(t, c.MaxTextChars));};
|
||||||
c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); };
|
c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); };
|
||||||
|
|
||||||
c = Rememberer.RememberChannel(c);
|
c = Rememberer.RememberChannel(c);
|
||||||
@ -409,4 +409,17 @@ public class DiscordInterface
|
|||||||
return msg.AddReactionAsync(emote);
|
return msg.AddReactionAsync(emote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string TruncateText(string msg, uint? chars)
|
||||||
|
{
|
||||||
|
chars ??= 500;
|
||||||
|
if(msg?.Length > chars)
|
||||||
|
{
|
||||||
|
return msg.Substring(0, (int)chars-2) + "✂";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ namespace vassago.TwitchInterface;
|
|||||||
|
|
||||||
internal class unifiedTwitchMessage
|
internal class unifiedTwitchMessage
|
||||||
{
|
{
|
||||||
public unifiedTwitchMessage(ChatMessage chatMessage){}
|
public unifiedTwitchMessage(ChatMessage chatMessage) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TwitchInterface
|
public class TwitchInterface
|
||||||
@ -110,7 +110,7 @@ public class TwitchInterface
|
|||||||
//data eived
|
//data eived
|
||||||
Console.WriteLine($"#{e.ChatMessage.Channel}[{DateTime.Now}][{e.ChatMessage.DisplayName} [id={e.ChatMessage.Username}]][msg id: {e.ChatMessage.Id}] {e.ChatMessage.Message}");
|
Console.WriteLine($"#{e.ChatMessage.Channel}[{DateTime.Now}][{e.ChatMessage.DisplayName} [id={e.ChatMessage.Username}]][msg id: {e.ChatMessage.Id}] {e.ChatMessage.Message}");
|
||||||
|
|
||||||
//translate to internal, upsert
|
//translate to internal, upsert
|
||||||
var m = UpsertMessage(e.ChatMessage);
|
var m = UpsertMessage(e.ChatMessage);
|
||||||
m.Reply = (t) => { return Task.Run(() => { client.SendReply(e.ChatMessage.Channel, e.ChatMessage.Id, t); }); };
|
m.Reply = (t) => { return Task.Run(() => { client.SendReply(e.ChatMessage.Channel, e.ChatMessage.Id, t); }); };
|
||||||
m.Channel.ChannelType = vassago.Models.Enumerations.ChannelType.Normal;
|
m.Channel.ChannelType = vassago.Models.Enumerations.ChannelType.Normal;
|
||||||
@ -142,14 +142,15 @@ public class TwitchInterface
|
|||||||
|
|
||||||
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 = Rememberer.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)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"acc's usser: {acc.IsUser?.Id}");
|
Console.WriteLine($"acc's usser: {acc.IsUser?.Id}");
|
||||||
}
|
}
|
||||||
acc ??= new Account() {
|
acc ??= new Account()
|
||||||
|
{
|
||||||
IsUser = Rememberer.SearchUser(
|
IsUser = Rememberer.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()
|
||||||
@ -161,16 +162,16 @@ public class TwitchInterface
|
|||||||
acc.Protocol = PROTOCOL;
|
acc.Protocol = PROTOCOL;
|
||||||
acc.SeenInChannel = inChannel;
|
acc.SeenInChannel = inChannel;
|
||||||
|
|
||||||
Console.WriteLine($"we asked rememberer to search for acc's user. {acc.IsUser?.Id}");
|
// Console.WriteLine($"we asked rememberer to search for acc's user. {acc.IsUser?.Id}");
|
||||||
if (acc.IsUser != null)
|
// if (acc.IsUser != null)
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"user has record of {acc.IsUser.Accounts?.Count ?? 0} accounts");
|
// Console.WriteLine($"user has record of {acc.IsUser.Accounts?.Count ?? 0} accounts");
|
||||||
}
|
// }
|
||||||
acc.IsUser ??= new vassago.Models.User() { Accounts = [acc] };
|
acc.IsUser ??= new vassago.Models.User() { Accounts = [acc] };
|
||||||
if (inChannel.Users?.Count > 0)
|
// if (inChannel.Users?.Count > 0)
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
// Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
|
||||||
}
|
// }
|
||||||
Rememberer.RememberAccount(acc);
|
Rememberer.RememberAccount(acc);
|
||||||
inChannel.Users ??= [];
|
inChannel.Users ??= [];
|
||||||
if (!inChannel.Users.Contains(acc))
|
if (!inChannel.Users.Contains(acc))
|
||||||
@ -187,7 +188,7 @@ public class TwitchInterface
|
|||||||
&& ci.Protocol == PROTOCOL);
|
&& ci.Protocol == PROTOCOL);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"couldn't find channel under protocol {PROTOCOL} with externalId {channelName}");
|
// Console.WriteLine($"couldn't find channel under protocol {PROTOCOL} with externalId {channelName}");
|
||||||
c = new Channel()
|
c = new Channel()
|
||||||
{
|
{
|
||||||
Users = []
|
Users = []
|
||||||
@ -206,7 +207,7 @@ public class TwitchInterface
|
|||||||
c = Rememberer.RememberChannel(c);
|
c = Rememberer.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)
|
||||||
{
|
{
|
||||||
selfAccountInChannel = UpsertAccount(selfAccountInProtocol.Username, c);
|
selfAccountInChannel = UpsertAccount(selfAccountInProtocol.Username, c);
|
||||||
}
|
}
|
||||||
@ -215,11 +216,11 @@ public class TwitchInterface
|
|||||||
}
|
}
|
||||||
private Channel UpsertDMChannel(string whisperWith)
|
private Channel UpsertDMChannel(string whisperWith)
|
||||||
{
|
{
|
||||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
||||||
&& ci.Protocol == PROTOCOL);
|
&& ci.Protocol == PROTOCOL);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"couldn't find channel under protocol {PROTOCOL}, whisper with {whisperWith}");
|
// Console.WriteLine($"couldn't find channel under protocol {PROTOCOL}, whisper with {whisperWith}");
|
||||||
c = new Channel()
|
c = new Channel()
|
||||||
{
|
{
|
||||||
Users = []
|
Users = []
|
||||||
@ -233,29 +234,32 @@ Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
|||||||
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.SendMessage = (t) => { return Task.Run(() => {
|
c.SendMessage = (t) =>
|
||||||
|
{
|
||||||
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
client.SendWhisper(whisperWith, t);
|
client.SendWhisper(whisperWith, t);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine(e);
|
Console.Error.WriteLine(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
||||||
c = Rememberer.RememberChannel(c);
|
c = Rememberer.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)
|
||||||
{
|
{
|
||||||
selfAccountInChannel = UpsertAccount(selfAccountInChannel.Username, c);
|
selfAccountInChannel = UpsertAccount(selfAccountInChannel.Username, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
//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".
|
||||||
//ah, but that's the trick, they aren't! twitchlib has a common base class, but
|
//ah, but that's the trick, they aren't! twitchlib has a common base class, but
|
||||||
|
@ -179,7 +179,16 @@ public static class Rememberer
|
|||||||
dbAccessSemaphore.Release();
|
dbAccessSemaphore.Release();
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
public static void RememberUAC(UAC toRemember)
|
public static List<UAC> SearchUACs(Expression<Func<UAC, bool>> predicate)
|
||||||
|
{
|
||||||
|
List<UAC> toReturn;
|
||||||
|
dbAccessSemaphore.Wait();
|
||||||
|
toReturn = db.UACs.Include(uac => uac.Users).Include(uac => uac.Channels).Include(uac => uac.AccountInChannels)
|
||||||
|
.Where(predicate).ToList();
|
||||||
|
dbAccessSemaphore.Release();
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
public static void RememberUAC(UAC toRemember)
|
||||||
{
|
{
|
||||||
dbAccessSemaphore.Wait();
|
dbAccessSemaphore.Wait();
|
||||||
db.Update(toRemember);
|
db.Update(toRemember);
|
||||||
|
@ -14,5 +14,12 @@
|
|||||||
],
|
],
|
||||||
"exchangePairsLocation": "assets/exchangepairs.json",
|
"exchangePairsLocation": "assets/exchangepairs.json",
|
||||||
"DBConnectionString": "Host=azure.club;Database=db;Username=user;Password=password",
|
"DBConnectionString": "Host=azure.club;Database=db;Username=user;Password=password",
|
||||||
"SetupSlashCommands": false
|
"SetupSlashCommands": false,
|
||||||
|
"Webhooks": [
|
||||||
|
{
|
||||||
|
"uacID": "9a94855a-e5a2-43b5-8420-ce670472ce95",
|
||||||
|
"Trigger": "test",
|
||||||
|
"Uri": "http://localhost"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user