Content warning

This commit is contained in:
2023-07-06 22:01:09 +01:00
parent 13f788a311
commit 13980b454f
8 changed files with 168 additions and 3 deletions

View File

@ -15,4 +15,7 @@ public class PatchEvent
[JsonProperty("tags")]
public string[] Tags { get; init; } = Array.Empty<string>();
[JsonProperty("content_warning")]
public string? ContentWarning { get; init; }
}

View File

@ -71,7 +71,7 @@ public class NostrController : Controller
var pubkey = GetPubKey();
if (string.IsNullOrEmpty(pubkey)) return Unauthorized();
await _streamManager.PatchEvent(pubkey, req.Title, req.Summary, req.Image, req.Tags);
await _streamManager.PatchEvent(pubkey, req.Title, req.Summary, req.Image, req.Tags, req.ContentWarning);
return Accepted();
}

View File

@ -17,5 +17,8 @@ public class UserConfiguration : IEntityTypeConfiguration<User>
builder.Property(a => a.Version)
.IsRowVersion();
builder.Property(a => a.Tags);
builder.Property(a => a.ContentWarning);
}
}

View File

@ -39,6 +39,11 @@ public class User
/// </summary>
public string? Tags { get; set; }
/// <summary>
/// Any content warning tag (NIP-36)
/// </summary>
public string? ContentWarning { get; set; }
/// <summary>
/// Concurrency token
/// </summary>

View File

@ -0,0 +1,116 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using NostrStreamer.Database;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NostrStreamer.Migrations
{
[DbContext(typeof(StreamerContext))]
[Migration("20230706204906_ContentWarning")]
partial class ContentWarning
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("NostrStreamer.Database.Payment", b =>
{
b.Property<string>("PaymentHash")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric(20,0)");
b.Property<DateTime>("Created")
.HasColumnType("timestamp with time zone");
b.Property<string>("Invoice")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPaid")
.HasColumnType("boolean");
b.Property<string>("PubKey")
.IsRequired()
.HasColumnType("text");
b.HasKey("PaymentHash");
b.HasIndex("PubKey");
b.ToTable("Payments");
});
modelBuilder.Entity("NostrStreamer.Database.User", b =>
{
b.Property<string>("PubKey")
.HasColumnType("text");
b.Property<long>("Balance")
.HasColumnType("bigint");
b.Property<string>("ContentWarning")
.HasColumnType("text");
b.Property<string>("Event")
.HasColumnType("text");
b.Property<string>("Image")
.HasColumnType("text");
b.Property<string>("StreamKey")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Summary")
.HasColumnType("text");
b.Property<string>("Tags")
.HasColumnType("text");
b.Property<string>("Title")
.HasColumnType("text");
b.Property<uint>("Version")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("PubKey");
b.ToTable("Users");
});
modelBuilder.Entity("NostrStreamer.Database.Payment", b =>
{
b.HasOne("NostrStreamer.Database.User", "User")
.WithMany("Payments")
.HasForeignKey("PubKey")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("NostrStreamer.Database.User", b =>
{
b.Navigation("Payments");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NostrStreamer.Migrations
{
/// <inheritdoc />
public partial class ContentWarning : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ContentWarning",
table: "Users",
type: "text",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ContentWarning",
table: "Users");
}
}
}

View File

@ -59,6 +59,9 @@ namespace NostrStreamer.Migrations
b.Property<long>("Balance")
.HasColumnType("bigint");
b.Property<string>("ContentWarning")
.HasColumnType("text");
b.Property<string>("Event")
.HasColumnType("text");

View File

@ -82,7 +82,7 @@ public class StreamManager
}
}
public async Task PatchEvent(string pubkey, string? title, string? summary, string? image, string[]? tags)
public async Task PatchEvent(string pubkey, string? title, string? summary, string? image, string[]? tags, string? contentWarning)
{
var user = await _db.Users.SingleOrDefaultAsync(a => a.PubKey == pubkey);
if (user == default) throw new Exception("User not found");
@ -91,6 +91,7 @@ public class StreamManager
user.Summary = summary;
user.Image = image;
user.Tags = tags != null ? string.Join(",", tags) : null;
user.ContentWarning = contentWarning;
var ev = CreateStreamEvent(user);
user.Event = JsonConvert.SerializeObject(ev, NostrSerializer.Settings);
@ -151,7 +152,8 @@ public class StreamManager
new("streaming", GetStreamUrl(user)),
new("image", user.Image ?? ""),
new("status", status),
new("p", user.PubKey, "", "host")
new("p", user.PubKey, "", "host"),
new("relays", _config.Relays),
};
if (status == "live")
@ -162,6 +164,11 @@ public class StreamManager
new("current_participants",
(viewers.HasValue ? viewers.ToString() : null) ??
existingEvent?.Tags?.FindFirstTagValue("current_participants") ?? "0"));
if (!string.IsNullOrEmpty(user.ContentWarning))
{
tags.Add(new("content-warning", user.ContentWarning));
}
}
foreach (var tag in !string.IsNullOrEmpty(user.Tags) ?