a lot of my problems are who owns what

This commit is contained in:
adam 2025-02-27 16:17:26 -05:00
parent 3ed37959ad
commit c971add137
4 changed files with 172 additions and 49 deletions

View File

@ -5,10 +5,10 @@ namespace vassago
using vassago.Models; using vassago.Models;
using vassago.TwitchInterface; using vassago.TwitchInterface;
using vassago.ProtocolInterfaces.DiscordInterface; using vassago.ProtocolInterfaces.DiscordInterface;
using System.Runtime.CompilerServices;
internal class ConsoleService : IHostedService internal class ConsoleService : IHostedService
{ {
public ConsoleService(IConfiguration aspConfig) public ConsoleService(IConfiguration aspConfig)
{ {
Shared.DBConnectionString = aspConfig["DBConnectionString"]; Shared.DBConnectionString = aspConfig["DBConnectionString"];
@ -22,14 +22,15 @@ namespace vassago
public async Task StartAsync(CancellationToken cancellationToken) public async Task StartAsync(CancellationToken cancellationToken)
{ {
var initTasks = new List<Task>();
var dbc = new ChattingContext(); var dbc = new ChattingContext();
await dbc.Database.MigrateAsync(); await dbc.Database.MigrateAsync(cancellationToken);
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();
await d.Init(dt); initTasks.Add(d.Init(dt));
ProtocolInterfaces.ProtocolList.discords.Add(d); ProtocolInterfaces.ProtocolList.discords.Add(d);
} }
@ -37,9 +38,11 @@ namespace vassago
foreach (var tc in TwitchConfigs) foreach (var tc in TwitchConfigs)
{ {
var t = new TwitchInterface.TwitchInterface(); var t = new TwitchInterface.TwitchInterface();
await t.Init(tc); initTasks.Add(t.Init(tc));
ProtocolInterfaces.ProtocolList.twitchs.Add(t); ProtocolInterfaces.ProtocolList.twitchs.Add(t);
} }
Task.WaitAll(initTasks, cancellationToken);
} }
public Task StopAsync(CancellationToken cancellationToken) public Task StopAsync(CancellationToken cancellationToken)

View File

@ -70,7 +70,8 @@ public class DiscordInterface
protocolAsChannel.DisplayName = "discord (itself)"; protocolAsChannel.DisplayName = "discord (itself)";
protocolAsChannel.SendMessage = (t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot accept text"); }; protocolAsChannel.SendMessage = (t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot accept text"); };
protocolAsChannel.SendFile = (f, t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot send file"); }; protocolAsChannel.SendFile = (f, t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot send file"); };
Rememberer.RememberChannel(protocolAsChannel); protocolAsChannel= Rememberer.RememberChannel(protocolAsChannel);
Console.WriteLine($"protocol as channel addeed; {protocolAsChannel}");
} }
finally finally
{ {
@ -110,11 +111,20 @@ public class DiscordInterface
} }
} }
private void SelfConnected() private async Task SelfConnected()
{ {
var selfAccount = UpsertAccount(client.CurrentUser, protocolAsChannel); await discordChannelSetup.WaitAsync();
selfAccount.DisplayName = client.CurrentUser.Username;
Behaver.Instance.MarkSelf(selfAccount); try
{
var selfAccount = UpsertAccount(client.CurrentUser, protocolAsChannel);
selfAccount.DisplayName = client.CurrentUser.Username;
Behaver.Instance.MarkSelf(selfAccount);
}
finally
{
discordChannelSetup.Release();
}
} }
private async Task MessageReceived(SocketMessage messageParam) private async Task MessageReceived(SocketMessage messageParam)
@ -195,7 +205,6 @@ public class DiscordInterface
Protocol = PROTOCOL Protocol = PROTOCOL
}; };
if (dMessage.Attachments?.Count > 0) if (dMessage.Attachments?.Count > 0)
{ {
m.Attachments = []; m.Attachments = [];
@ -209,6 +218,7 @@ public class DiscordInterface
m.Timestamp = dMessage.EditedTimestamp ?? dMessage.CreatedAt; m.Timestamp = dMessage.EditedTimestamp ?? dMessage.CreatedAt;
m.Channel = UpsertChannel(dMessage.Channel); m.Channel = UpsertChannel(dMessage.Channel);
m.Author = UpsertAccount(dMessage.Author, m.Channel); m.Author = UpsertAccount(dMessage.Author, m.Channel);
Console.WriteLine($"received message; author: {m.Author.DisplayName}, {m.Author.Id}");
if (dMessage.Channel is IGuildChannel) if (dMessage.Channel is IGuildChannel)
{ {
m.Author.DisplayName = (dMessage.Author as IGuildUser).DisplayName;//discord forgot how display names work. m.Author.DisplayName = (dMessage.Author as IGuildUser).DisplayName;//discord forgot how display names work.
@ -218,7 +228,7 @@ public class DiscordInterface
m.Reply = (t) => { return dMessage.ReplyAsync(t); }; m.Reply = (t) => { return dMessage.ReplyAsync(t); };
m.React = (e) => { return AttemptReact(dMessage, e); }; m.React = (e) => { return AttemptReact(dMessage, e); };
Rememberer.RememberChannel(m.Channel); Rememberer.RememberMessage(m);
return m; return m;
} }
internal Channel UpsertChannel(IMessageChannel channel) internal Channel UpsertChannel(IMessageChannel channel)
@ -237,7 +247,8 @@ public class DiscordInterface
c.Protocol = PROTOCOL; c.Protocol = PROTOCOL;
if (channel is IGuildChannel) if (channel is IGuildChannel)
{ {
UpsertChannel((channel as IGuildChannel).Guild); Console.WriteLine($"{channel.Name} is a guild channel. So i'm going to upsert the guild, {(channel as IGuildChannel).Guild}");
c.ParentChannel = UpsertChannel((channel as IGuildChannel).Guild);
} }
else if (channel is IPrivateChannel) else if (channel is IPrivateChannel)
{ {
@ -255,12 +266,15 @@ public class DiscordInterface
c.DisplayName = "DM: " + (channel as IPrivateChannel).Recipients?.FirstOrDefault(u => u.Id != client.CurrentUser.Id).Username; c.DisplayName = "DM: " + (channel as IPrivateChannel).Recipients?.FirstOrDefault(u => u.Id != client.CurrentUser.Id).Username;
break; break;
} }
Rememberer.RememberChannel(c);
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 = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == PROTOCOL);
if(parentChannel is null)
{
Console.Error.WriteLine("why am I still null?");
}
} }
else if (channel is IPrivateChannel) else if (channel is IPrivateChannel)
{ {
@ -273,11 +287,11 @@ public class DiscordInterface
} }
parentChannel.SubChannels ??= []; parentChannel.SubChannels ??= [];
parentChannel.SubChannels.Add(c); parentChannel.SubChannels.Add(c);
Rememberer.RememberChannel(parentChannel);
c.SendMessage = (t) => { return channel.SendMessageAsync(t); }; c.SendMessage = (t) => { return channel.SendMessageAsync(t); };
c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); }; c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); };
return c;
return Rememberer.RememberChannel(c);
} }
internal Channel UpsertChannel(IGuild channel) internal Channel UpsertChannel(IGuild channel)
{ {
@ -285,7 +299,6 @@ public class DiscordInterface
if (c == null) if (c == null)
{ {
c = new Channel(); c = new Channel();
Rememberer.RememberChannel(c);
} }
c.DisplayName = channel.Name; c.DisplayName = channel.Name;
@ -299,8 +312,8 @@ public class DiscordInterface
c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); }; c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); };
c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); }; c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); };
Rememberer.RememberChannel(c);
return c; return Rememberer.RememberChannel(c);
} }
internal static Account UpsertAccount(IUser user, Channel inChannel) internal static Account UpsertAccount(IUser user, Channel inChannel)
{ {
@ -314,10 +327,9 @@ public class DiscordInterface
acc.SeenInChannel = inChannel; acc.SeenInChannel = inChannel;
acc.IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol)); acc.IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
//db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol)); acc.IsUser ??= new User() { Accounts = [ acc ] };
inChannel.Users ??= [];
acc.IsUser ??= new User() { Accounts = [ acc ] }; inChannel.Users.Add(acc);
Rememberer.RememberAccount(acc); Rememberer.RememberAccount(acc);
return acc; return acc;
} }

View File

@ -5,6 +5,7 @@ using vassago.Models;
public static class Rememberer public static class Rememberer
{ {
private static readonly SemaphoreSlim dbAccessSemaphore = new(1, 1);
public static Account SearchAccount(Expression<Func<Account, bool>> predicate) public static Account SearchAccount(Expression<Func<Account, bool>> predicate)
{ {
return (new ChattingContext()).Accounts.FirstOrDefault(predicate); return (new ChattingContext()).Accounts.FirstOrDefault(predicate);
@ -31,49 +32,156 @@ public static class Rememberer
} }
public static void RememberAccount(Account toRemember) public static void RememberAccount(Account toRemember)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
if (toRemember.Id == Guid.Empty) try
db.Accounts.Add(toRemember); {
var db = new ChattingContext();
if (toRemember.Id == Guid.Empty)
{
var parentChannel = toRemember.SeenInChannel;
var isUser = toRemember.IsUser;
toRemember.SeenInChannel = null;
toRemember.IsUser = null;
db.Accounts.Add(toRemember);
db.SaveChanges();
db.SaveChanges(); toRemember.SeenInChannel = parentChannel;
toRemember.IsUser = isUser;
db.SaveChanges();
}
else
{
db.SaveChanges();
}
}
finally
{
dbAccessSemaphore.Release();
}
} }
public static void RememberAttachment(Attachment toRemember) public static void RememberAttachment(Attachment toRemember)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
if (toRemember.Id == Guid.Empty) try
db.Attachments.Add(toRemember); {
var db = new ChattingContext();
db.SaveChanges(); if (toRemember.Id == Guid.Empty)
{
var msg = toRemember.Message;
toRemember.Message = null;
db.Attachments.Add(toRemember);
db.SaveChanges();
toRemember.Message = msg;
db.SaveChanges();
}
else
{
db.SaveChanges();
}
}
finally
{
dbAccessSemaphore.Release();
}
} }
public static void RememberChannel(Channel toRemember) public static Channel RememberChannel(Channel toRemember)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
if (toRemember.Id == Guid.Empty) try
db.Channels.Add(toRemember); {
var db = new ChattingContext();
if (toRemember.Id == Guid.Empty)
{
var parent = toRemember.ParentChannel;
var subChannesl = toRemember.SubChannels;
var msgs = toRemember.Messages;
var accounts = toRemember.Users;
toRemember.ParentChannel = null;
toRemember.SubChannels = null;
toRemember.Messages = null;
toRemember.Users = null;
db.Channels.Add(toRemember);
db.SaveChanges();
toRemember.ParentChannel = parent;
toRemember.SubChannels = subChannesl;
toRemember.Messages = msgs;
toRemember.Users = accounts;
db.SaveChanges();
}
db.SaveChanges(); db.SaveChanges();
}
finally
{
dbAccessSemaphore.Release();
}
return toRemember;
} }
public static void RememberMessage(Message toRemember) public static void RememberMessage(Message toRemember)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
if (toRemember.Id == Guid.Empty) try
{ {
db.Messages.Add(toRemember); var db = new ChattingContext();
if (toRemember.Id == Guid.Empty)
{
var author = toRemember.Author;
var channel = toRemember.Channel;
var attachments = toRemember.Attachments;
toRemember.Author = null;
toRemember.Channel = null;
toRemember.Attachments = null;
db.Messages.Add(toRemember);
db.SaveChanges();
toRemember.Author = author;
toRemember.Channel = channel;
toRemember.Attachments = attachments;
db.SaveChanges();
}
db.SaveChanges();
}
finally
{
dbAccessSemaphore.Release();
} }
db.SaveChanges();
} }
public static void RememberUser(User toRemember) public static void RememberUser(User toRemember)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
if (toRemember.Id == Guid.Empty) try
db.Users.Add(toRemember); {
var db = new ChattingContext();
db.SaveChanges(); if (toRemember.Id == Guid.Empty)
{
var accs = toRemember.Accounts;
toRemember.Accounts = null;
db.Users.Add(toRemember);
db.SaveChanges();
toRemember.Accounts = accs;
db.SaveChanges();
}
else
{
db.SaveChanges();
}
}
finally
{
dbAccessSemaphore.Release();
}
} }
public static void ForgetUser(User toForget) public static void ForgetUser(User toForget)
{ {
var db = new ChattingContext(); dbAccessSemaphore.Wait();
db.Users.Remove(toForget); try
db.SaveChanges(); {
var db = new ChattingContext();
db.Users.Remove(toForget);
db.SaveChanges();
}
finally
{
dbAccessSemaphore.Release();
}
} }
} }

View File

@ -26,7 +26,7 @@ case "$1" in
"db-fullreset") "db-fullreset")
sudo -u postgres psql -c "drop database ${servicename}_dev;" sudo -u postgres psql -c "drop database ${servicename}_dev;"
sudo -u postgres psql -c "delete user $servicename" sudo -u postgres psql -c "drop user $servicename"
$0 "initial" $0 "initial"
;; ;;
*) *)