ok no i take it back, we do need a rememberer?

send 2 messages - it'll pull out a channel and complain it's already been attached.
This commit is contained in:
adam 2025-02-03 20:41:11 -05:00
parent c3a9ac3c54
commit 03fdb56190
8 changed files with 435 additions and 12 deletions

View File

@ -0,0 +1,271 @@
// <auto-generated />
using System;
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("20250204004906_cascade")]
partial class cascade
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
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.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.HasKey("Id");
b.HasIndex("AuthorId");
b.HasIndex("ChannelId");
b.ToTable("Messages");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.HasKey("Id");
b.ToTable("Users");
});
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
}
}
}

View File

@ -0,0 +1,133 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace vassago.Migrations
{
/// <inheritdoc />
public partial class cascade : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Channels_SeenInChannelId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Users_IsUserId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Attachments_Messages_MessageId",
table: "Attachments");
migrationBuilder.DropForeignKey(
name: "FK_Channels_Channels_ParentChannelId",
table: "Channels");
migrationBuilder.DropForeignKey(
name: "FK_Messages_Channels_ChannelId",
table: "Messages");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Channels_SeenInChannelId",
table: "Accounts",
column: "SeenInChannelId",
principalTable: "Channels",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Users_IsUserId",
table: "Accounts",
column: "IsUserId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Attachments_Messages_MessageId",
table: "Attachments",
column: "MessageId",
principalTable: "Messages",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Channels_Channels_ParentChannelId",
table: "Channels",
column: "ParentChannelId",
principalTable: "Channels",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Messages_Channels_ChannelId",
table: "Messages",
column: "ChannelId",
principalTable: "Channels",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Channels_SeenInChannelId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Users_IsUserId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Attachments_Messages_MessageId",
table: "Attachments");
migrationBuilder.DropForeignKey(
name: "FK_Channels_Channels_ParentChannelId",
table: "Channels");
migrationBuilder.DropForeignKey(
name: "FK_Messages_Channels_ChannelId",
table: "Messages");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Channels_SeenInChannelId",
table: "Accounts",
column: "SeenInChannelId",
principalTable: "Channels",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Users_IsUserId",
table: "Accounts",
column: "IsUserId",
principalTable: "Users",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Attachments_Messages_MessageId",
table: "Attachments",
column: "MessageId",
principalTable: "Messages",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Channels_Channels_ParentChannelId",
table: "Channels",
column: "ParentChannelId",
principalTable: "Channels",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Messages_Channels_ChannelId",
table: "Messages",
column: "ChannelId",
principalTable: "Channels",
principalColumn: "Id");
}
}
}

View File

@ -195,11 +195,13 @@ namespace vassago.Migrations
{ {
b.HasOne("vassago.Models.User", "IsUser") b.HasOne("vassago.Models.User", "IsUser")
.WithMany("Accounts") .WithMany("Accounts")
.HasForeignKey("IsUserId"); .HasForeignKey("IsUserId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("vassago.Models.Channel", "SeenInChannel") b.HasOne("vassago.Models.Channel", "SeenInChannel")
.WithMany("Users") .WithMany("Users")
.HasForeignKey("SeenInChannelId"); .HasForeignKey("SeenInChannelId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("IsUser"); b.Navigation("IsUser");
@ -210,7 +212,8 @@ namespace vassago.Migrations
{ {
b.HasOne("vassago.Models.Message", "Message") b.HasOne("vassago.Models.Message", "Message")
.WithMany("Attachments") .WithMany("Attachments")
.HasForeignKey("MessageId"); .HasForeignKey("MessageId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("Message"); b.Navigation("Message");
}); });
@ -219,7 +222,8 @@ namespace vassago.Migrations
{ {
b.HasOne("vassago.Models.Channel", "ParentChannel") b.HasOne("vassago.Models.Channel", "ParentChannel")
.WithMany("SubChannels") .WithMany("SubChannels")
.HasForeignKey("ParentChannelId"); .HasForeignKey("ParentChannelId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("ParentChannel"); b.Navigation("ParentChannel");
}); });
@ -232,7 +236,8 @@ namespace vassago.Migrations
b.HasOne("vassago.Models.Channel", "Channel") b.HasOne("vassago.Models.Channel", "Channel")
.WithMany("Messages") .WithMany("Messages")
.HasForeignKey("ChannelId"); .HasForeignKey("ChannelId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("Author"); b.Navigation("Author");

View File

@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Microsoft.EntityFrameworkCore;
using static vassago.Models.Enumerations; using static vassago.Models.Enumerations;
public class Channel public class Channel
@ -14,10 +15,13 @@ public class Channel
public Guid Id { get; set; } public Guid Id { get; set; }
public string ExternalId { get; set; } public string ExternalId { get; set; }
public string DisplayName { get; set; } public string DisplayName { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List<Channel> SubChannels { get; set; } public List<Channel> SubChannels { get; set; }
public Channel ParentChannel { get; set; } public Channel ParentChannel { get; set; }
public string Protocol { get; set; } public string Protocol { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List<Message> Messages { get; set; } public List<Message> Messages { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List<Account> Users { get; set; } public List<Account> Users { get; set; }
public ChannelType ChannelType {get; set; } public ChannelType ChannelType {get; set; }

View File

@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.WebSocket; using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
public class Message public class Message
{ {
@ -17,6 +18,7 @@ public class Message
public bool MentionsMe { get; set; } public bool MentionsMe { get; set; }
public DateTimeOffset Timestamp { get; set; } public DateTimeOffset Timestamp { get; set; }
public bool ActedOn { get; set; } public bool ActedOn { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List<Attachment> Attachments { get; set; } public List<Attachment> Attachments { get; set; }
public Account Author { get; set; } public Account Author { get; set; }
public Channel Channel { get; set; } public Channel Channel { get; set; }

View File

@ -4,11 +4,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection; using System.Reflection;
using Microsoft.EntityFrameworkCore;
public class User public class User
{ {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; } public Guid Id { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List<Account> Accounts { get; set; } public List<Account> Accounts { get; set; }
//if I ever get lots and lots of tags, or some automatic way to register a feature's arbitrary tags, then I can move this off. //if I ever get lots and lots of tags, or some automatic way to register a feature's arbitrary tags, then I can move this off.

View File

@ -234,7 +234,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); };
db.SaveChangesAsync(); db.SaveChanges();
return m; return m;
} }
internal Channel UpsertChannel(IMessageChannel channel) internal Channel UpsertChannel(IMessageChannel channel)
@ -255,7 +255,7 @@ public class DiscordInterface
c.Protocol = PROTOCOL; c.Protocol = PROTOCOL;
if (channel is IGuildChannel) if (channel is IGuildChannel)
{ {
c.ParentChannel = UpsertChannel((channel as IGuildChannel).Guild); c.ParentChannel = UpsertChannel((channel as IGuildChannel).Guild, db);
c.ParentChannel.SubChannels.Add(c); c.ParentChannel.SubChannels.Add(c);
} }
else if (channel is IPrivateChannel) else if (channel is IPrivateChannel)
@ -277,19 +277,25 @@ 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;
} }
db.SaveChangesAsync(); db.SaveChanges();
return c; return c;
} }
internal Channel UpsertChannel(IGuild channel) internal Channel UpsertChannel(IGuild channel, ChattingContext db = null)
{ {
var db = new ChattingContext(); db = db ?? new ChattingContext();
Console.WriteLine($"upserting *guild*: {channel.Id}");
Channel c = db.Channels.FirstOrDefault(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == PROTOCOL); Channel c = db.Channels.FirstOrDefault(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == PROTOCOL);
if (c == null) if (c == null)
{ {
Console.WriteLine($"don't have one already. Creating.");
c = new Channel(); c = new Channel();
db.Channels.Add(c); db.Channels.Add(c);
Console.WriteLine($"upserting channel {channel.Name} from discord, have to create a new one in the DB"); Console.WriteLine($"upserting channel {channel.Name} from discord, have to create a new one in the DB");
} }
else
{
Console.WriteLine($"found one.");
}
c.DisplayName = channel.Name; c.DisplayName = channel.Name;
c.ExternalId = channel.Id.ToString(); c.ExternalId = channel.Id.ToString();
@ -307,7 +313,6 @@ public class DiscordInterface
} }
internal Account UpsertAccount(IUser user, Channel inChannel) internal Account UpsertAccount(IUser user, Channel inChannel)
{ {
var db = new ChattingContext(); var db = new ChattingContext();
var acc = db.Accounts.FirstOrDefault(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id); var acc = db.Accounts.FirstOrDefault(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id);
if (acc == null) if (acc == null)

View File

@ -2,7 +2,8 @@
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore": "None"
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",