feat: initial working version of service refs NOISSUE
This commit is contained in:
parent
2bf3258081
commit
d04b453e6f
@ -1,4 +0,0 @@
|
||||
FROM mcr.microsoft.com/dotnet/runtime:9.0
|
||||
COPY ./song_of_the_day/bin/Release/net9.0/ /app
|
||||
WORKDIR /app
|
||||
CMD ["song_of_the_day"]
|
@ -4,8 +4,8 @@
|
||||
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
||||
<clear />
|
||||
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="gitea-projects" value="https://git.disi.dev/api/packages/Projects/nuget/index.json" />
|
||||
<!--add key="gitea-projects" value="https://git.disi.dev/api/packages/Projects/nuget/index.json" />
|
||||
<add key="gitea-homelab" value="https://git.disi.dev/api/packages/Homelab/nuget/index.json" />
|
||||
<add key="gitea-artifacts" value="https://git.disi.dev/api/packages/Artifacts/nuget/index.json" />
|
||||
<add key="gitea-artifacts" value="https://git.disi.dev/api/packages/Artifacts/nuget/index.json" /-->
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
75
song_of_the_day/Config/AppConfiguration.cs
Normal file
75
song_of_the_day/Config/AppConfiguration.cs
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
public class AppConfiguration
|
||||
{
|
||||
public static AppConfiguration Instance = new AppConfiguration();
|
||||
|
||||
private AppConfiguration()
|
||||
{
|
||||
this.SignalAPIEndpointUri = Environment.GetEnvironmentVariable("SIGNAL_API_URI") ?? "http://192.168.1.108";
|
||||
this.SignalAPIEndpointPort = Environment.GetEnvironmentVariable("SIGNAL_API_PORT") ?? "8719";
|
||||
this.HostPhoneNumber = Environment.GetEnvironmentVariable("HOST_PHONE") ?? "+4367762751895";
|
||||
this.DatabaseUri = Environment.GetEnvironmentVariable("DB_URI") ?? "192.168.1.108";
|
||||
this.DatabasePort = Environment.GetEnvironmentVariable("DB_PORT") ?? "5477";
|
||||
this.DatabaseName = Environment.GetEnvironmentVariable("DB_NAME") ?? "sotd";
|
||||
this.DatabaseUser = Environment.GetEnvironmentVariable("DB_USER") ?? "sotd";
|
||||
this.DatabasePW = Environment.GetEnvironmentVariable("DB_PASS") ?? "SotdP0stgresP4ss";
|
||||
this.SignalGroupId = Environment.GetEnvironmentVariable("SIGNAL_GROUP_ID") ?? "group.Wmk1UTVQTnh0Sjd6a0xiOGhnTnMzZlNkc2p2Q3c0SXJiQkU2eDlNU0hyTT0=";
|
||||
this.WebUIBaseURL = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "https://sotd.disi.dev/";
|
||||
this.UseBotTag = bool.Parse(Environment.GetEnvironmentVariable("USE_BOT_TAG") ?? "true");
|
||||
}
|
||||
|
||||
public string SignalAPIEndpointUri
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string SignalAPIEndpointPort
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string DatabaseUri
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string DatabasePort
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string DatabaseName
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string DatabaseUser
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string DatabasePW
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string SignalGroupId
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string HostPhoneNumber
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string WebUIBaseURL
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public bool UseBotTag
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using sotd.Pages;
|
||||
|
||||
public class DataContext : DbContext
|
||||
{
|
||||
public static DataContext Instance;
|
||||
public static DataContext Instance
|
||||
{
|
||||
get { return new DataContext(); }
|
||||
}
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<Song> Songs { get; set; }
|
||||
public DbSet<SongSuggestion> SongSuggestions { get; set; }
|
||||
public DbSet<User>? Users { get; set; }
|
||||
public DbSet<Song>? Songs { get; set; }
|
||||
public DbSet<SongSuggestion>? SongSuggestions { get; set; }
|
||||
public DbSet<SuggestionHelper>? SuggestionHelpers { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder.UseNpgsql(@"Host=192.168.1.108:5477;Username=sotd;Password=SotdP0stgresP4ss;Database=sotd");
|
||||
=> optionsBuilder.UseNpgsql($"Host={AppConfiguration.Instance.DatabaseUri}:{AppConfiguration.Instance.DatabasePort};"
|
||||
+ $"Username={AppConfiguration.Instance.DatabaseUser};Password={AppConfiguration.Instance.DatabasePW};"
|
||||
+ $"Database={AppConfiguration.Instance.DatabaseName}");
|
||||
}
|
127
song_of_the_day/Data/Migrations/20250413192634_AdditionalFields.Designer.cs
generated
Normal file
127
song_of_the_day/Data/Migrations/20250413192634_AdditionalFields.Designer.cs
generated
Normal file
@ -0,0 +1,127 @@
|
||||
// <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;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20250413192634_AdditionalFields")]
|
||||
partial class AdditionalFields
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Song", b =>
|
||||
{
|
||||
b.Property<int>("SongId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SongId"));
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("SongId");
|
||||
|
||||
b.ToTable("Songs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("SongId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SongId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("SongSuggestions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("UserId"));
|
||||
|
||||
b.Property<bool>("IsIntroduced")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.HasOne("Song", "Song")
|
||||
.WithMany()
|
||||
.HasForeignKey("SongId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Song");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AdditionalFields : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsIntroduced",
|
||||
table: "Users",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "UserName",
|
||||
table: "Users",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsIntroduced",
|
||||
table: "Users");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UserName",
|
||||
table: "Users");
|
||||
}
|
||||
}
|
||||
}
|
127
song_of_the_day/Data/Migrations/20250414161136_Update user properties.Designer.cs
generated
Normal file
127
song_of_the_day/Data/Migrations/20250414161136_Update user properties.Designer.cs
generated
Normal file
@ -0,0 +1,127 @@
|
||||
// <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;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20250414161136_Update user properties")]
|
||||
partial class Updateuserproperties
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Song", b =>
|
||||
{
|
||||
b.Property<int>("SongId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SongId"));
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("SongId");
|
||||
|
||||
b.ToTable("Songs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("SongId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SongId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("SongSuggestions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("UserId"));
|
||||
|
||||
b.Property<bool>("IsIntroduced")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NickName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalMemberId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.HasOne("Song", "Song")
|
||||
.WithMany()
|
||||
.HasForeignKey("SongId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Song");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Updateuserproperties : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "UserName",
|
||||
table: "Users",
|
||||
newName: "SignalMemberId");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "SignalId",
|
||||
table: "Users",
|
||||
newName: "NickName");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "SignalMemberId",
|
||||
table: "Users",
|
||||
newName: "UserName");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "NickName",
|
||||
table: "Users",
|
||||
newName: "SignalId");
|
||||
}
|
||||
}
|
||||
}
|
127
song_of_the_day/Data/Migrations/20250414181019_Add SuggestionHelper entity.Designer.cs
generated
Normal file
127
song_of_the_day/Data/Migrations/20250414181019_Add SuggestionHelper entity.Designer.cs
generated
Normal file
@ -0,0 +1,127 @@
|
||||
// <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;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20250414181019_Add SuggestionHelper entity")]
|
||||
partial class AddSuggestionHelperentity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Song", b =>
|
||||
{
|
||||
b.Property<int>("SongId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SongId"));
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("SongId");
|
||||
|
||||
b.ToTable("Songs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("SongId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SongId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("SongSuggestions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("UserId"));
|
||||
|
||||
b.Property<bool>("IsIntroduced")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NickName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalMemberId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.HasOne("Song", "Song")
|
||||
.WithMany()
|
||||
.HasForeignKey("SongId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Song");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddSuggestionHelperentity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
148
song_of_the_day/Data/Migrations/20250414181911_Now really add SuggestionHelper entity.Designer.cs
generated
Normal file
148
song_of_the_day/Data/Migrations/20250414181911_Now really add SuggestionHelper entity.Designer.cs
generated
Normal file
@ -0,0 +1,148 @@
|
||||
// <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;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20250414181911_Now really add SuggestionHelper entity")]
|
||||
partial class NowreallyaddSuggestionHelperentity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Song", b =>
|
||||
{
|
||||
b.Property<int>("SongId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SongId"));
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("SongId");
|
||||
|
||||
b.ToTable("Songs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("SongId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SongId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("SongSuggestions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SuggestionHelper", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SuggestionHelpers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("UserId"));
|
||||
|
||||
b.Property<bool>("IsIntroduced")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("NickName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalMemberId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SongSuggestion", b =>
|
||||
{
|
||||
b.HasOne("Song", "Song")
|
||||
.WithMany()
|
||||
.HasForeignKey("SongId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Song");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace song_of_the_day.DataMigrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class NowreallyaddSuggestionHelperentity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SuggestionHelpers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Title = table.Column<string>(type: "text", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SuggestionHelpers", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "SuggestionHelpers");
|
||||
}
|
||||
}
|
||||
}
|
@ -72,6 +72,27 @@ namespace song_of_the_day.DataMigrations
|
||||
b.ToTable("SongSuggestions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SuggestionHelper", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SuggestionHelpers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("User", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
@ -80,11 +101,18 @@ namespace song_of_the_day.DataMigrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("UserId"));
|
||||
|
||||
b.Property<bool>("IsIntroduced")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalId")
|
||||
b.Property<string>("NickName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("SignalMemberId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
|
@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
public class Song
|
||||
{
|
||||
public int SongId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Artist { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Artist { get; set; }
|
||||
public string? Url { get; set; }
|
||||
}
|
@ -4,7 +4,7 @@ public class SongSuggestion
|
||||
{
|
||||
|
||||
public int Id { get; set; }
|
||||
public User User { get; set; }
|
||||
public Song Song { get; set; }
|
||||
public User? User { get; set; }
|
||||
public Song? Song { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
}
|
9
song_of_the_day/Data/SuggestionHelper.cs
Normal file
9
song_of_the_day/Data/SuggestionHelper.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class SuggestionHelper
|
||||
{
|
||||
|
||||
public int Id { get; set; }
|
||||
public string? Title { get; set; }
|
||||
public string? Description { get; set; }
|
||||
}
|
@ -3,6 +3,8 @@ using Microsoft.EntityFrameworkCore;
|
||||
public class User
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public string SignalId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? SignalMemberId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? NickName { get; set; }
|
||||
public bool IsIntroduced { get; set; }
|
||||
}
|
15
song_of_the_day/Dockerfile
Normal file
15
song_of_the_day/Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
WORKDIR /App
|
||||
|
||||
# Copy everything
|
||||
COPY . ./
|
||||
# Restore as distinct layers
|
||||
RUN dotnet restore
|
||||
# Build and publish a release
|
||||
RUN dotnet publish -o out
|
||||
|
||||
# Build runtime image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0
|
||||
WORKDIR /App
|
||||
COPY --from=build /App/out .
|
||||
ENTRYPOINT ["dotnet", "song_of_the_day.dll"]
|
@ -1,12 +1,17 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using song_of_the_day;
|
||||
|
||||
public class SignalIntegration
|
||||
{
|
||||
public static SignalIntegration Instance;
|
||||
public static SignalIntegration? Instance;
|
||||
|
||||
public SignalIntegration(string uri, int port, string phoneNumber)
|
||||
{
|
||||
var http = new HttpClient() {
|
||||
BaseAddress = new Uri("http://" + uri + ":" + port)
|
||||
var http = new HttpClient()
|
||||
{
|
||||
BaseAddress = new Uri(uri + ":" + port)
|
||||
};
|
||||
apiClient = new song_of_the_day.swaggerClient(http);
|
||||
apiClient.BaseUrl = "";
|
||||
@ -17,17 +22,103 @@ public class SignalIntegration
|
||||
|
||||
private string phoneNumber;
|
||||
|
||||
public async Task ListGroups()
|
||||
public async Task ListGroupsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("listing groups");
|
||||
try {
|
||||
ICollection<song_of_the_day.GroupEntry> groupEntries = await apiClient.GroupsAllAsync(this.phoneNumber);
|
||||
Console.WriteLine($"{groupEntries.Count} groups");
|
||||
foreach (var group in groupEntries)
|
||||
{
|
||||
Console.WriteLine($"{group.Name} {group.Id}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception (ListGroupsAsync): " + ex.Message);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Console.WriteLine("Exception: " + ex.Message);
|
||||
}
|
||||
|
||||
Console.WriteLine("listing groups done");
|
||||
public async Task SendMessageToGroupAsync(string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
SendMessageV2 data = new SendMessageV2();
|
||||
data.Recipients = new List<string>();
|
||||
data.Recipients.Add(AppConfiguration.Instance.SignalGroupId);
|
||||
data.Message = message;
|
||||
data.Text_mode = SendMessageV2Text_mode.Styled;
|
||||
data.Number = AppConfiguration.Instance.HostPhoneNumber;
|
||||
var response = await apiClient.Send2Async(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception (SendMessageToGroupAsync): " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendMessageToUserAsync(string message, string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
SendMessageV2 data = new SendMessageV2();
|
||||
data.Recipients = new List<string>();
|
||||
data.Recipients.Add(userId);
|
||||
data.Message = (AppConfiguration.Instance.UseBotTag ? "**[Proggy]**\n" : "") + message;
|
||||
data.Text_mode = SendMessageV2Text_mode.Styled;
|
||||
data.Number = AppConfiguration.Instance.HostPhoneNumber;
|
||||
var response = await apiClient.Send2Async(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception (SendMessageToUserAsync): " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task IntroduceUserAsync(User user)
|
||||
{
|
||||
await this.SendMessageToUserAsync("Hi, my name is Proggy and I am your friendly neighborhood *Song of the Day* bot!", user.SignalMemberId);
|
||||
await this.SendMessageToUserAsync("You are receiving this message because you have been invited to a *Song of the Day* community group.", user.SignalMemberId);
|
||||
await this.SendMessageToUserAsync("In that community group I will pick a person at random each day at 8 AM and encourage them to share a song with the rest of the community.", user.SignalMemberId);
|
||||
if (AppConfiguration.Instance.UseBotTag)
|
||||
{
|
||||
await this.SendMessageToUserAsync("You can always see which messages are sent by me rather than the community host by the **[Proggy]** tag at the beginning of the message", user.SignalMemberId);
|
||||
}
|
||||
await this.SendMessageToUserAsync($"Not right now, but eventually you will be able to see more details about your community at {AppConfiguration.Instance.WebUIBaseURL}.", user.SignalMemberId);
|
||||
await this.SendMessageToUserAsync($"""You can navigate to {AppConfiguration.Instance.WebUIBaseURL + (AppConfiguration.Instance.WebUIBaseURL.EndsWith("/") ? "" : "/")}User/{user.UserId} to set your preferred display name for me to use.""", user.SignalMemberId);
|
||||
await this.SendMessageToUserAsync($"Now have fun and enjoy being a part of this community!", user.SignalMemberId);
|
||||
}
|
||||
|
||||
public async Task<ICollection<string>> GetMemberListAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await apiClient.Groups2Async(AppConfiguration.Instance.HostPhoneNumber, AppConfiguration.Instance.SignalGroupId);
|
||||
return response.Members;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception (GetMemberListAsync): " + ex.Message);
|
||||
}
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
public async Task<ListContactsResponse> GetContactAsync(string memberId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var allIdentities = await apiClient.ContactsAllAsync(AppConfiguration.Instance.HostPhoneNumber);
|
||||
var identityCandidates = allIdentities.Where(u => u.Number == memberId || u.Uuid == memberId);
|
||||
var identity = identityCandidates.SingleOrDefault();
|
||||
if (identity == null)
|
||||
{
|
||||
throw new Exception($"Could not determine identity for memberId '{memberId}'!");
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception (GetContactAsync): " + ex.Message);
|
||||
return new ListContactsResponse();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
@page
|
||||
@model IndexModel
|
||||
@{
|
||||
ViewData["Title"] = "Home page";
|
||||
ViewData["Title"] = "Song of the Day";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
|
@ -1,8 +0,0 @@
|
||||
@page
|
||||
@model PrivacyModel
|
||||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
|
||||
<p>Use this page to detail your site's privacy policy.</p>
|
@ -1,19 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace sotd.Pages;
|
||||
|
||||
public class PrivacyModel : PageModel
|
||||
{
|
||||
private readonly ILogger<PrivacyModel> _logger;
|
||||
|
||||
public PrivacyModel(ILogger<PrivacyModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" asp-area="" asp-page="/Index">sotd</a>
|
||||
<a class="navbar-brand" asp-area="" asp-page="/Index">Song of the Day</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
@ -24,7 +24,7 @@
|
||||
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
|
||||
<a class="nav-link text-dark" asp-area="" asp-page="/SuggestionHelpers">Suggestion Helpers</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
<footer class="border-top footer text-muted">
|
||||
<div class="container">
|
||||
© 2025 - sotd - <a asp-area="" asp-page="/Privacy">Privacy</a>
|
||||
© 2025 - Song of the Day
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
32
song_of_the_day/Pages/SuggestionHelpers.cshtml
Normal file
32
song_of_the_day/Pages/SuggestionHelpers.cshtml
Normal file
@ -0,0 +1,32 @@
|
||||
@page
|
||||
@model SuggestionHelpersModel
|
||||
@{
|
||||
ViewData["Title"] = "Suggestion Helpers";
|
||||
}
|
||||
|
||||
<div class="text-left">
|
||||
<table>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
@foreach (var helper in @Model.SuggestionHelpers)
|
||||
{
|
||||
var title = helper.Title; var description = helper.Description;
|
||||
<tr>
|
||||
<td>@title</td>
|
||||
<td>@description</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<hr />
|
||||
<form method="post">
|
||||
<label asp-for="NewSuggestionTitle">Title</label>
|
||||
<input asp-for="NewSuggestionTitle" />
|
||||
<br />
|
||||
<label asp-for="NewSuggestionDescription">Description</label>
|
||||
<input asp-for="NewSuggestionDescription" />
|
||||
<br />
|
||||
<input type="submit" title="Submit" />
|
||||
</form>
|
||||
</div>
|
52
song_of_the_day/Pages/SuggestionHelpers.cshtml.cs
Normal file
52
song_of_the_day/Pages/SuggestionHelpers.cshtml.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace sotd.Pages;
|
||||
|
||||
public class SuggestionHelpersModel : PageModel
|
||||
{
|
||||
private readonly ILogger<SuggestionHelpersModel> _logger;
|
||||
|
||||
public SuggestionHelpersModel(ILogger<SuggestionHelpersModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
this.NewSuggestionDescription = "";
|
||||
this.NewSuggestionTitle = "";
|
||||
this.SuggestionHelpers = new List<SuggestionHelper>();
|
||||
}
|
||||
|
||||
[BindProperty]
|
||||
public ICollection<SuggestionHelper> SuggestionHelpers { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string NewSuggestionTitle { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string NewSuggestionDescription { get; set; }
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
using (var dci = DataContext.Instance)
|
||||
{
|
||||
this.SuggestionHelpers = dci.SuggestionHelpers.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPost()
|
||||
{
|
||||
using (var dci = DataContext.Instance)
|
||||
{
|
||||
var newHelper = new SuggestionHelper()
|
||||
{
|
||||
Title = this.NewSuggestionTitle,
|
||||
Description = this.NewSuggestionDescription
|
||||
};
|
||||
dci.SuggestionHelpers.Add(newHelper);
|
||||
dci.SaveChanges();
|
||||
this.SuggestionHelpers = dci.SuggestionHelpers.ToList();
|
||||
}
|
||||
this.NewSuggestionDescription = "";
|
||||
this.NewSuggestionTitle = "";
|
||||
}
|
||||
}
|
17
song_of_the_day/Pages/User.cshtml
Normal file
17
song_of_the_day/Pages/User.cshtml
Normal file
@ -0,0 +1,17 @@
|
||||
@page "{userIndex}"
|
||||
@model UserModel
|
||||
@{
|
||||
ViewData["Title"] = "User #" + @Model.userId;
|
||||
}
|
||||
|
||||
<div class="text-left">
|
||||
<form method="post">
|
||||
<label asp-for="UserNickName">Preferred Name</label>
|
||||
<input asp-for="UserNickName" />
|
||||
<br />
|
||||
<label asp-for="UserName">Contact Name</label>
|
||||
<input asp-for="UserName" disabled />
|
||||
<br />
|
||||
<input type="submit" title="Submit" />
|
||||
</form>
|
||||
</div>
|
45
song_of_the_day/Pages/User.cshtml.cs
Normal file
45
song_of_the_day/Pages/User.cshtml.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace sotd.Pages;
|
||||
|
||||
public class UserModel : PageModel
|
||||
{
|
||||
private readonly ILogger<UserModel> _logger;
|
||||
|
||||
public UserModel(ILogger<UserModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
this.UserNickName = "";
|
||||
this.UserName = "";
|
||||
}
|
||||
|
||||
public int userId { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string UserNickName { get; set; }
|
||||
|
||||
public void OnGet(int userIndex)
|
||||
{
|
||||
using (var dci = DataContext.Instance)
|
||||
{
|
||||
var user = dci.Users.Find(userIndex);
|
||||
this.UserName = user.Name;
|
||||
this.UserNickName = user.NickName;
|
||||
this.userId = userIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPost(int userIndex)
|
||||
{
|
||||
using (var dci = DataContext.Instance)
|
||||
{
|
||||
var user = dci.Users.Find(userIndex);
|
||||
user.NickName = this.UserNickName;
|
||||
dci.SaveChanges();
|
||||
this.UserName = user.Name;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,83 @@
|
||||
|
||||
using Scalar.AspNetCore;
|
||||
using Microsoft.AspNetCore.OpenApi;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
DataContext.Instance = new DataContext();
|
||||
var groupId = "group.Wmk1UTVQTnh0Sjd6a0xiOGhnTnMzZlNkc2p2Q3c0SXJiQkU2eDlNU0hyTT0=";
|
||||
SignalIntegration.Instance = new SignalIntegration("192.168.1.108", 8719, "+4367762751895");
|
||||
await SignalIntegration.Instance.ListGroups();
|
||||
SignalIntegration.Instance = new SignalIntegration(AppConfiguration.Instance.SignalAPIEndpointUri,
|
||||
int.Parse(AppConfiguration.Instance.SignalAPIEndpointPort),
|
||||
AppConfiguration.Instance.HostPhoneNumber);
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
var userCheckTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
|
||||
userCheckTimer.OnOccurence += async (s, ea) =>
|
||||
{
|
||||
var memberList = await SignalIntegration.Instance.GetMemberListAsync();
|
||||
var dci = DataContext.Instance;
|
||||
var needsSaving = false;
|
||||
foreach (var memberId in memberList)
|
||||
{
|
||||
var foundUser = dci.Users.Where(u => u.SignalMemberId == memberId).SingleOrDefault();
|
||||
if (foundUser == null)
|
||||
{
|
||||
var newUserContact = await SignalIntegration.Instance.GetContactAsync(memberId);
|
||||
Console.WriteLine("New user:");
|
||||
Console.WriteLine($" Name: {newUserContact.Name}");
|
||||
Console.WriteLine($" MemberId: {memberId}");
|
||||
User newUser = new User()
|
||||
{
|
||||
Name = newUserContact.Name,
|
||||
SignalMemberId = memberId,
|
||||
NickName = string.Empty,
|
||||
IsIntroduced = false
|
||||
};
|
||||
needsSaving = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsSaving)
|
||||
{
|
||||
await dci.SaveChangesAsync();
|
||||
}
|
||||
await dci.DisposeAsync();
|
||||
};
|
||||
userCheckTimer.Start();
|
||||
|
||||
var userIntroTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
|
||||
userIntroTimer.OnOccurence += async (s, ea) =>
|
||||
{
|
||||
var dci = DataContext.Instance;
|
||||
var introUsers = dci.Users.Where(u => !u.IsIntroduced);
|
||||
bool needsSaving = false;
|
||||
foreach (var user in introUsers)
|
||||
{
|
||||
await SignalIntegration.Instance.IntroduceUserAsync(user);
|
||||
user.IsIntroduced = true;
|
||||
needsSaving = true;
|
||||
}
|
||||
|
||||
if (needsSaving)
|
||||
{
|
||||
await dci.SaveChangesAsync();
|
||||
}
|
||||
await dci.DisposeAsync();
|
||||
};
|
||||
userIntroTimer.Start();
|
||||
|
||||
var pickOfTheDayTimer = new CronTimer("0 8 * * *", "Europe/Vienna", includingSeconds: false);
|
||||
pickOfTheDayTimer.OnOccurence += async (s, ea) =>
|
||||
{
|
||||
var dci = DataContext.Instance;
|
||||
var luckyUser = await dci.Users.ElementAtAsync((new Random()).Next(await dci.Users.CountAsync()));
|
||||
var userName = string.IsNullOrEmpty(luckyUser.NickName) ? luckyUser.Name : luckyUser.NickName;
|
||||
SignalIntegration.Instance.SendMessageToGroupAsync($"Today's chosen person to share a song is: **{userName}**");
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"Congratulations, you have been chosen to share a song today!", luckyUser.SignalMemberId);
|
||||
var suggestion = await dci.SuggestionHelpers.ElementAtAsync((new Random()).Next(await dci.SuggestionHelpers.CountAsync()));
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"Today's (optional) suggestion helper to help you pick a song is:\n\n**{suggestion.Title}**\n\n*{suggestion.Description}*", luckyUser.SignalMemberId);
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"For now please just share your suggestion with the group - in the future I might ask you to share directly with me or via the website to help me keep track of past suggestions!", luckyUser.SignalMemberId);
|
||||
};
|
||||
pickOfTheDayTimer.Start();
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddOpenApi();
|
||||
@ -35,6 +104,3 @@ app.MapRazorPages()
|
||||
.WithStaticAssets();
|
||||
|
||||
app.Run();
|
||||
|
||||
//Console.WriteLine("Size: " + DataContext.Instance.Songs.Count());
|
||||
//await SignalIntegration.Instance.ListGroups();
|
@ -16,6 +16,7 @@
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
<PackageReference Include="NSwag.ApiDescription.Client" Version="13.0.5" />
|
||||
<PackageReference Include="Scalar.AspNetCore" Version="2.1.*" />
|
||||
<PackageReference Include="CronTimer" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<OpenApiReference Include="swagger.json" SourceUrl="https://bbernhard.github.io/signal-cli-rest-api/src/docs/swagger.json" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user