summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config/dotnet-tools.json5
-rw-r--r--Controllers/MediaController.cs15
-rw-r--r--Enum.cs6
-rw-r--r--Media.cs2
-rw-r--r--Migrations/20260131125650_InitialMigration.Designer.cs362
-rw-r--r--Migrations/20260131125650_InitialMigration.cs319
-rw-r--r--Migrations/HBContextModelSnapshot.cs359
-rw-r--r--Pages/TagDefinitions.razor8
-rw-r--r--Server.csproj18
-rw-r--r--Services/MediaService.cs26
-rw-r--r--appsettings.json2
11 files changed, 1095 insertions, 27 deletions
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 558293e..e3d2b85 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,10 +3,11 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
- "version": "7.0.10",
+ "version": "8.0.23",
"commands": [
"dotnet-ef"
- ]
+ ],
+ "rollForward": false
}
}
} \ No newline at end of file
diff --git a/Controllers/MediaController.cs b/Controllers/MediaController.cs
index fa6e7ab..3368f45 100644
--- a/Controllers/MediaController.cs
+++ b/Controllers/MediaController.cs
@@ -79,6 +79,17 @@ public class MediaController : Controller {
.ElementAtOrDefault(0)?
.TryParseDateTimeUtc();
+ // Parse original path from headers
+ string? path =
+ formFile.Headers["X-HyperBooru-Path"]
+ .ElementAtOrDefault(0);
+
+ object? pathType = null;
+ string? pathTypeString =
+ formFile.Headers["X-HyperBooru-PathType"]
+ .ElementAtOrDefault(0);
+ Enum.TryParse(typeof(PathType), pathTypeString, true, out pathType);
+
media = mediaService.Create(
formFile.OpenReadStream(),
formFile.FileName,
@@ -86,7 +97,9 @@ public class MediaController : Controller {
.ElementAtOrDefault(0),
lastAccessTime,
lastWriteTime,
- createTime);
+ createTime,
+ path,
+ (PathType?) pathType);
} catch(MediaCreateException e) {
return BadRequest(e.Message);
}
diff --git a/Enum.cs b/Enum.cs
new file mode 100644
index 0000000..6d68f96
--- /dev/null
+++ b/Enum.cs
@@ -0,0 +1,6 @@
+namespace HyperBooru;
+
+public enum PathType {
+ Windows,
+ Unix
+}
diff --git a/Media.cs b/Media.cs
index dd7534c..51626be 100644
--- a/Media.cs
+++ b/Media.cs
@@ -41,6 +41,8 @@ public class UploadedFile : HBObject {
public DateTime? LastAccessTime { get; set; }
public DateTime? LastWriteTime { get; set; }
public DateTime? CreateTime { get; set; }
+ public string? Path { get; set; }
+ public PathType? PathType { get; set; }
public virtual Media Media { get; set; }
}
diff --git a/Migrations/20260131125650_InitialMigration.Designer.cs b/Migrations/20260131125650_InitialMigration.Designer.cs
new file mode 100644
index 0000000..2e4a05e
--- /dev/null
+++ b/Migrations/20260131125650_InitialMigration.Designer.cs
@@ -0,0 +1,362 @@
+// <auto-generated />
+using System;
+using HyperBooru;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace HyperBooru.Migrations
+{
+ [DbContext(typeof(HBContext))]
+ [Migration("20260131125650_InitialMigration")]
+ partial class InitialMigration
+ {
+ /// <inheritdoc />
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.23")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("HyperBooru.HBObject", b =>
+ {
+ b.Property<int>("ObjectId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ObjectId"));
+
+ b.Property<Guid>("Guid")
+ .HasColumnType("uuid");
+
+ b.HasKey("ObjectId");
+
+ b.HasIndex("Guid");
+
+ b.ToTable("Objects", (string)null);
+
+ b.UseTptMappingStrategy();
+ });
+
+ modelBuilder.Entity("HyperBooru.OcrData", b =>
+ {
+ b.Property<int>("OcrDataId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("OcrDataId"));
+
+ b.Property<int>("MediaId")
+ .HasColumnType("integer");
+
+ b.Property<string>("SearchableText")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Text")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<DateTime>("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("OcrDataId");
+
+ b.HasIndex("MediaId")
+ .IsUnique();
+
+ b.ToTable("OcrData");
+ });
+
+ modelBuilder.Entity("TagDefinitionTagDefinition", b =>
+ {
+ b.Property<int>("ImplicitTagsObjectId")
+ .HasColumnType("integer");
+
+ b.Property<int>("TagDefinitionObjectId")
+ .HasColumnType("integer");
+
+ b.HasKey("ImplicitTagsObjectId", "TagDefinitionObjectId");
+
+ b.HasIndex("TagDefinitionObjectId");
+
+ b.ToTable("TagDefinitionTagDefinition");
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<int?>("CurrentUploadedFileId")
+ .HasColumnType("integer");
+
+ b.Property<string>("LongDescription")
+ .HasColumnType("text");
+
+ b.Property<string>("ShortDescription")
+ .HasColumnType("text");
+
+ b.HasIndex("CurrentUploadedFileId")
+ .IsUnique();
+
+ b.ToTable("Media", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.Tag", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<DateTime>("CreateTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<int>("TagDefinitionId")
+ .HasColumnType("integer");
+
+ b.Property<int>("TargetObjectId")
+ .HasColumnType("integer");
+
+ b.HasIndex("TagDefinitionId");
+
+ b.HasIndex("TargetObjectId");
+
+ b.ToTable("Tags", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.TagDefinition", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("Alias")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Namespace")
+ .HasColumnType("text");
+
+ b.Property<int>("Source")
+ .HasColumnType("integer");
+
+ b.ToTable("TagDefinitions", (string)null);
+
+ b.HasData(
+ new
+ {
+ ObjectId = -1,
+ Guid = new Guid("ebdad4f8-455a-4351-8017-1d4854d6fa38"),
+ Name = "nsfw",
+ Source = 0
+ },
+ new
+ {
+ ObjectId = -2,
+ Guid = new Guid("ea212801-5bcc-4c0e-814f-fb9d30db58bc"),
+ Name = "ingest",
+ Source = 0
+ });
+ });
+
+ modelBuilder.Entity("HyperBooru.UploadedFile", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("Checksum")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<bool>("ChecksumVerified")
+ .HasColumnType("boolean");
+
+ b.Property<DateTime?>("CreateTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("Filename")
+ .HasColumnType("text");
+
+ b.Property<int?>("Height")
+ .HasColumnType("integer");
+
+ b.Property<DateTime?>("LastAccessTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<DateTime?>("LastWriteTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<long>("Length")
+ .HasColumnType("bigint");
+
+ b.Property<int>("MediaObjectId")
+ .HasColumnType("integer");
+
+ b.Property<string>("MimeType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Path")
+ .HasColumnType("text");
+
+ b.Property<int?>("PathType")
+ .HasColumnType("integer");
+
+ b.Property<DateTime>("UploadTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<int?>("Width")
+ .HasColumnType("integer");
+
+ b.HasIndex("MediaObjectId");
+
+ b.ToTable("UploadedFiles", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.User", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("PasswordHash")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Username")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasIndex("Username");
+
+ b.ToTable("Users");
+
+ b.HasData(
+ new
+ {
+ ObjectId = -3,
+ Guid = new Guid("4fa948f4-7c45-4f81-bb6b-e417491e6c96"),
+ PasswordHash = "P4geAuE2yX/PDRHuJSq74FF5vO782rWz5c0LAQPR8m45DEYAONhu1wYnAn60PSNyjocqEBdnCeKCJfK3sKyuWw==",
+ Username = "admin"
+ });
+ });
+
+ modelBuilder.Entity("HyperBooru.OcrData", b =>
+ {
+ b.HasOne("HyperBooru.Media", "Media")
+ .WithOne("OcrData")
+ .HasForeignKey("HyperBooru.OcrData", "MediaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Media");
+ });
+
+ modelBuilder.Entity("TagDefinitionTagDefinition", b =>
+ {
+ b.HasOne("HyperBooru.TagDefinition", null)
+ .WithMany()
+ .HasForeignKey("ImplicitTagsObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.TagDefinition", null)
+ .WithMany()
+ .HasForeignKey("TagDefinitionObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.HasOne("HyperBooru.UploadedFile", "CurrentUploadedFile")
+ .WithOne()
+ .HasForeignKey("HyperBooru.Media", "CurrentUploadedFileId");
+
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.Media", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CurrentUploadedFile");
+ });
+
+ modelBuilder.Entity("HyperBooru.Tag", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.Tag", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.TagDefinition", "TagDefinition")
+ .WithMany()
+ .HasForeignKey("TagDefinitionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.HBObject", "Target")
+ .WithMany("Tags")
+ .HasForeignKey("TargetObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("TagDefinition");
+
+ b.Navigation("Target");
+ });
+
+ modelBuilder.Entity("HyperBooru.TagDefinition", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.TagDefinition", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.UploadedFile", b =>
+ {
+ b.HasOne("HyperBooru.Media", "Media")
+ .WithMany("UploadedFiles")
+ .HasForeignKey("MediaObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.UploadedFile", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Media");
+ });
+
+ modelBuilder.Entity("HyperBooru.User", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.User", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.HBObject", b =>
+ {
+ b.Navigation("Tags");
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.Navigation("OcrData");
+
+ b.Navigation("UploadedFiles");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Migrations/20260131125650_InitialMigration.cs b/Migrations/20260131125650_InitialMigration.cs
new file mode 100644
index 0000000..a1a7d8f
--- /dev/null
+++ b/Migrations/20260131125650_InitialMigration.cs
@@ -0,0 +1,319 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
+
+namespace HyperBooru.Migrations
+{
+ /// <inheritdoc />
+ public partial class InitialMigration : Migration
+ {
+ /// <inheritdoc />
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Objects",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ Guid = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Objects", x => x.ObjectId);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "TagDefinitions",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false),
+ Source = table.Column<int>(type: "integer", nullable: false),
+ Namespace = table.Column<string>(type: "text", nullable: true),
+ Name = table.Column<string>(type: "text", nullable: false),
+ Alias = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TagDefinitions", x => x.ObjectId);
+ table.ForeignKey(
+ name: "FK_TagDefinitions_Objects_ObjectId",
+ column: x => x.ObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Users",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false),
+ Username = table.Column<string>(type: "text", nullable: false),
+ PasswordHash = table.Column<string>(type: "text", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Users", x => x.ObjectId);
+ table.ForeignKey(
+ name: "FK_Users_Objects_ObjectId",
+ column: x => x.ObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "TagDefinitionTagDefinition",
+ columns: table => new
+ {
+ ImplicitTagsObjectId = table.Column<int>(type: "integer", nullable: false),
+ TagDefinitionObjectId = table.Column<int>(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TagDefinitionTagDefinition", x => new { x.ImplicitTagsObjectId, x.TagDefinitionObjectId });
+ table.ForeignKey(
+ name: "FK_TagDefinitionTagDefinition_TagDefinitions_ImplicitTagsObjec~",
+ column: x => x.ImplicitTagsObjectId,
+ principalTable: "TagDefinitions",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_TagDefinitionTagDefinition_TagDefinitions_TagDefinitionObje~",
+ column: x => x.TagDefinitionObjectId,
+ principalTable: "TagDefinitions",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Tags",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false),
+ TagDefinitionId = table.Column<int>(type: "integer", nullable: false),
+ CreateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
+ TargetObjectId = table.Column<int>(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Tags", x => x.ObjectId);
+ table.ForeignKey(
+ name: "FK_Tags_Objects_ObjectId",
+ column: x => x.ObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Tags_Objects_TargetObjectId",
+ column: x => x.TargetObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Tags_TagDefinitions_TagDefinitionId",
+ column: x => x.TagDefinitionId,
+ principalTable: "TagDefinitions",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Media",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false),
+ ShortDescription = table.Column<string>(type: "text", nullable: true),
+ LongDescription = table.Column<string>(type: "text", nullable: true),
+ CurrentUploadedFileId = table.Column<int>(type: "integer", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Media", x => x.ObjectId);
+ table.ForeignKey(
+ name: "FK_Media_Objects_ObjectId",
+ column: x => x.ObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "OcrData",
+ columns: table => new
+ {
+ OcrDataId = table.Column<int>(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ MediaId = table.Column<int>(type: "integer", nullable: false),
+ Text = table.Column<string>(type: "text", nullable: false),
+ SearchableText = table.Column<string>(type: "text", nullable: false),
+ Timestamp = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_OcrData", x => x.OcrDataId);
+ table.ForeignKey(
+ name: "FK_OcrData_Media_MediaId",
+ column: x => x.MediaId,
+ principalTable: "Media",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UploadedFiles",
+ columns: table => new
+ {
+ ObjectId = table.Column<int>(type: "integer", nullable: false),
+ Checksum = table.Column<string>(type: "text", nullable: false),
+ ChecksumVerified = table.Column<bool>(type: "boolean", nullable: false),
+ Filename = table.Column<string>(type: "text", nullable: true),
+ Length = table.Column<long>(type: "bigint", nullable: false),
+ MimeType = table.Column<string>(type: "text", nullable: false),
+ Width = table.Column<int>(type: "integer", nullable: true),
+ Height = table.Column<int>(type: "integer", nullable: true),
+ UploadTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
+ LastAccessTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
+ LastWriteTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
+ CreateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
+ Path = table.Column<string>(type: "text", nullable: true),
+ PathType = table.Column<int>(type: "integer", nullable: true),
+ MediaObjectId = table.Column<int>(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UploadedFiles", x => x.ObjectId);
+ table.ForeignKey(
+ name: "FK_UploadedFiles_Media_MediaObjectId",
+ column: x => x.MediaObjectId,
+ principalTable: "Media",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_UploadedFiles_Objects_ObjectId",
+ column: x => x.ObjectId,
+ principalTable: "Objects",
+ principalColumn: "ObjectId",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.InsertData(
+ table: "Objects",
+ columns: new[] { "ObjectId", "Guid" },
+ values: new object[,]
+ {
+ { -3, new Guid("4fa948f4-7c45-4f81-bb6b-e417491e6c96") },
+ { -2, new Guid("ea212801-5bcc-4c0e-814f-fb9d30db58bc") },
+ { -1, new Guid("ebdad4f8-455a-4351-8017-1d4854d6fa38") }
+ });
+
+ migrationBuilder.InsertData(
+ table: "TagDefinitions",
+ columns: new[] { "ObjectId", "Alias", "Name", "Namespace", "Source" },
+ values: new object[,]
+ {
+ { -2, null, "ingest", null, 0 },
+ { -1, null, "nsfw", null, 0 }
+ });
+
+ migrationBuilder.InsertData(
+ table: "Users",
+ columns: new[] { "ObjectId", "PasswordHash", "Username" },
+ values: new object[] { -3, "P4geAuE2yX/PDRHuJSq74FF5vO782rWz5c0LAQPR8m45DEYAONhu1wYnAn60PSNyjocqEBdnCeKCJfK3sKyuWw==", "admin" });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Media_CurrentUploadedFileId",
+ table: "Media",
+ column: "CurrentUploadedFileId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Objects_Guid",
+ table: "Objects",
+ column: "Guid");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_OcrData_MediaId",
+ table: "OcrData",
+ column: "MediaId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_TagDefinitionTagDefinition_TagDefinitionObjectId",
+ table: "TagDefinitionTagDefinition",
+ column: "TagDefinitionObjectId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Tags_TagDefinitionId",
+ table: "Tags",
+ column: "TagDefinitionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Tags_TargetObjectId",
+ table: "Tags",
+ column: "TargetObjectId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UploadedFiles_MediaObjectId",
+ table: "UploadedFiles",
+ column: "MediaObjectId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_Username",
+ table: "Users",
+ column: "Username");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Media_UploadedFiles_CurrentUploadedFileId",
+ table: "Media",
+ column: "CurrentUploadedFileId",
+ principalTable: "UploadedFiles",
+ principalColumn: "ObjectId");
+ }
+
+ /// <inheritdoc />
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Media_Objects_ObjectId",
+ table: "Media");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_UploadedFiles_Objects_ObjectId",
+ table: "UploadedFiles");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_Media_UploadedFiles_CurrentUploadedFileId",
+ table: "Media");
+
+ migrationBuilder.DropTable(
+ name: "OcrData");
+
+ migrationBuilder.DropTable(
+ name: "TagDefinitionTagDefinition");
+
+ migrationBuilder.DropTable(
+ name: "Tags");
+
+ migrationBuilder.DropTable(
+ name: "Users");
+
+ migrationBuilder.DropTable(
+ name: "TagDefinitions");
+
+ migrationBuilder.DropTable(
+ name: "Objects");
+
+ migrationBuilder.DropTable(
+ name: "UploadedFiles");
+
+ migrationBuilder.DropTable(
+ name: "Media");
+ }
+ }
+}
diff --git a/Migrations/HBContextModelSnapshot.cs b/Migrations/HBContextModelSnapshot.cs
new file mode 100644
index 0000000..422037f
--- /dev/null
+++ b/Migrations/HBContextModelSnapshot.cs
@@ -0,0 +1,359 @@
+// <auto-generated />
+using System;
+using HyperBooru;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace HyperBooru.Migrations
+{
+ [DbContext(typeof(HBContext))]
+ partial class HBContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.23")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("HyperBooru.HBObject", b =>
+ {
+ b.Property<int>("ObjectId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ObjectId"));
+
+ b.Property<Guid>("Guid")
+ .HasColumnType("uuid");
+
+ b.HasKey("ObjectId");
+
+ b.HasIndex("Guid");
+
+ b.ToTable("Objects", (string)null);
+
+ b.UseTptMappingStrategy();
+ });
+
+ modelBuilder.Entity("HyperBooru.OcrData", b =>
+ {
+ b.Property<int>("OcrDataId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("OcrDataId"));
+
+ b.Property<int>("MediaId")
+ .HasColumnType("integer");
+
+ b.Property<string>("SearchableText")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Text")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<DateTime>("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("OcrDataId");
+
+ b.HasIndex("MediaId")
+ .IsUnique();
+
+ b.ToTable("OcrData");
+ });
+
+ modelBuilder.Entity("TagDefinitionTagDefinition", b =>
+ {
+ b.Property<int>("ImplicitTagsObjectId")
+ .HasColumnType("integer");
+
+ b.Property<int>("TagDefinitionObjectId")
+ .HasColumnType("integer");
+
+ b.HasKey("ImplicitTagsObjectId", "TagDefinitionObjectId");
+
+ b.HasIndex("TagDefinitionObjectId");
+
+ b.ToTable("TagDefinitionTagDefinition");
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<int?>("CurrentUploadedFileId")
+ .HasColumnType("integer");
+
+ b.Property<string>("LongDescription")
+ .HasColumnType("text");
+
+ b.Property<string>("ShortDescription")
+ .HasColumnType("text");
+
+ b.HasIndex("CurrentUploadedFileId")
+ .IsUnique();
+
+ b.ToTable("Media", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.Tag", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<DateTime>("CreateTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<int>("TagDefinitionId")
+ .HasColumnType("integer");
+
+ b.Property<int>("TargetObjectId")
+ .HasColumnType("integer");
+
+ b.HasIndex("TagDefinitionId");
+
+ b.HasIndex("TargetObjectId");
+
+ b.ToTable("Tags", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.TagDefinition", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("Alias")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Namespace")
+ .HasColumnType("text");
+
+ b.Property<int>("Source")
+ .HasColumnType("integer");
+
+ b.ToTable("TagDefinitions", (string)null);
+
+ b.HasData(
+ new
+ {
+ ObjectId = -1,
+ Guid = new Guid("ebdad4f8-455a-4351-8017-1d4854d6fa38"),
+ Name = "nsfw",
+ Source = 0
+ },
+ new
+ {
+ ObjectId = -2,
+ Guid = new Guid("ea212801-5bcc-4c0e-814f-fb9d30db58bc"),
+ Name = "ingest",
+ Source = 0
+ });
+ });
+
+ modelBuilder.Entity("HyperBooru.UploadedFile", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("Checksum")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<bool>("ChecksumVerified")
+ .HasColumnType("boolean");
+
+ b.Property<DateTime?>("CreateTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("Filename")
+ .HasColumnType("text");
+
+ b.Property<int?>("Height")
+ .HasColumnType("integer");
+
+ b.Property<DateTime?>("LastAccessTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<DateTime?>("LastWriteTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<long>("Length")
+ .HasColumnType("bigint");
+
+ b.Property<int>("MediaObjectId")
+ .HasColumnType("integer");
+
+ b.Property<string>("MimeType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Path")
+ .HasColumnType("text");
+
+ b.Property<int?>("PathType")
+ .HasColumnType("integer");
+
+ b.Property<DateTime>("UploadTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<int?>("Width")
+ .HasColumnType("integer");
+
+ b.HasIndex("MediaObjectId");
+
+ b.ToTable("UploadedFiles", (string)null);
+ });
+
+ modelBuilder.Entity("HyperBooru.User", b =>
+ {
+ b.HasBaseType("HyperBooru.HBObject");
+
+ b.Property<string>("PasswordHash")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Username")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasIndex("Username");
+
+ b.ToTable("Users");
+
+ b.HasData(
+ new
+ {
+ ObjectId = -3,
+ Guid = new Guid("4fa948f4-7c45-4f81-bb6b-e417491e6c96"),
+ PasswordHash = "P4geAuE2yX/PDRHuJSq74FF5vO782rWz5c0LAQPR8m45DEYAONhu1wYnAn60PSNyjocqEBdnCeKCJfK3sKyuWw==",
+ Username = "admin"
+ });
+ });
+
+ modelBuilder.Entity("HyperBooru.OcrData", b =>
+ {
+ b.HasOne("HyperBooru.Media", "Media")
+ .WithOne("OcrData")
+ .HasForeignKey("HyperBooru.OcrData", "MediaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Media");
+ });
+
+ modelBuilder.Entity("TagDefinitionTagDefinition", b =>
+ {
+ b.HasOne("HyperBooru.TagDefinition", null)
+ .WithMany()
+ .HasForeignKey("ImplicitTagsObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.TagDefinition", null)
+ .WithMany()
+ .HasForeignKey("TagDefinitionObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.HasOne("HyperBooru.UploadedFile", "CurrentUploadedFile")
+ .WithOne()
+ .HasForeignKey("HyperBooru.Media", "CurrentUploadedFileId");
+
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.Media", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CurrentUploadedFile");
+ });
+
+ modelBuilder.Entity("HyperBooru.Tag", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.Tag", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.TagDefinition", "TagDefinition")
+ .WithMany()
+ .HasForeignKey("TagDefinitionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.HBObject", "Target")
+ .WithMany("Tags")
+ .HasForeignKey("TargetObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("TagDefinition");
+
+ b.Navigation("Target");
+ });
+
+ modelBuilder.Entity("HyperBooru.TagDefinition", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.TagDefinition", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.UploadedFile", b =>
+ {
+ b.HasOne("HyperBooru.Media", "Media")
+ .WithMany("UploadedFiles")
+ .HasForeignKey("MediaObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.UploadedFile", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Media");
+ });
+
+ modelBuilder.Entity("HyperBooru.User", b =>
+ {
+ b.HasOne("HyperBooru.HBObject", null)
+ .WithOne()
+ .HasForeignKey("HyperBooru.User", "ObjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("HyperBooru.HBObject", b =>
+ {
+ b.Navigation("Tags");
+ });
+
+ modelBuilder.Entity("HyperBooru.Media", b =>
+ {
+ b.Navigation("OcrData");
+
+ b.Navigation("UploadedFiles");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor
index 3840c6d..e2e4df6 100644
--- a/Pages/TagDefinitions.razor
+++ b/Pages/TagDefinitions.razor
@@ -140,10 +140,10 @@
}
private void PromptTagCreate() {
- string? @namespace = tabContainer.ActivePane?.Title;
- if(@namespace == "Default")
- @namespace = null;
- tagEditDialog.Show(@namespace);
+ string? ns = tabContainer.ActivePane?.Title;
+ if(ns == "Default")
+ ns = null;
+ tagEditDialog.Show(ns);
}
private void TagUpdated(object? sender, EventArgs e) {
diff --git a/Server.csproj b/Server.csproj
index c14aa24..e3ca595 100644
--- a/Server.csproj
+++ b/Server.csproj
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
- <TargetFramework>net7.0</TargetFramework>
+ <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>HyperBooru</AssemblyName>
@@ -9,6 +9,7 @@
<AssemblyVersion>0.1.0.0</AssemblyVersion>
<FileVersion>$(AssemblyVersion)</FileVersion>
<Version>0.1-alpha</Version>
+ <UserSecretsId>2907567f-4640-4581-8f4d-0977952d26bd</UserSecretsId>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -20,17 +21,16 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="13.5.0" />
- <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
+ <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.10.2" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.23" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.23">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
- <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="7.0.10" />
- <PackageReference Include="Mime-Detective" Version="23.6.1" />
- <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
- <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
- <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
+ <PackageReference Include="Mime-Detective" Version="25.8.1" />
+ <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
+ <PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.4" />
+ <PackageReference Include="System.Drawing.Common" Version="8.0.23" />
<PackageReference Include="Tesseract" Version="5.2.0" />
</ItemGroup>
diff --git a/Services/MediaService.cs b/Services/MediaService.cs
index 7e32651..104d0db 100644
--- a/Services/MediaService.cs
+++ b/Services/MediaService.cs
@@ -21,7 +21,9 @@ public interface IMediaService {
string? checksum = null,
DateTime? lastAccessTime = null,
DateTime? lastWriteTime = null,
- DateTime? createTime = null);
+ DateTime? createTime = null,
+ string? path = null,
+ PathType? pathType = null);
public void Delete(Guid media);
public void Delete(Media media);
@@ -38,7 +40,7 @@ public class MediaService : IMediaService {
private IDbContextFactory<HBContext> dbFactory;
private IConfigService config;
- private ContentInspector inspector;
+ private IContentInspector inspector;
public MediaService(IDbContextFactory<HBContext> dbFactory,
IConfigService config) {
@@ -48,8 +50,8 @@ public class MediaService : IMediaService {
ContentInspectorBuilder inspectorBuilder = new() {
Definitions =
- Default.FileTypes.Images.All()
- .Union(Default.FileTypes.Video.All())
+ DefaultDefinitions.FileTypes.Images.All()
+ .Union(DefaultDefinitions.FileTypes.Video.All())
.ToList()
};
@@ -103,7 +105,9 @@ public class MediaService : IMediaService {
string? checksum = null,
DateTime? lastAccessTime = null,
DateTime? lastWriteTime = null,
- DateTime? createTime = null) {
+ DateTime? createTime = null,
+ string? path = null,
+ PathType? pathType = null) {
using var db = dbFactory.CreateDbContext();
using var transaction = db.Database.BeginTransaction();
@@ -142,12 +146,14 @@ public class MediaService : IMediaService {
Checksum = hash,
ChecksumVerified = checksum is not null,
MimeType = mime,
- Width = magickImage.Width,
- Height = magickImage.Height,
+ Width = (int) magickImage.Width,
+ Height = (int) magickImage.Height,
UploadTime = DateTime.UtcNow,
LastAccessTime = lastAccessTime,
LastWriteTime = lastWriteTime,
- CreateTime = createTime
+ CreateTime = createTime,
+ Path = pathType is null ? null : path,
+ PathType = pathType
};
if(media is null) {
@@ -280,8 +286,8 @@ public class MediaService : IMediaService {
var thumbPath = GetPath(m, w, h);
- if(!System.IO.File.Exists(thumbPath)) {
- image.Resize(w, h);
+ if(!File.Exists(thumbPath)) {
+ image.Resize((uint) w, (uint) h);
image.Write(thumbPath);
}
diff --git a/appsettings.json b/appsettings.json
index 90977fc..414e673 100644
--- a/appsettings.json
+++ b/appsettings.json
@@ -6,7 +6,7 @@
}
},
"ConnectionStrings": {
- "DefaultConnection": "Host=127.0.0.1;Database=HyperBooru;Username=hyperbooru;Password=password"
+ "DefaultConnection": "Host=127.0.0.1;Database=hyperbooru;Username=hyperbooru;Password=password"
},
"AllowedHosts": "*"
}