runs and listens without exploding

This commit is contained in:
adam 2025-03-11 22:20:09 -04:00
parent 50ecfc5867
commit 53753374f0
4 changed files with 73 additions and 37 deletions

View File

@ -237,10 +237,12 @@ public class DiscordInterface
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()}");
c = new Channel(); c = new Channel()
{
Users = []
};
} }
c.DisplayName = channel.Name;
c.ExternalId = channel.Id.ToString(); c.ExternalId = channel.Id.ToString();
c.ChannelType = (channel is IPrivateChannel) ? vassago.Models.Enumerations.ChannelType.DM : vassago.Models.Enumerations.ChannelType.Normal; c.ChannelType = (channel is IPrivateChannel) ? vassago.Models.Enumerations.ChannelType.DM : vassago.Models.Enumerations.ChannelType.Normal;
c.Messages ??= []; c.Messages ??= [];
@ -263,7 +265,11 @@ public class DiscordInterface
switch (c.ChannelType) switch (c.ChannelType)
{ {
case vassago.Models.Enumerations.ChannelType.DM: case vassago.Models.Enumerations.ChannelType.DM:
c.DisplayName = "DM: " + (channel as IPrivateChannel).Recipients?.FirstOrDefault(u => u.Id != client.CurrentUser.Id).Username; var asPriv =(channel as IPrivateChannel);
c.DisplayName = "DM: " + asPriv?.Recipients?.FirstOrDefault(u => u.Id != client.CurrentUser.Id).Username;
break;
default:
c.DisplayName = channel.Name;
break; break;
} }
@ -286,12 +292,23 @@ public class DiscordInterface
Console.Error.WriteLine($"trying to upsert channel {channel.Id}/{channel.Name}, but it's neither guildchannel nor private channel. shrug.jpg"); Console.Error.WriteLine($"trying to upsert channel {channel.Id}/{channel.Name}, but it's neither guildchannel nor private channel. shrug.jpg");
} }
parentChannel.SubChannels ??= []; parentChannel.SubChannels ??= [];
parentChannel.SubChannels.Add(c); if(!parentChannel.SubChannels.Contains(c))
{
parentChannel.SubChannels.Add(c);
}
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 Rememberer.RememberChannel(c); c = Rememberer.RememberChannel(c);
var selfAccountInChannel = c.Users.FirstOrDefault(a => a.ExternalId == client.CurrentUser.Id.ToString());
if(selfAccountInChannel == null)
{
selfAccountInChannel = UpsertAccount(client.CurrentUser, c);
}
return c;
} }
internal Channel UpsertChannel(IGuild channel) internal Channel UpsertChannel(IGuild channel)
{ {
@ -316,22 +333,22 @@ public class DiscordInterface
return Rememberer.RememberChannel(c); return Rememberer.RememberChannel(c);
} }
internal static Account UpsertAccount(IUser user, Channel inChannel) internal static Account UpsertAccount(IUser discordUser, Channel inChannel)
{ {
var acc = Rememberer.SearchAccount(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id); var acc = Rememberer.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)
{ {
Console.WriteLine($"acc's user: {acc.IsUser?.Id}"); Console.WriteLine($"acc's user: {acc.IsUser?.Id}");
} }
acc ??= new Account() { acc ??= new Account() {
IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol)) IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == discordUser.Id.ToString() && a.Protocol == PROTOCOL))
?? new User() ?? new User()
}; };
acc.Username = user.Username; acc.Username = discordUser.Username;
acc.ExternalId = user.Id.ToString(); acc.ExternalId = discordUser.Id.ToString();
acc.IsBot = user.IsBot || user.IsWebhook; acc.IsBot = discordUser.IsBot || discordUser.IsWebhook;
acc.Protocol = PROTOCOL; acc.Protocol = PROTOCOL;
acc.SeenInChannel = inChannel; acc.SeenInChannel = inChannel;
@ -345,8 +362,13 @@ public class DiscordInterface
{ {
Console.WriteLine($"channel has {inChannel.Users.Count} accounts"); Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
} }
inChannel.Users ??= [acc];
Rememberer.RememberAccount(acc); Rememberer.RememberAccount(acc);
inChannel.Users ??= [];
if(!inChannel.Users.Contains(acc))
{
inChannel.Users.Add(acc);
Rememberer.RememberChannel(inChannel);
}
return acc; return acc;
} }

View File

@ -61,6 +61,27 @@ public static class Rememberer
db.SaveChanges(); db.SaveChanges();
} }
public static void ForgetAccount(Account toForget)
{
var user = toForget.IsUser;
var usersOnlyAccount = user.Accounts?.Count == 1;
if(usersOnlyAccount)
{
Rememberer.ForgetUser(user);
}
else
{
db.Accounts.Remove(toForget);
db.SaveChanges();
}
}
public static void ForgetChannel(Channel toForget)
{
db.Channels.Remove(toForget);
db.SaveChanges();
}
public static void ForgetUser(User toForget) public static void ForgetUser(User toForget)
{ {
db.Users.Remove(toForget); db.Users.Remove(toForget);
@ -69,11 +90,11 @@ public static class Rememberer
} }
public static List<Account> AccountsOverview() public static List<Account> AccountsOverview()
{ {
return db.Accounts.ToList(); return [..db.Accounts];
} }
public static List<Channel> ChannelsOverview() public static List<Channel> ChannelsOverview()
{ {
return db.Channels.Include(u => u.SubChannels).Include(c => c.ParentChannel).ToList(); return [..db.Channels.Include(u => u.SubChannels).Include(c => c.ParentChannel)];
} }
public static Channel ChannelDetail(Guid Id) public static Channel ChannelDetail(Guid Id)
{ {

View File

@ -25,7 +25,7 @@ public class HomeController : Controller
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: \"channels\", nodes: ["); sb.Append("{text: \"channels\", expanded:true, nodes: [");
var first = true; var first = true;
var topLevelChannels = Rememberer.ChannelsOverview().Where(x => x.ParentChannel == null); var topLevelChannels = Rememberer.ChannelsOverview().Where(x => x.ParentChannel == null);
@ -46,7 +46,7 @@ public class HomeController : Controller
if (allChannels.Any()) if (allChannels.Any())
{ {
sb.Append(",{text: \"orphaned channels\", nodes: ["); sb.Append(",{text: \"orphaned channels\", expanded:true, nodes: [");
first = true; first = true;
while (true) while (true)
{ {
@ -68,7 +68,7 @@ public class HomeController : Controller
} }
if (allAccounts.Any()) if (allAccounts.Any())
{ {
sb.Append(",{text: \"channelless accounts\", nodes: ["); sb.Append(",{text: \"channelless accounts\", expanded:true, nodes: [");
first = true; first = true;
foreach (var acc in allAccounts) foreach (var acc in allAccounts)
{ {
@ -87,7 +87,7 @@ public class HomeController : Controller
var users = Rememberer.UsersOverview();// _db.Users.ToList(); var users = Rememberer.UsersOverview();// _db.Users.ToList();
if(users.Any()) if(users.Any())
{ {
sb.Append(",{text: \"users\", 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 = Rememberer.AccountsOverview();
@ -105,7 +105,7 @@ public class HomeController : Controller
} }
sb.Append("]}"); sb.Append("]}");
} }
sb.Append("]"); sb.Append(']');
ViewData.Add("treeString", sb.ToString()); ViewData.Add("treeString", sb.ToString());
return View("Index"); return View("Index");
} }
@ -114,6 +114,7 @@ public class HomeController : Controller
allChannels.Remove(currentChannel); allChannels.Remove(currentChannel);
//"but adam", you say, "there's an href attribute, why make a link?" because that makes the entire bar a link, and trying to expand the node will probably click the link //"but adam", you say, "there's an href attribute, why make a link?" because that makes the entire bar a link, and trying to expand the node will probably click the link
sb.Append($"{{\"text\": \"<a href=\\\"{Url.ActionLink(action: "Details", controller: "Channels", values: new {id = currentChannel.Id})}\\\">{currentChannel.DisplayName}</a>\""); sb.Append($"{{\"text\": \"<a href=\\\"{Url.ActionLink(action: "Details", controller: "Channels", values: new {id = currentChannel.Id})}\\\">{currentChannel.DisplayName}</a>\"");
sb.Append(", expanded:true ");
var theseAccounts = allAccounts.Where(a => a.SeenInChannel?.Id == currentChannel.Id).ToList(); var theseAccounts = allAccounts.Where(a => a.SeenInChannel?.Id == currentChannel.Id).ToList();
allAccounts.RemoveAll(a => a.SeenInChannel?.Id == currentChannel.Id); allAccounts.RemoveAll(a => a.SeenInChannel?.Id == currentChannel.Id);
var first = true; var first = true;
@ -123,7 +124,7 @@ public class HomeController : Controller
} }
if (currentChannel.SubChannels != null) if (currentChannel.SubChannels != null)
{ {
foreach (var subChannel in currentChannel.SubChannels ?? new List<Channel>()) foreach (var subChannel in currentChannel.SubChannels)
{ {
if (first) if (first)
{ {
@ -135,7 +136,7 @@ public class HomeController : Controller
} }
serializeChannel(ref sb, ref allChannels, ref allAccounts, subChannel); serializeChannel(ref sb, ref allChannels, ref allAccounts, subChannel);
} }
if (theseAccounts != null) if (theseAccounts != null && !first) //"first" here tells us that we have at least one subchannel
{ {
sb.Append(','); sb.Append(',');
} }

View File

@ -11,26 +11,24 @@ namespace vassago.Controllers.api;
public class ChannelsController : ControllerBase public class ChannelsController : ControllerBase
{ {
private readonly ILogger<ChannelsController> _logger; private readonly ILogger<ChannelsController> _logger;
private readonly ChattingContext _db;
public ChannelsController(ILogger<ChannelsController> logger, ChattingContext db) public ChannelsController(ILogger<ChannelsController> logger)
{ {
_logger = logger; _logger = logger;
_db = db;
} }
[HttpGet("{id}")] [HttpGet("{id}")]
[Produces("application/json")] [Produces("application/json")]
public Channel Get(Guid id) public Channel Get(Guid id)
{ {
return _db.Find<Channel>(id); return Rememberer.ChannelDetail(id);
} }
[HttpPatch] [HttpPatch]
[Produces("application/json")] [Produces("application/json")]
public IActionResult Patch([FromBody] Channel channel) public IActionResult Patch([FromBody] Channel channel)
{ {
var fromDb = _db.Channels.Find(channel.Id); var fromDb = Rememberer.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");
@ -39,21 +37,20 @@ public class ChannelsController : 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;
_db.SaveChanges(); Rememberer.RememberChannel(fromDb);
return Ok(fromDb); return Ok(fromDb);
} }
[HttpDelete] [HttpDelete]
[Produces("application/json")] [Produces("application/json")]
public IActionResult Delete([FromBody] Channel channel) public IActionResult Delete([FromBody] Channel channel)
{ {
var fromDb = _db.Channels.Find(channel.Id); var fromDb = Rememberer.ChannelDetail(channel.Id);
if (fromDb == null) if (fromDb == null)
{ {
_logger.LogError($"attempt to delete channel {channel.Id}, not found"); _logger.LogError($"attempt to delete channel {channel.Id}, not found");
return NotFound(); return NotFound();
} }
deleteChannel(fromDb); deleteChannel(fromDb);
_db.SaveChanges();
return Ok(); return Ok();
} }
private void deleteChannel(Channel channel) private void deleteChannel(Channel channel)
@ -74,21 +71,16 @@ public class ChannelsController : ControllerBase
} }
} }
if(channel.Messages?.Count > 0) Rememberer.ForgetChannel(channel);
{
_db.Remove(channel.Messages);
}
_db.Remove(channel);
} }
private void deleteAccount(Account account) private void deleteAccount(Account account)
{ {
var user = account.IsUser; var user = account.IsUser;
var usersOnlyAccount = user.Accounts?.Count == 1; var usersOnlyAccount = user.Accounts?.Count == 1;
_db.Remove(account); Rememberer.ForgetAccount(account);
if(usersOnlyAccount) if(usersOnlyAccount)
_db.Users.Remove(user); Rememberer.ForgetUser(user);
} }
} }