Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Database/BaseDBMigration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ private void CreateCommonTables()
.WithColumn("TelegramID").AsInt64().NotNullable()
.WithColumn("Name").AsString(255).NotNullable()
.WithColumn("Link").AsString(255).NotNullable()
.WithColumn("Status").AsString(255).Nullable();
.WithColumn("Status").AsString(255).Nullable()
.WithColumn("SettingsJson").AsString(int.MaxValue).NotNullable().WithDefaultValue("{}");
}

// Contacts
Expand Down
2 changes: 2 additions & 0 deletions Database/DBInit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public static WebApplicationBuilder CreateBuilderByDBType(string[] args)
new SqliteUserRepository(Config.sqlConnectionString!));
builder.Services.AddSingleton<IUserGetter>(_ =>
new SqliteUserGetter(Config.sqlConnectionString!));
builder.Services.AddSingleton<IUserSettingsRepository>(_ =>
new SqliteUserSettingsRepository(Config.sqlConnectionString!));

builder.Services.AddSingleton<IContactGroupRepository>(_ =>
new SqliteContactGroupRepository(Config.sqlConnectionString!));
Expand Down
20 changes: 20 additions & 0 deletions Database/Interfaces/IUserSettingsRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2024-2025 ZenonEl
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Эта программа является свободным программным обеспечением: вы можете распространять и/или изменять
// её на условиях Стандартной общественной лицензии GNU Affero, опубликованной
// Фондом свободного программного обеспечения, либо версии 3 лицензии, либо
// (по вашему выбору) любой более поздней версии.

using TelegramMediaRelayBot.Domain.Models;

namespace TelegramMediaRelayBot.Database.Interfaces;

public interface IUserSettingsRepository
{
Task<UserSettings> GetSettingsAsync(int userId);
Task<bool> SaveSettingsAsync(int userId, UserSettings settings);
}
32 changes: 32 additions & 0 deletions Database/Migrations/AddSettingsJsonColumn.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2024-2025 ZenonEl
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Эта программа является свободным программным обеспечением: вы можете распространять и/или изменять
// её на условиях Стандартной общественной лицензии GNU Affero, опубликованной
// Фондом свободного программного обеспечения, либо версии 3 лицензии, либо
// (по вашему выбору) любой более поздней версии.

using FluentMigrator;

namespace TelegramMediaRelayBot.Database.Migrations;

[Migration(20260328)]
public class AddSettingsJsonColumn : Migration
{
public override void Up()
{
if (!Schema.Table("Users").Column("SettingsJson").Exists())
{
Alter.Table("Users")
.AddColumn("SettingsJson").AsString(int.MaxValue).NotNullable().WithDefaultValue("{}");
}
}

public override void Down()
{
Delete.Column("SettingsJson").FromTable("Users");
}
}
57 changes: 57 additions & 0 deletions Database/Repositories/SqLite/UserSettingsRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2024-2025 ZenonEl
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Эта программа является свободным программным обеспечением: вы можете распространять и/или изменять
// её на условиях Стандартной общественной лицензии GNU Affero, опубликованной
// Фондом свободного программного обеспечения, либо версии 3 лицензии, либо
// (по вашему выбору) любой более поздней версии.

using Dapper;
using Microsoft.Data.Sqlite;
using TelegramMediaRelayBot.Database.Interfaces;
using TelegramMediaRelayBot.Domain.Models;

namespace TelegramMediaRelayBot.Database.Repositories.Sqlite;

public class SqliteUserSettingsRepository(string connectionString) : IUserSettingsRepository
{
private readonly string _connectionString = connectionString;

public async Task<UserSettings> GetSettingsAsync(int userId)
{
const string query = "SELECT SettingsJson FROM Users WHERE ID = @userId";

try
{
using var connection = new SqliteConnection(_connectionString);
var json = await connection.ExecuteScalarAsync<string>(query, new { userId });
return UserSettings.FromJson(json ?? "{}");
}
catch (Exception ex)
{
Log.Error(ex, "Failed to get settings for user {UserId}", userId);
return new UserSettings();
}
}

public async Task<bool> SaveSettingsAsync(int userId, UserSettings settings)
{
const string query = "UPDATE Users SET SettingsJson = @json WHERE ID = @userId";

try
{
var json = settings.ToJson();
using var connection = new SqliteConnection(_connectionString);
var affected = await connection.ExecuteAsync(query, new { json, userId });
return affected > 0;
}
catch (Exception ex)
{
Log.Error(ex, "Failed to save settings for user {UserId}", userId);
return false;
}
}
}
60 changes: 60 additions & 0 deletions Domain/Models/UserSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (C) 2024-2025 ZenonEl
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Эта программа является свободным программным обеспечением: вы можете распространять и/или изменять
// её на условиях Стандартной общественной лицензии GNU Affero, опубликованной
// Фондом свободного программного обеспечения, либо версии 3 лицензии, либо
// (по вашему выбору) любой более поздней версии.

using System.Text.Json;
using System.Text.Json.Serialization;

namespace TelegramMediaRelayBot.Domain.Models;

public sealed class UserSettings
{
public DistributionSettings Distribution { get; set; } = new();
public PrivacyUserSettings Privacy { get; set; } = new();

private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};

public string ToJson() => JsonSerializer.Serialize(this, JsonOptions);

public static UserSettings FromJson(string json)
{
if (string.IsNullOrWhiteSpace(json)) return new();
try { return JsonSerializer.Deserialize<UserSettings>(json, JsonOptions) ?? new(); }
catch { return new(); }
}
}

public sealed class DistributionSettings
{
public string DefaultAction { get; set; } = "send_only_to_me";
public string DefaultActionCondition { get; set; } = "";
public int AutoSendDelaySeconds { get; set; } = 30;
public List<int> TargetGroupIds { get; set; } = [];
public List<int> TargetContactIds { get; set; } = [];
}

public sealed class PrivacyUserSettings
{
public bool InboxEnabled { get; set; } = false;
public bool AllowContentForwarding { get; set; } = true;
public string WhoCanFindMe { get; set; } = "everyone";
public SiteFilterSettings SiteFilter { get; set; } = new();
}

public sealed class SiteFilterSettings
{
public bool Enabled { get; set; } = false;
public string FilterType { get; set; } = "none";
public List<string> BlockedDomains { get; set; } = [];
}
Loading