Compare commits

...

9 Commits
0.2.6 ... main

Author SHA1 Message Date
e9a824c6ef release: version 0.3.2 🚀
Some checks failed
Build Docker image / Create Release (push) Successful in 30s
CI / linter (9.0.X, ubuntu-latest) (push) Failing after 1m28s
CI / tests_linux (9.0.X, ubuntu-latest) (push) Has been skipped
Build Docker image / deploy (push) Successful in 2m48s
SonarQube Scan / SonarQube Trigger (push) Failing after 4m55s
2025-05-25 21:36:50 +02:00
e0f206bc0c fix: exception thrown on LastOrDefault(), refs NOISSUE 2025-05-25 21:36:34 +02:00
183309e1ed release: version 0.3.1 🚀
Some checks failed
Build Docker image / Create Release (push) Successful in 21s
CI / linter (9.0.X, ubuntu-latest) (push) Failing after 1m22s
CI / tests_linux (9.0.X, ubuntu-latest) (push) Has been skipped
Build Docker image / deploy (push) Successful in 3m13s
SonarQube Scan / SonarQube Trigger (push) Failing after 4m54s
2025-05-24 19:20:17 +02:00
a6321324f7 fix: fix build errors, refs NOISSUE 2025-05-24 19:20:12 +02:00
e400249284 release: version 0.3.0 🚀
Some checks failed
Build Docker image / Create Release (push) Successful in 24s
CI / linter (9.0.X, ubuntu-latest) (push) Failing after 1m3s
CI / tests_linux (9.0.X, ubuntu-latest) (push) Has been skipped
Build Docker image / deploy (push) Failing after 1m48s
SonarQube Scan / SonarQube Trigger (push) Failing after 4m56s
2025-05-24 18:56:45 +02:00
73c5e40e1d ci: more CI fixes, refs NOISSUE 2025-05-24 18:56:37 +02:00
f728c88853 ci: improve commit message generation script, refs NOISSUE 2025-05-24 18:51:58 +02:00
5fdd6ec1d0 feat: keep track of user submissions, refs #4 2025-05-24 18:51:58 +02:00
fbb6d1a409 feat: save submission history, refs #7 2025-05-24 18:51:50 +02:00
12 changed files with 554 additions and 34 deletions

View File

@ -46,7 +46,7 @@ create_file() {
} }
get_commit_range() { get_commit_range() {
rm $TEMP_FILE_PATH/messages.txt rm -f $TEMP_FILE_PATH/messages.txt
if [[ $LAST_TAG =~ $PATTERN ]]; then if [[ $LAST_TAG =~ $PATTERN ]]; then
create_file true create_file true
else else
@ -64,16 +64,16 @@ start() {
while read message; do while read message; do
echo $message echo $message
if echo $message | grep -Pq '(feat|style)(\([\w]+\))?!:([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(NOISSUE)))'; then if echo $message | grep -Pq '(feat|style)(\([\w]+\))?!:([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(#[0-9]+)|(NOISSUE)))'; then
increment_type="major" increment_type="major"
echo "a" echo "a"
break break
elif echo $message | grep -Pq '(feat|style)(\([\w]+\))?:([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(NOISSUE)))'; then elif echo $message | grep -Pq '(feat|style)(\([\w]+\))?:([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(#[0-9]+)|(NOISSUE)))'; then
if [ -z "$increment_type" ] || [ "$increment_type" == "patch" ]; then if [ -z "$increment_type" ] || [ "$increment_type" == "patch" ]; then
increment_type="minor" increment_type="minor"
echo "b" echo "b"
fi fi
elif echo $message | grep -Pq '(build|fix|perf|refactor|revert)(\(.+\))?:\s([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(NOISSUE)))'; then elif echo $message | grep -Pq '(build|fix|perf|refactor|revert)(\(.+\))?:\s([a-zA-Z0-9-_!\&\.\%\(\)\=\w\s]+)\s?(,?\s?)((ref(s?):?\s?)(([A-Z0-9]+\-[0-9]+)|(#[0-9]+)|(NOISSUE)))'; then
if [ -z "$increment_type" ]; then if [ -z "$increment_type" ]; then
increment_type="patch" increment_type="patch"
echo "c" echo "c"

View File

@ -5,6 +5,35 @@ Changelog
(unreleased) (unreleased)
------------ ------------
Fix
~~~
- Exception thrown on LastOrDefault(), refs NOISSUE. [Simon
Diesenreiter]
0.3.1 (2025-05-24)
------------------
Fix
~~~
- Fix build errors, refs NOISSUE. [Simon Diesenreiter]
Other
~~~~~
0.3.0 (2025-05-24)
------------------
- Ci: more CI fixes, refs NOISSUE. [Simon Diesenreiter]
- Ci: improve commit message generation script, refs NOISSUE. [Simon
Diesenreiter]
- Feat: keep track of user submissions, refs #4. [Simon Diesenreiter]
- Feat: save submission history, refs #7. [Simon Diesenreiter]
0.2.6 (2025-05-22)
------------------
Fix Fix
~~~ ~~~
- Bugfixes, refs NOISSUE. [Simon Diesenreiter] - Bugfixes, refs NOISSUE. [Simon Diesenreiter]
@ -216,10 +245,6 @@ Other
0.1.9 (2025-04-15) 0.1.9 (2025-04-15)
------------------ ------------------
0.1.8 (2025-04-15)
------------------
Fix Fix
~~~ ~~~
- Additional debug outputs refs NOISSUE. [Simon Diesenreiter] - Additional debug outputs refs NOISSUE. [Simon Diesenreiter]

View File

@ -16,14 +16,15 @@ public class AppConfiguration
this.SignalGroupId = Environment.GetEnvironmentVariable("SIGNAL_GROUP_ID") ?? "group.Wmk1UTVQTnh0Sjd6a0xiOGhnTnMzZlNkc2p2Q3c0SXJiQkU2eDlNU0hyTT0="; this.SignalGroupId = Environment.GetEnvironmentVariable("SIGNAL_GROUP_ID") ?? "group.Wmk1UTVQTnh0Sjd6a0xiOGhnTnMzZlNkc2p2Q3c0SXJiQkU2eDlNU0hyTT0=";
this.WebUIBaseURL = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "https://sotd.disi.dev/"; this.WebUIBaseURL = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "https://sotd.disi.dev/";
this.UseBotTag = bool.Parse(Environment.GetEnvironmentVariable("USE_BOT_TAG") ?? "true"); this.UseBotTag = bool.Parse(Environment.GetEnvironmentVariable("USE_BOT_TAG") ?? "true");
this.AverageDaysBetweenRequests = int.Parse(Environment.GetEnvironmentVariable("AVERAGE_DAYS_BETWEEN_REQUESTS") ?? "2"); this.DaysBetweenRequests = int.Parse(Environment.GetEnvironmentVariable("DAYS_BETWEEN_REQUESTS") ?? "2");
var managersGroupName = Environment.GetEnvironmentVariable("LDAP_ADMINGROUP") ?? "admins"; var managersGroupName = Environment.GetEnvironmentVariable("LDAP_ADMINGROUP") ?? "admins";
var userGroupName = Environment.GetEnvironmentVariable("LDAP_USERGROUP") ?? "everybody"; var userGroupName = Environment.GetEnvironmentVariable("LDAP_USERGROUP") ?? "everybody";
var bindValue = Environment.GetEnvironmentVariable("LDAP_BIND");
this.LDAPConfig = new ConfigurationAD() this.LDAPConfig = new ConfigurationAD()
{ {
Username = Environment.GetEnvironmentVariable("LDAP_BIND") ?? "cn=admin,dc=disi,dc=dev", Username = Environment.GetEnvironmentVariable("LDAP_BIND") ?? "cn=admin,dc=disi,dc=dev",
Password = Environment.GetEnvironmentVariable("LDAP_PASS") ?? "adminPass2022!", Password = Environment.GetEnvironmentVariable("LDAP_PASS") ?? "adminPass2022!",
Port = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("LDAP_BIND")) ? int.Parse(Environment.GetEnvironmentVariable("LDAP_BIND")) : 389, Port = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("LDAP_BIND")) ? int.Parse(bindValue ?? "389") : 389,
LDAPserver = Environment.GetEnvironmentVariable("LDAP_URL") ?? "192.168.1.108", LDAPserver = Environment.GetEnvironmentVariable("LDAP_URL") ?? "192.168.1.108",
LDAPQueryBase = Environment.GetEnvironmentVariable("LDAP_BASE") ?? "dc=disi,dc=dev", LDAPQueryBase = Environment.GetEnvironmentVariable("LDAP_BASE") ?? "dc=disi,dc=dev",
LDAPUserQueryBase = Environment.GetEnvironmentVariable("LDAP_BASE") ?? "ou=people,dc=disi,dc=dev", LDAPUserQueryBase = Environment.GetEnvironmentVariable("LDAP_BASE") ?? "ou=people,dc=disi,dc=dev",
@ -87,7 +88,7 @@ public class AppConfiguration
get; private set; get; private set;
} }
public int AverageDaysBetweenRequests public int DaysBetweenRequests
{ {
get; private set; get; private set;
} }

View File

@ -0,0 +1,145 @@
// <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("20250524160218_additional data for song submissions")]
partial class additionaldataforsongsubmissions
{
/// <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")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Url")
.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<bool>("Submitted")
.HasColumnType("boolean");
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")
.HasColumnType("text");
b.Property<string>("Title")
.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>("AssociationInProgress")
.HasColumnType("boolean");
b.Property<bool>("IsIntroduced")
.HasColumnType("boolean");
b.Property<string>("LdapUserName")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("NickName")
.HasColumnType("text");
b.Property<string>("SignalMemberId")
.HasColumnType("text");
b.HasKey("UserId");
b.ToTable("Users");
});
modelBuilder.Entity("SongSuggestion", b =>
{
b.HasOne("Song", "Song")
.WithMany()
.HasForeignKey("SongId");
b.HasOne("User", "User")
.WithMany()
.HasForeignKey("UserId");
b.Navigation("Song");
b.Navigation("User");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace song_of_the_day.DataMigrations
{
/// <inheritdoc />
public partial class additionaldataforsongsubmissions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Submitted",
table: "SongSuggestions",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Submitted",
table: "SongSuggestions");
}
}
}

View File

@ -0,0 +1,164 @@
// <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("20250524164159_keep track of users oicked for submission")]
partial class keeptrackofusersoickedforsubmission
{
/// <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")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Url")
.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<bool>("HasUsedSuggestion")
.HasColumnType("boolean");
b.Property<int?>("SongId")
.HasColumnType("integer");
b.Property<int>("SuggestionHelperId")
.HasColumnType("integer");
b.Property<bool>("UserHasSubmitted")
.HasColumnType("boolean");
b.Property<int?>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("SongId");
b.HasIndex("SuggestionHelperId");
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")
.HasColumnType("text");
b.Property<string>("Title")
.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>("AssociationInProgress")
.HasColumnType("boolean");
b.Property<bool>("IsIntroduced")
.HasColumnType("boolean");
b.Property<string>("LdapUserName")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("NickName")
.HasColumnType("text");
b.Property<string>("SignalMemberId")
.HasColumnType("text");
b.Property<bool>("WasChosenForSuggestionThisRound")
.HasColumnType("boolean");
b.HasKey("UserId");
b.ToTable("Users");
});
modelBuilder.Entity("SongSuggestion", b =>
{
b.HasOne("Song", "Song")
.WithMany()
.HasForeignKey("SongId");
b.HasOne("SuggestionHelper", "SuggestionHelper")
.WithMany()
.HasForeignKey("SuggestionHelperId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("User", "User")
.WithMany()
.HasForeignKey("UserId");
b.Navigation("Song");
b.Navigation("SuggestionHelper");
b.Navigation("User");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,82 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace song_of_the_day.DataMigrations
{
/// <inheritdoc />
public partial class keeptrackofusersoickedforsubmission : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "Submitted",
table: "SongSuggestions",
newName: "UserHasSubmitted");
migrationBuilder.AddColumn<bool>(
name: "WasChosenForSuggestionThisRound",
table: "Users",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "HasUsedSuggestion",
table: "SongSuggestions",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<int>(
name: "SuggestionHelperId",
table: "SongSuggestions",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_SongSuggestions_SuggestionHelperId",
table: "SongSuggestions",
column: "SuggestionHelperId");
migrationBuilder.AddForeignKey(
name: "FK_SongSuggestions_SuggestionHelpers_SuggestionHelperId",
table: "SongSuggestions",
column: "SuggestionHelperId",
principalTable: "SuggestionHelpers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_SongSuggestions_SuggestionHelpers_SuggestionHelperId",
table: "SongSuggestions");
migrationBuilder.DropIndex(
name: "IX_SongSuggestions_SuggestionHelperId",
table: "SongSuggestions");
migrationBuilder.DropColumn(
name: "WasChosenForSuggestionThisRound",
table: "Users");
migrationBuilder.DropColumn(
name: "HasUsedSuggestion",
table: "SongSuggestions");
migrationBuilder.DropColumn(
name: "SuggestionHelperId",
table: "SongSuggestions");
migrationBuilder.RenameColumn(
name: "UserHasSubmitted",
table: "SongSuggestions",
newName: "Submitted");
}
}
}

View File

@ -54,9 +54,18 @@ namespace song_of_the_day.DataMigrations
b.Property<DateTime>("Date") b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone"); .HasColumnType("timestamp with time zone");
b.Property<bool>("HasUsedSuggestion")
.HasColumnType("boolean");
b.Property<int?>("SongId") b.Property<int?>("SongId")
.HasColumnType("integer"); .HasColumnType("integer");
b.Property<int>("SuggestionHelperId")
.HasColumnType("integer");
b.Property<bool>("UserHasSubmitted")
.HasColumnType("boolean");
b.Property<int?>("UserId") b.Property<int?>("UserId")
.HasColumnType("integer"); .HasColumnType("integer");
@ -64,6 +73,8 @@ namespace song_of_the_day.DataMigrations
b.HasIndex("SongId"); b.HasIndex("SongId");
b.HasIndex("SuggestionHelperId");
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("SongSuggestions"); b.ToTable("SongSuggestions");
@ -114,6 +125,9 @@ namespace song_of_the_day.DataMigrations
b.Property<string>("SignalMemberId") b.Property<string>("SignalMemberId")
.HasColumnType("text"); .HasColumnType("text");
b.Property<bool>("WasChosenForSuggestionThisRound")
.HasColumnType("boolean");
b.HasKey("UserId"); b.HasKey("UserId");
b.ToTable("Users"); b.ToTable("Users");
@ -125,12 +139,20 @@ namespace song_of_the_day.DataMigrations
.WithMany() .WithMany()
.HasForeignKey("SongId"); .HasForeignKey("SongId");
b.HasOne("SuggestionHelper", "SuggestionHelper")
.WithMany()
.HasForeignKey("SuggestionHelperId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("User", "User") b.HasOne("User", "User")
.WithMany() .WithMany()
.HasForeignKey("UserId"); .HasForeignKey("UserId");
b.Navigation("Song"); b.Navigation("Song");
b.Navigation("SuggestionHelper");
b.Navigation("User"); b.Navigation("User");
}); });
#pragma warning restore 612, 618 #pragma warning restore 612, 618

View File

@ -1,3 +1,4 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
public class SongSuggestion public class SongSuggestion
@ -7,4 +8,7 @@ public class SongSuggestion
public User? User { get; set; } public User? User { get; set; }
public Song? Song { get; set; } public Song? Song { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }
public bool UserHasSubmitted { get; set; }
public required SuggestionHelper SuggestionHelper { get; set; }
public bool HasUsedSuggestion { get; set; }
} }

View File

@ -9,4 +9,5 @@ public class User
public bool IsIntroduced { get; set; } public bool IsIntroduced { get; set; }
public bool AssociationInProgress { get; set; } public bool AssociationInProgress { get; set; }
public string? LdapUserName { get; set; } public string? LdapUserName { get; set; }
public bool WasChosenForSuggestionThisRound { get; set; }
} }

View File

@ -18,10 +18,6 @@ LdapIntegration.Instance = new LdapIntegration(AppConfiguration.Instance.LDAPCon
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var rand = new Random();
var num = rand.NextInt64();
var mod = num % AppConfiguration.Instance.AverageDaysBetweenRequests;
Console.WriteLine("Setting up user check timer"); Console.WriteLine("Setting up user check timer");
var userCheckTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false); var userCheckTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
userCheckTimer.OnOccurence += async (s, ea) => userCheckTimer.OnOccurence += async (s, ea) =>
@ -31,7 +27,7 @@ userCheckTimer.OnOccurence += async (s, ea) =>
var needsSaving = false; var needsSaving = false;
foreach (var memberId in memberList) foreach (var memberId in memberList)
{ {
var foundUser = dci.Users.Where(u => u.SignalMemberId == memberId).SingleOrDefault(); var foundUser = dci.Users?.Where(u => u.SignalMemberId == memberId).SingleOrDefault();
if (foundUser == null) if (foundUser == null)
{ {
var newUserContact = await SignalIntegration.Instance.GetContactAsync(memberId); var newUserContact = await SignalIntegration.Instance.GetContactAsync(memberId);
@ -46,8 +42,9 @@ userCheckTimer.OnOccurence += async (s, ea) =>
IsIntroduced = false, IsIntroduced = false,
LdapUserName = string.Empty, LdapUserName = string.Empty,
AssociationInProgress = false, AssociationInProgress = false,
WasChosenForSuggestionThisRound = false,
}; };
dci.Users.Add(newUser); dci.Users?.Add(newUser);
needsSaving = true; needsSaving = true;
} }
} }
@ -65,7 +62,13 @@ var userIntroTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeco
userIntroTimer.OnOccurence += async (s, ea) => userIntroTimer.OnOccurence += async (s, ea) =>
{ {
var dci = DataContext.Instance; var dci = DataContext.Instance;
var introUsers = dci.Users.Where(u => !u.IsIntroduced); var introUsers = dci.Users?.Where(u => !u.IsIntroduced);
if (introUsers == null)
{
await dci.DisposeAsync();
return;
}
bool needsSaving = false; bool needsSaving = false;
foreach (var user in introUsers) foreach (var user in introUsers)
{ {
@ -87,34 +90,72 @@ Console.WriteLine("Setting up pick of the day timer");
var pickOfTheDayTimer = new CronTimer("0 8 * * *", "Europe/Vienna", includingSeconds: false); var pickOfTheDayTimer = new CronTimer("0 8 * * *", "Europe/Vienna", includingSeconds: false);
pickOfTheDayTimer.OnOccurence += async (s, ea) => pickOfTheDayTimer.OnOccurence += async (s, ea) =>
{ {
var rand = new Random(); var dci = DataContext.Instance;
var num = rand.NextInt64();
var mod = num % AppConfiguration.Instance.AverageDaysBetweenRequests;
if (mod > 0) var lastSong = dci.SongSuggestions?.OrderBy(s => s.Id).LastOrDefault();
if (lastSong != null && lastSong.Date >= DateTime.Today.Subtract(TimeSpan.FromDays(AppConfiguration.Instance.DaysBetweenRequests)))
{ {
Console.WriteLine("Skipping pick of the day today!"); Console.WriteLine("Skipping pick of the day today!");
await dci.DisposeAsync();
return; return;
} }
var dci = DataContext.Instance; if (dci.Users == null || dci.SuggestionHelpers == null || dci.SongSuggestions == null)
var luckyUser = await dci.Users.ElementAtAsync((new Random()).Next(await dci.Users.CountAsync())); {
Console.WriteLine("Unable to properly initialize DB context!");
await dci.DisposeAsync();
return;
}
var potentialUsers = dci.Users.Where(u => !u.WasChosenForSuggestionThisRound);
if (!potentialUsers.Any())
{
Console.WriteLine("Resetting suggestion count on users before resuming");
await dci.Users.ForEachAsync(u => u.WasChosenForSuggestionThisRound = false);
await dci.SaveChangesAsync();
potentialUsers = dci.Users.Where(u => !u.WasChosenForSuggestionThisRound);
}
Console.WriteLine("Today's pool of pickable users is: " + string.Join(", ", potentialUsers.Select(u => u.Name)));
var luckyUser = potentialUsers.ElementAt((new Random()).Next(potentialUsers.Count()));
if (luckyUser == null)
{
Console.WriteLine("Unable to determine today's lucky user!");
await dci.DisposeAsync();
return;
}
var userName = string.IsNullOrEmpty(luckyUser.NickName) ? luckyUser.Name : luckyUser.NickName; var userName = string.IsNullOrEmpty(luckyUser.NickName) ? luckyUser.Name : luckyUser.NickName;
var suggestion = await dci.SuggestionHelpers.ElementAtAsync((new Random()).Next(await dci.SuggestionHelpers.CountAsync())); var suggestion = await dci.SuggestionHelpers.ElementAtAsync((new Random()).Next(await dci.SuggestionHelpers.CountAsync()));
await SignalIntegration.Instance.SendMessageToGroupAsync($"Today's chosen person to share a song is: **{userName}**"); var newSongSuggestion = new SongSuggestion()
await SignalIntegration.Instance.SendMessageToGroupAsync($"Today's (optional) suggestion helper to help you pick a song is:\n\n**{suggestion.Title}**\n\n*{suggestion.Description}*"); {
await SignalIntegration.Instance.SendMessageToUserAsync($"Congratulations, you have been chosen to share a song today!", luckyUser.SignalMemberId); User = luckyUser,
await 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); SuggestionHelper = suggestion,
await 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); UserHasSubmitted = false,
HasUsedSuggestion = false,
Date = DateTime.Today
};
if (luckyUser.SignalMemberId is string signalId)
{
await dci.SongSuggestions.AddAsync(newSongSuggestion);
await dci.SaveChangesAsync();
await SignalIntegration.Instance.SendMessageToGroupAsync($"Today's chosen person to share a song is: **{userName}**");
await SignalIntegration.Instance.SendMessageToGroupAsync($"Today's (optional) suggestion helper to help you pick a song is:\n\n**{suggestion.Title}**\n\n*{suggestion.Description}*");
await SignalIntegration.Instance.SendMessageToUserAsync($"Congratulations, you have been chosen to share a song today!", signalId);
await SignalIntegration.Instance.SendMessageToUserAsync($"Today's (optional) suggestion helper to help you pick a song is:\n\n**{suggestion.Title}**\n\n*{suggestion.Description}*", signalId);
await 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);
}
await dci.DisposeAsync();
}; };
pickOfTheDayTimer.Start(); pickOfTheDayTimer.Start();
var startUserAssociationProcess = async (User userToAssociate) => var startUserAssociationProcess = async (User userToAssociate) =>
{ {
await SignalIntegration.Instance.SendMessageToUserAsync($"Hi, I see you are not associated with any website user yet.", userToAssociate.SignalMemberId); if (userToAssociate.SignalMemberId is string signalId)
await SignalIntegration.Instance.SendMessageToUserAsync($"If you haven't yet, please navigate to https://users.disi.dev to create a new account.", userToAssociate.SignalMemberId); {
await SignalIntegration.Instance.SendMessageToUserAsync($"Once you have done so, go to https://sotd.disi.dev, login, navigate to \"Unclaimed Phone Numbers\" and click on the \"Claim\" button to start the claim process.", userToAssociate.SignalMemberId); await SignalIntegration.Instance.SendMessageToUserAsync($"Hi, I see you are not associated with any website user yet.", signalId);
await SignalIntegration.Instance.SendMessageToUserAsync($"With a future update you will be required to submit songs via your user account - at that point you will be skipped during the selection process if you have not yet claimed your phone number!", userToAssociate.SignalMemberId); await SignalIntegration.Instance.SendMessageToUserAsync($"If you haven't yet, please navigate to https://users.disi.dev to create a new account.", signalId);
await SignalIntegration.Instance.SendMessageToUserAsync($"Once you have done so, go to https://sotd.disi.dev, login, navigate to \"Unclaimed Phone Numbers\" and click on the \"Claim\" button to start the claim process.", signalId);
await SignalIntegration.Instance.SendMessageToUserAsync($"With a future update you will be required to submit songs via your user account - at that point you will be skipped during the selection process if you have not yet claimed your phone number!", signalId);
}
}; };
Console.WriteLine("Setting up LdapAssociation timer"); Console.WriteLine("Setting up LdapAssociation timer");
@ -122,6 +163,12 @@ var ldapAssociationTimer = new CronTimer("*/10 * * * *", "Europe/Vienna", includ
ldapAssociationTimer.OnOccurence += async (s, ea) => ldapAssociationTimer.OnOccurence += async (s, ea) =>
{ {
var dci = DataContext.Instance; var dci = DataContext.Instance;
if (dci.Users == null)
{
Console.WriteLine("Unable to properly initialize DB context!");
await dci.DisposeAsync();
return;
}
var nonAssociatedUsers = dci.Users.Where(u => string.IsNullOrEmpty(u.LdapUserName) && !u.AssociationInProgress); var nonAssociatedUsers = dci.Users.Where(u => string.IsNullOrEmpty(u.LdapUserName) && !u.AssociationInProgress);
var needsSaving = false; var needsSaving = false;
foreach (var user in nonAssociatedUsers) foreach (var user in nonAssociatedUsers)

View File

@ -1 +1 @@
0.2.6 0.3.2