Compare commits
3 Commits
21cb5c9453
...
3429c8f8dc
| Author | SHA1 | Date | |
|---|---|---|---|
| 3429c8f8dc | |||
| 538bf07454 | |||
| 525725a7e5 |
@@ -4,10 +4,12 @@ namespace HermesSocketServer.Models
|
|||||||
{
|
{
|
||||||
public class Channel
|
public class Channel
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public required string Id { get; set; }
|
||||||
public User User { get; set; }
|
public required User User { get; set; }
|
||||||
public ChatterStore Chatters { get; set; }
|
public required ChatterStore Chatters { get; set; }
|
||||||
public PolicyStore Policies { get; set; }
|
public required PolicyStore Policies { get; set; }
|
||||||
public TTSFilterStore Filters { get; set; }
|
public required TTSFilterStore Filters { get; set; }
|
||||||
|
public required ActionStore Actions { get; set; }
|
||||||
|
public required RedemptionStore Redemptions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ namespace HermesSocketServer.Models
|
|||||||
public class ChatterVoice
|
public class ChatterVoice
|
||||||
{
|
{
|
||||||
public long ChatterId { get; set; }
|
public long ChatterId { get; set; }
|
||||||
public string UserId { get; set; }
|
public required string UserId { get; set; }
|
||||||
public string VoiceId { get; set; }
|
public required string VoiceId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,10 @@ namespace HermesSocketServer.Models
|
|||||||
{
|
{
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public required string Id { get; set; }
|
||||||
public string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
public string Email { get; set; }
|
public required string Email { get; set; }
|
||||||
public string Role { get; set; }
|
public required string Role { get; set; }
|
||||||
public string DefaultVoice { get; set; }
|
public required string DefaultVoice { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace HermesSocketServer.Models
|
|
||||||
{
|
|
||||||
public class Voice
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -51,12 +51,15 @@ namespace HermesSocketServer.Quests
|
|||||||
});
|
});
|
||||||
|
|
||||||
string sql2 = "SELECT id FROM \"Quest\" WHERE type = @type AND start = @start";
|
string sql2 = "SELECT id FROM \"Quest\" WHERE type = @type AND start = @start";
|
||||||
int? questId = (int?)await _database.ExecuteScalar(sql, c =>
|
int? questId = (int?)await _database.ExecuteScalar(sql2, c =>
|
||||||
{
|
{
|
||||||
c.Parameters.AddWithValue("@type", temp.Type);
|
c.Parameters.AddWithValue("@type", temp.Type);
|
||||||
c.Parameters.AddWithValue("@start", temp.StartTime);
|
c.Parameters.AddWithValue("@start", temp.StartTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (questId == null)
|
||||||
|
return;
|
||||||
|
|
||||||
var quest = new DailyQuest((short)questId.Value, task, date);
|
var quest = new DailyQuest((short)questId.Value, task, date);
|
||||||
_quests.Add(quest.Id, quest);
|
_quests.Add(quest.Id, quest);
|
||||||
}
|
}
|
||||||
@@ -88,12 +91,15 @@ namespace HermesSocketServer.Quests
|
|||||||
});
|
});
|
||||||
|
|
||||||
string sql2 = "SELECT id FROM \"Quest\" WHERE type = @type AND start = @start";
|
string sql2 = "SELECT id FROM \"Quest\" WHERE type = @type AND start = @start";
|
||||||
int? questId = (int?)await _database.ExecuteScalar(sql, c =>
|
int? questId = (int?)await _database.ExecuteScalar(sql2, c =>
|
||||||
{
|
{
|
||||||
c.Parameters.AddWithValue("@type", temp.Type);
|
c.Parameters.AddWithValue("@type", temp.Type);
|
||||||
c.Parameters.AddWithValue("@start", temp.StartTime);
|
c.Parameters.AddWithValue("@start", temp.StartTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (questId == null)
|
||||||
|
return;
|
||||||
|
|
||||||
var quest = new WeeklyQuest((short)questId.Value, task, date);
|
var quest = new WeeklyQuest((short)questId.Value, task, date);
|
||||||
_quests.Add(quest.Id, quest);
|
_quests.Add(quest.Id, quest);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var id = Guid.NewGuid();
|
var id = Guid.NewGuid();
|
||||||
string groupId = data["groupId"].ToString()!;
|
string groupId = data["groupId"].ToString()!;
|
||||||
@@ -36,9 +36,9 @@ namespace HermesSocketServer.Requests
|
|||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_logger.Information($"Added policy to channel [policy id: {id}][group id: {groupId}][path: {path}][count: {count}][span: {span}][channel: {channel.Id}]");
|
_logger.Information($"Added policy to channel [policy id: {id}][group id: {groupId}][path: {path}][count: {count}][span: {span}][channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(policy);
|
return Task.FromResult(RequestResult.Successful(policy));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
53
Requests/CreateRedeemableAction.cs
Normal file
53
Requests/CreateRedeemableAction.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class CreateRedeemableAction : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "create_redeemable_action";
|
||||||
|
public string[] RequiredKeys => ["name", "data", "type"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public CreateRedeemableAction(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
string name = data["name"].ToString()!;
|
||||||
|
string d = data["data"].ToString()!;
|
||||||
|
string type = data["type"].ToString()!;
|
||||||
|
IDictionary<string, string> dict = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dict = JsonSerializer.Deserialize<IDictionary<string, string>>(d)!;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, $"Failed to parse data on redeemable action while creating action [name: {name}][type: {type}][data: {d}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Could not parse the data on this action."));
|
||||||
|
}
|
||||||
|
|
||||||
|
var action = new RedeemableAction()
|
||||||
|
{
|
||||||
|
UserId = channel.Id,
|
||||||
|
Name = name,
|
||||||
|
Data = dict,
|
||||||
|
Type = type,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result = channel.Actions.Set(name, action);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Added redeemable action to channel [name: {name}][type: {type}][channel: {channel.Id}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(action));
|
||||||
|
}
|
||||||
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Requests/CreateRedemption.cs
Normal file
47
Requests/CreateRedemption.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class CreateRedemption : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "create_redemption";
|
||||||
|
public string[] RequiredKeys => ["redemption", "action", "order"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public CreateRedemption(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
var id = Guid.NewGuid();
|
||||||
|
string redemptionId = data["redemption"].ToString()!;
|
||||||
|
string actionName = data["action"].ToString()!;
|
||||||
|
if (channel.Actions.Get(actionName) == null)
|
||||||
|
return Task.FromResult(RequestResult.Failed("Action Name must be an existing action."));
|
||||||
|
if (!int.TryParse(data["order"].ToString()!, out var order))
|
||||||
|
return Task.FromResult(RequestResult.Failed("Order must be an integer."));
|
||||||
|
|
||||||
|
var redemption = new Redemption()
|
||||||
|
{
|
||||||
|
Id = id.ToString(),
|
||||||
|
UserId = channel.Id,
|
||||||
|
RedemptionId = redemptionId,
|
||||||
|
ActionName = actionName,
|
||||||
|
Order = order,
|
||||||
|
State = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result = channel.Redemptions.Set(id.ToString(), redemption);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Added redemption to channel [id: {id}][redemption id: {redemptionId}][action: {actionName}][order: {order}][channel: {channel.Id}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(redemption));
|
||||||
|
}
|
||||||
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var id = Guid.NewGuid();
|
var id = Guid.NewGuid();
|
||||||
string search = data["search"].ToString()!;
|
string search = data["search"].ToString()!;
|
||||||
@@ -33,9 +33,9 @@ namespace HermesSocketServer.Requests
|
|||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_logger.Information($"Added filter to channel [filter id: {id}][search: {search}][replace: {replace}][channel: {channel.Id}]");
|
_logger.Information($"Added filter to channel [filter id: {id}][search: {search}][replace: {replace}][channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(filter);
|
return Task.FromResult(RequestResult.Successful(filter));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using HermesSocketServer.Store;
|
using HermesSocketServer.Store;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
@@ -8,7 +9,7 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "create_tts_voice";
|
public string Name => "create_tts_voice";
|
||||||
public string[] RequiredKeys => ["voice"];
|
public string[] RequiredKeys => ["voice"];
|
||||||
private IStore<string, Voice> _voices;
|
private IStore<string, TTSVoice> _voices;
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
private Random _random;
|
private Random _random;
|
||||||
|
|
||||||
@@ -19,12 +20,12 @@ namespace HermesSocketServer.Requests
|
|||||||
_random = new Random();
|
_random = new Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string voice = data["voice"].ToString()!;
|
string voice = data["voice"].ToString()!;
|
||||||
string id = RandomString(25);
|
string id = RandomString(25);
|
||||||
|
|
||||||
var result = _voices.Set(id, new Voice()
|
var result = _voices.Set(id, new TTSVoice()
|
||||||
{
|
{
|
||||||
Id = id,
|
Id = id,
|
||||||
Name = voice
|
Name = voice
|
||||||
@@ -32,9 +33,9 @@ namespace HermesSocketServer.Requests
|
|||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
_logger.Information($"Added a new voice [voice: {voice}][voice id: {id}]");
|
_logger.Information($"Added a new voice [voice: {voice}][voice id: {id}]");
|
||||||
return RequestResult.Successful(id);
|
return Task.FromResult(RequestResult.Successful(id));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
|
|
||||||
private string RandomString(int length)
|
private string RandomString(int length)
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string policyId = data["id"].ToString()!;
|
string policyId = data["id"].ToString()!;
|
||||||
var policy = channel.Policies.Get(policyId);
|
var policy = channel.Policies.Get(policyId);
|
||||||
if (policy != null) {
|
if (policy != null) {
|
||||||
channel.Policies.Remove(policyId);
|
channel.Policies.Remove(policyId);
|
||||||
_logger.Information($"Deleted a policy by id [policy id: {data["id"]}]");
|
_logger.Information($"Deleted a policy by id [policy id: {data["id"]}]");
|
||||||
return RequestResult.Successful(policy.GroupId + "/" + policy.Path);
|
return Task.FromResult(RequestResult.Successful(policy.GroupId + "/" + policy.Path));
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Warning("Failed to find policy by id ");
|
_logger.Warning($"Failed to find policy by id [id: {policyId}]");
|
||||||
return RequestResult.Failed("Cannot find the policy by id.");
|
return Task.FromResult(RequestResult.Failed("Policy ID does not exist."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
32
Requests/DeleteRedeemableAction.cs
Normal file
32
Requests/DeleteRedeemableAction.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class DeleteRedeemableAction : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "delete_redeemable_action";
|
||||||
|
public string[] RequiredKeys => ["name"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public DeleteRedeemableAction(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
string name = data["name"].ToString()!;
|
||||||
|
var result = channel.Actions.Remove(name);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Deleted a redeemable action by name [name: {name}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warning($"Action name does not exist [id: {name}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Action name does not exist."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Requests/DeleteRedemption.cs
Normal file
32
Requests/DeleteRedemption.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class DeleteRedemption : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "delete_redemption";
|
||||||
|
public string[] RequiredKeys => ["id"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public DeleteRedemption(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
string id = data["id"].ToString()!;
|
||||||
|
var result = channel.Redemptions.Remove(id);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Deleted a redemption by id [id: {id}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warning($"Redemption ID does not exist [id: {id}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Redemption ID does not exist."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,13 +14,19 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string filterId = data["id"].ToString()!;
|
string filterId = data["id"].ToString()!;
|
||||||
channel.Filters.Remove(filterId);
|
var result = channel.Filters.Remove(filterId);
|
||||||
|
|
||||||
_logger.Information($"Deleted a TTS filter by id [tts filter id: {filterId}]");
|
if (result)
|
||||||
return RequestResult.Successful(null);
|
{
|
||||||
|
_logger.Information($"Deleted a TTS filter by id [tts filter id: {filterId}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warning($"Filter ID does not exist [id: {filterId}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Filter ID does not exist."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using HermesSocketServer.Store;
|
using HermesSocketServer.Store;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
@@ -8,7 +9,7 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "delete_tts_voice";
|
public string Name => "delete_tts_voice";
|
||||||
public string[] RequiredKeys => ["voice"];
|
public string[] RequiredKeys => ["voice"];
|
||||||
private IStore<string, Voice> _voices;
|
private IStore<string, TTSVoice> _voices;
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
public DeleteTTSVoice(VoiceStore voices, ILogger logger)
|
public DeleteTTSVoice(VoiceStore voices, ILogger logger)
|
||||||
@@ -17,12 +18,19 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string voiceId = data["voice"].ToString()!;
|
string voiceId = data["voice"].ToString()!;
|
||||||
_voices.Remove(voiceId);
|
var result = _voices.Remove(voiceId);
|
||||||
_logger.Information($"Deleted a voice by id [voice id: {voiceId}]");
|
|
||||||
return RequestResult.Successful(null);
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Deleted a voice by id [voice id: {voiceId}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warning($"Voice ID does not exist [id: {voiceId}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Voice ID does not exist."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,11 +14,11 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
IEnumerable<long> ids = channel.Chatters.Get().Values.Select(c => c.ChatterId);
|
IEnumerable<long> ids = channel.Chatters.Get().Values.Select(c => c.ChatterId);
|
||||||
_logger.Information($"Fetched all chatters for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all chatters for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(ids, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(ids, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,13 +19,13 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var user = _users.Get(channel.Id);
|
var user = _users.Get(channel.Id);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
return RequestResult.Failed("Unable to find user data.", notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Failed("Unable to find user data.", notifyClientsOnAccount: false));
|
||||||
|
|
||||||
return RequestResult.Successful(user.DefaultVoice ?? _configuration.Tts.DefaultTtsVoice, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(user.DefaultVoice ?? _configuration.Tts.DefaultTtsVoice, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,12 +14,12 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var results = channel.Policies.Get().Values;
|
var results = channel.Policies.Get().Values;
|
||||||
|
|
||||||
_logger.Information($"Fetched policies for channel [policy size: {results.Count}][channel: {channel.Id}]");
|
_logger.Information($"Fetched policies for channel [policy size: {results.Count}][channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(results, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(results, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using HermesSocketLibrary.db;
|
|
||||||
using HermesSocketLibrary.Requests.Messages;
|
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
@@ -10,31 +7,18 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "get_redeemable_actions";
|
public string Name => "get_redeemable_actions";
|
||||||
public string[] RequiredKeys => [];
|
public string[] RequiredKeys => [];
|
||||||
private readonly JsonSerializerOptions _options;
|
|
||||||
private readonly Database _database;
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public GetRedeemableActions(JsonSerializerOptions options, Database database, ILogger logger)
|
public GetRedeemableActions(ILogger logger)
|
||||||
{
|
{
|
||||||
_options = options;
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var temp = new Dictionary<string, object>() { { "user", channel.Id } };
|
var redemptions = channel.Actions.Get().Values;
|
||||||
|
|
||||||
var redemptions = new List<RedeemableAction>();
|
|
||||||
string sql = $"SELECT name, type, data FROM \"Action\" WHERE \"userId\" = @user";
|
|
||||||
await _database.Execute(sql, temp, (r) => redemptions.Add(new RedeemableAction()
|
|
||||||
{
|
|
||||||
Name = r.GetString(0),
|
|
||||||
Type = r.GetString(1),
|
|
||||||
Data = JsonSerializer.Deserialize<IDictionary<string, string>>(r.GetString(2), _options)!
|
|
||||||
}));
|
|
||||||
_logger.Information($"Fetched all chatters' selected tts voice for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all chatters' selected tts voice for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(redemptions, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(redemptions, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketLibrary.Requests.Messages;
|
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
@@ -18,11 +17,11 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var temp = new Dictionary<string, object>() { { "user", channel.Id } };
|
var temp = new Dictionary<string, object>() { { "user", channel.Id } };
|
||||||
|
|
||||||
var redemptions = new List<Redemption>();
|
var redemptions = channel.Redemptions.Get().Values; /* new List<Redemption>();
|
||||||
string sql = $"SELECT id, \"redemptionId\", \"actionName\", \"order\", state FROM \"Redemption\" WHERE \"userId\" = @user";
|
string sql = $"SELECT id, \"redemptionId\", \"actionName\", \"order\", state FROM \"Redemption\" WHERE \"userId\" = @user";
|
||||||
await _database.Execute(sql, temp, (r) => redemptions.Add(new Redemption()
|
await _database.Execute(sql, temp, (r) => redemptions.Add(new Redemption()
|
||||||
{
|
{
|
||||||
@@ -31,9 +30,9 @@ namespace HermesSocketServer.Requests
|
|||||||
ActionName = r.GetString(2),
|
ActionName = r.GetString(2),
|
||||||
Order = r.GetInt32(3),
|
Order = r.GetInt32(3),
|
||||||
State = r.GetBoolean(4)
|
State = r.GetBoolean(4)
|
||||||
}));
|
}));*/
|
||||||
_logger.Information($"Fetched all redemptions for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all redemptions for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(redemptions, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(redemptions, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,11 +14,11 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var results = channel.Chatters.Get().ToDictionary(p => p.Key, p => p.Value.VoiceId);
|
var results = channel.Chatters.Get().ToDictionary(p => p.Key, p => p.Value.VoiceId);
|
||||||
_logger.Information($"Fetched all chatters' selected tts voice for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all chatters' selected tts voice for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(results, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(results, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,16 +18,16 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
IEnumerable<VoiceDetails> voices = _voices.Get().Select(v => new VoiceDetails()
|
IEnumerable<TTSVoice> voices = _voices.Get().Select(v => new TTSVoice()
|
||||||
{
|
{
|
||||||
Id = v.Value.Id,
|
Id = v.Value.Id,
|
||||||
Name = v.Value.Name
|
Name = v.Value.Name,
|
||||||
});
|
});
|
||||||
|
|
||||||
_logger.Information($"Fetched all TTS voices for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all TTS voices for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(voices, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(voices, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using HermesSocketLibrary.Requests.Messages;
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using HermesSocketServer.Services;
|
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
namespace HermesSocketServer.Requests
|
namespace HermesSocketServer.Requests
|
||||||
@@ -9,21 +8,19 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "get_tts_word_filters";
|
public string Name => "get_tts_word_filters";
|
||||||
public string[] RequiredKeys => [];
|
public string[] RequiredKeys => [];
|
||||||
private ChannelManager _channels;
|
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
public GetTTSWordFilters(ChannelManager channels, ILogger logger)
|
public GetTTSWordFilters(ILogger logger)
|
||||||
{
|
{
|
||||||
_channels = channels;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
IEnumerable<TTSWordFilter> filters = channel.Filters.Get().Values;
|
IEnumerable<TTSWordFilter> filters = channel.Filters.Get().Values;
|
||||||
|
|
||||||
_logger.Information($"Fetched all word filters for channel [channel: {channel.Id}]");
|
_logger.Information($"Fetched all word filters for channel [channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(filters, notifyClientsOnAccount: false);
|
return Task.FromResult(RequestResult.Successful(filters, notifyClientsOnAccount: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,6 @@ namespace HermesSocketServer.Requests
|
|||||||
string Name { get; }
|
string Name { get; }
|
||||||
string[] RequiredKeys { get; }
|
string[] RequiredKeys { get; }
|
||||||
|
|
||||||
Task<RequestResult> Grant(Channel channel, IDictionary<string, object>? data);
|
Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
if (message == null || message.Type == null)
|
if (message == null || message.Type == null)
|
||||||
{
|
{
|
||||||
_logger.Debug($"Request type does not exist [id: {message.RequestId}][nounce: {message.Nounce}]");
|
_logger.Debug($"Request type does not exist [id: {message?.RequestId ?? "null"}][nounce: {message?.Nounce ?? "null"}]");
|
||||||
return RequestResult.Failed("Request type does not exist.");
|
return RequestResult.Failed("Request type does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ namespace HermesSocketServer.Requests
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await request.Grant(channel, message.Data);
|
return await request.Grant(channel, message.Data ?? new Dictionary<string, object>());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string user = data["user"].ToString()!;
|
string user = data["user"].ToString()!;
|
||||||
string voice = data["voice"].ToString()!;
|
string voice = data["voice"].ToString()!;
|
||||||
|
|
||||||
var success = _users.Modify(user, (user) => user.DefaultVoice = voice);
|
var success = _users.Modify(user, (user) => user.DefaultVoice = voice);
|
||||||
if (!success)
|
if (!success)
|
||||||
return RequestResult.Failed("Unable to find user data.");
|
return Task.FromResult(RequestResult.Failed("Unable to find user data."));
|
||||||
|
|
||||||
_logger.Information($"Updated default TTS voice for channel [channel: {channel.Id}][voice: {voice}]");
|
_logger.Information($"Updated default TTS voice for channel [channel: {channel.Id}][voice: {voice}]");
|
||||||
return RequestResult.Successful(null);
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using HermesSocketServer.Services;
|
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
namespace HermesSocketServer.Requests
|
namespace HermesSocketServer.Requests
|
||||||
@@ -8,16 +7,14 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "update_policy";
|
public string Name => "update_policy";
|
||||||
public string[] RequiredKeys => ["id", "groupId", "path", "count", "span"];
|
public string[] RequiredKeys => ["id", "groupId", "path", "count", "span"];
|
||||||
private ChannelManager _channels;
|
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
public UpdatePolicy(ChannelManager channels, ILogger logger)
|
public UpdatePolicy(ILogger logger)
|
||||||
{
|
{
|
||||||
_channels = channels;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var id = Guid.Parse(data["id"].ToString()!);
|
var id = Guid.Parse(data["id"].ToString()!);
|
||||||
string groupId = data["groupId"].ToString()!;
|
string groupId = data["groupId"].ToString()!;
|
||||||
@@ -39,9 +36,9 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
var policy = channel.Policies.Get(id.ToString());
|
var policy = channel.Policies.Get(id.ToString());
|
||||||
_logger.Information($"Updated policy to channel [policy id: {id}][group id: {groupId}][path: {path}][count: {count}][span: {span}][channel: {channel.Id}]");
|
_logger.Information($"Updated policy to channel [policy id: {id}][group id: {groupId}][path: {path}][count: {count}][span: {span}][channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(policy);
|
return Task.FromResult(RequestResult.Successful(policy));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
59
Requests/UpdateRedeemableAction.cs
Normal file
59
Requests/UpdateRedeemableAction.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class UpdateRedeemableAction : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "update_redeemable_action";
|
||||||
|
public string[] RequiredKeys => ["name", "data", "type"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public UpdateRedeemableAction(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
string name = data["name"].ToString()!;
|
||||||
|
string d = data["data"].ToString()!;
|
||||||
|
string type = data["type"].ToString()!;
|
||||||
|
IDictionary<string, string> dict = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dict = JsonSerializer.Deserialize<IDictionary<string, string>>(d)!;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, $"Failed to parse data on redeemable action while updating action [name: {name}][type: {type}][data: {d}]");
|
||||||
|
return Task.FromResult(RequestResult.Failed("Could not parse the data on this action."));
|
||||||
|
}
|
||||||
|
|
||||||
|
var action = new RedeemableAction()
|
||||||
|
{
|
||||||
|
UserId = channel.Id,
|
||||||
|
Name = name,
|
||||||
|
Data = dict,
|
||||||
|
Type = type,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result = channel.Actions.Modify(name, action =>
|
||||||
|
{
|
||||||
|
action.Type = type;
|
||||||
|
action.Data = dict;
|
||||||
|
});
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Added redeemable action to channel [name: {name}][type: {type}][channel: {channel.Id}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(action));
|
||||||
|
}
|
||||||
|
if (channel.Actions.Get(name) == null)
|
||||||
|
return Task.FromResult(RequestResult.Failed("Action does not exist."));
|
||||||
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
Requests/UpdateRedemption.cs
Normal file
62
Requests/UpdateRedemption.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Models;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Requests
|
||||||
|
{
|
||||||
|
public class UpdateRedemption : IRequest
|
||||||
|
{
|
||||||
|
public string Name => "update_redemption";
|
||||||
|
public string[] RequiredKeys => ["id", "redemption", "action", "order"];
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public UpdateRedemption(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
|
{
|
||||||
|
var id = data["id"].ToString()!;
|
||||||
|
string redemptionId = data["redemption"].ToString()!;
|
||||||
|
string actionName = data["action"].ToString()!;
|
||||||
|
if (channel.Actions.Get(actionName) == null)
|
||||||
|
return Task.FromResult(RequestResult.Failed("Action Name must be an existing action."));
|
||||||
|
if (!int.TryParse(data["order"].ToString()!, out var order))
|
||||||
|
return Task.FromResult(RequestResult.Failed("Order must be an integer."));
|
||||||
|
bool state = data["state"].ToString()?.ToLower() == "true";
|
||||||
|
|
||||||
|
var redemption = new Redemption()
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
UserId = channel.Id,
|
||||||
|
RedemptionId = redemptionId,
|
||||||
|
ActionName = actionName,
|
||||||
|
Order = order,
|
||||||
|
State = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result = channel.Redemptions.Modify(id.ToString(), r =>
|
||||||
|
{
|
||||||
|
if (r.UserId != channel.Id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
r.RedemptionId = redemptionId;
|
||||||
|
r.ActionName = actionName;
|
||||||
|
r.Order = order;
|
||||||
|
r.State = state;
|
||||||
|
});
|
||||||
|
|
||||||
|
var r = channel.Redemptions.Get(id);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
_logger.Information($"Added redemption to channel [id: {id}][redemption id: {redemptionId}][action: {actionName}][order: {order}][channel: {channel.Id}]");
|
||||||
|
return Task.FromResult(RequestResult.Successful(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == null || r.UserId != channel.Id)
|
||||||
|
return Task.FromResult(RequestResult.Failed("Redemption does not exist."));
|
||||||
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,16 +9,14 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "update_tts_filter";
|
public string Name => "update_tts_filter";
|
||||||
public string[] RequiredKeys => ["id", "search", "replace"];
|
public string[] RequiredKeys => ["id", "search", "replace"];
|
||||||
private ChannelManager _channels;
|
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
public UpdateTTSFilter(ChannelManager channels, ILogger logger)
|
public UpdateTTSFilter(ILogger logger)
|
||||||
{
|
{
|
||||||
_channels = channels;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
var id = data["id"].ToString()!;
|
var id = data["id"].ToString()!;
|
||||||
string search = data["search"].ToString()!;
|
string search = data["search"].ToString()!;
|
||||||
@@ -37,9 +35,9 @@ namespace HermesSocketServer.Requests
|
|||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_logger.Information($"Updated filter to channel [filter id: {id}][search: {search}][replace: {replace}][channel: {channel.Id}]");
|
_logger.Information($"Updated filter to channel [filter id: {id}][search: {search}][replace: {replace}][channel: {channel.Id}]");
|
||||||
return RequestResult.Successful(filter);
|
return Task.FromResult(RequestResult.Successful(filter));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,6 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "update_tts_user";
|
public string Name => "update_tts_user";
|
||||||
public string[] RequiredKeys => ["chatter", "voice"];
|
public string[] RequiredKeys => ["chatter", "voice"];
|
||||||
private ChannelManager _channels;
|
|
||||||
private Database _database;
|
private Database _database;
|
||||||
private readonly ServerConfiguration _configuration;
|
private readonly ServerConfiguration _configuration;
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
using HermesSocketServer.Store;
|
using HermesSocketServer.Store;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
@@ -8,7 +9,7 @@ namespace HermesSocketServer.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "update_tts_voice";
|
public string Name => "update_tts_voice";
|
||||||
public string[] RequiredKeys => ["voice", "voiceId"];
|
public string[] RequiredKeys => ["voice", "voiceId"];
|
||||||
private IStore<string, Voice> _voices;
|
private IStore<string, TTSVoice> _voices;
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
||||||
public UpdateTTSVoice(VoiceStore voices, ILogger logger)
|
public UpdateTTSVoice(VoiceStore voices, ILogger logger)
|
||||||
@@ -17,12 +18,12 @@ namespace HermesSocketServer.Requests
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
string voiceName = data["voice"].ToString()!;
|
string voiceName = data["voice"].ToString()!;
|
||||||
string voiceId = data["voiceid"].ToString()!;
|
string voiceId = data["voiceid"].ToString()!;
|
||||||
|
|
||||||
var result = _voices.Set(voiceId, new Voice()
|
var result = _voices.Set(voiceId, new TTSVoice()
|
||||||
{
|
{
|
||||||
Id = voiceId,
|
Id = voiceId,
|
||||||
Name = voiceName
|
Name = voiceName
|
||||||
@@ -30,9 +31,9 @@ namespace HermesSocketServer.Requests
|
|||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_logger.Information($"Updated voice's [voice id: {voiceId}] name [new name: {voiceName}]");
|
_logger.Information($"Updated voice's [voice id: {voiceId}] name [new name: {voiceName}]");
|
||||||
return RequestResult.Successful(null);
|
return Task.FromResult(RequestResult.Successful(null));
|
||||||
}
|
}
|
||||||
return RequestResult.Failed("Something went wrong when updating the cache.");
|
return Task.FromResult(RequestResult.Failed("Something went wrong when updating the cache."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace HermesSocketServer.Requests
|
|||||||
|
|
||||||
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
public async Task<RequestResult> Grant(Channel channel, IDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
data["voice"] = data["voice"].ToString();
|
data["voice"] = data["voice"].ToString()!;
|
||||||
data["state"] = data["state"].ToString() == "True";
|
data["state"] = data["state"].ToString() == "True";
|
||||||
data["user"] = channel.Id;
|
data["user"] = channel.Id;
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
namespace HermesSocketServer
|
namespace HermesSocketServer
|
||||||
{
|
{
|
||||||
public class ServerConfiguration
|
public class ServerConfiguration
|
||||||
{
|
{
|
||||||
public string Environment;
|
public required string Environment;
|
||||||
public WebsocketServerConfiguration WebsocketServer;
|
public required WebsocketServerConfiguration WebsocketServer;
|
||||||
public DatabaseConfiguration Database;
|
public required DatabaseConfiguration Database;
|
||||||
public TTSConfiguration Tts;
|
public required TTSConfiguration Tts;
|
||||||
public string AdminPassword;
|
public string? AdminPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WebsocketServerConfiguration
|
public class WebsocketServerConfiguration
|
||||||
{
|
{
|
||||||
public string Host;
|
public required string Host;
|
||||||
public string Port;
|
public required string Port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DatabaseConfiguration
|
public class DatabaseConfiguration
|
||||||
{
|
{
|
||||||
public string ConnectionString;
|
public required string ConnectionString;
|
||||||
public int SaveDelayInSeconds;
|
public int SaveDelayInSeconds;
|
||||||
|
public required IDictionary<string, DatabaseTable> Tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TTSConfiguration
|
public class TTSConfiguration
|
||||||
{
|
{
|
||||||
public long OwnerId;
|
public long OwnerId;
|
||||||
public string DefaultTtsVoice;
|
public required string DefaultTtsVoice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,41 +9,51 @@ namespace HermesSocketServer.Services
|
|||||||
{
|
{
|
||||||
private readonly UserStore _users;
|
private readonly UserStore _users;
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
|
private readonly ServerConfiguration _configuration;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly IDictionary<string, Channel> _channels;
|
private readonly IDictionary<string, Channel> _channels;
|
||||||
private readonly object _lock;
|
private readonly object _lock;
|
||||||
|
|
||||||
public ChannelManager(UserStore users, Database database, Serilog.ILogger logger)
|
public ChannelManager(UserStore users, Database database, ServerConfiguration configuration, Serilog.ILogger logger)
|
||||||
{
|
{
|
||||||
_users = users;
|
_users = users;
|
||||||
_database = database;
|
_database = database;
|
||||||
|
_configuration = configuration;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_channels = new ConcurrentDictionary<string, Channel>();
|
_channels = new ConcurrentDictionary<string, Channel>();
|
||||||
_lock = new object();
|
_lock = new object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Channel?> Add(string userId)
|
public Task<Channel?> Add(string userId)
|
||||||
{
|
{
|
||||||
var user = _users.Get(userId);
|
var user = _users.Get(userId);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
return Task.FromResult<Channel?>(null);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (_channels.ContainsKey(userId))
|
if (_channels.ContainsKey(userId))
|
||||||
{
|
return Task.FromResult<Channel?>(null);
|
||||||
return null;
|
|
||||||
}
|
var actionTable = _configuration.Database.Tables["Action"];
|
||||||
|
var chatterTable = _configuration.Database.Tables["Chatter"];
|
||||||
|
var policyTable = _configuration.Database.Tables["Policy"];
|
||||||
|
var redemptionTable = _configuration.Database.Tables["Redemption"];
|
||||||
|
var ttsFilterTable = _configuration.Database.Tables["TtsFilter"];
|
||||||
|
|
||||||
|
var chatters = new ChatterStore(userId, chatterTable, _database, _logger);
|
||||||
|
var policies = new PolicyStore(userId, policyTable, _database, _logger);
|
||||||
|
var filters = new TTSFilterStore(userId, ttsFilterTable, _database, _logger);
|
||||||
|
var actions = new ActionStore(userId, actionTable, _database, _logger);
|
||||||
|
var redemptions = new RedemptionStore(userId, redemptionTable, _database, _logger);
|
||||||
|
|
||||||
var chatters = new ChatterStore(userId, _database, _logger);
|
|
||||||
var policies = new PolicyStore(userId, _database, _logger);
|
|
||||||
var filters = new TTSFilterStore(userId, _database, _logger);
|
|
||||||
Task.WaitAll([
|
Task.WaitAll([
|
||||||
chatters.Load(),
|
chatters.Load(),
|
||||||
policies.Load(),
|
policies.Load(),
|
||||||
filters.Load(),
|
filters.Load(),
|
||||||
|
actions.Load(),
|
||||||
|
redemptions.Load(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var channel = new Channel()
|
var channel = new Channel()
|
||||||
@@ -53,10 +63,12 @@ namespace HermesSocketServer.Services
|
|||||||
Chatters = chatters,
|
Chatters = chatters,
|
||||||
Policies = policies,
|
Policies = policies,
|
||||||
Filters = filters,
|
Filters = filters,
|
||||||
|
Actions = actions,
|
||||||
|
Redemptions = redemptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
_channels.Add(userId, channel);
|
_channels.Add(userId, channel);
|
||||||
return channel;
|
return Task.FromResult<Channel?>(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +88,8 @@ namespace HermesSocketServer.Services
|
|||||||
channel.Chatters.Save(),
|
channel.Chatters.Save(),
|
||||||
channel.Policies.Save(),
|
channel.Policies.Save(),
|
||||||
channel.Filters.Save(),
|
channel.Filters.Save(),
|
||||||
|
channel.Actions.Save(),
|
||||||
|
channel.Redemptions.Save(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +102,8 @@ namespace HermesSocketServer.Services
|
|||||||
channel.Chatters.Save(),
|
channel.Chatters.Save(),
|
||||||
channel.Policies.Save(),
|
channel.Policies.Save(),
|
||||||
channel.Filters.Save(),
|
channel.Filters.Save(),
|
||||||
|
channel.Actions.Save(),
|
||||||
|
channel.Redemptions.Save(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ namespace HermesSocketServer.Socket.Handlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task Execute<T>(WebSocketUser sender, T data, HermesSocketManager sockets)
|
public Task Execute<T>(WebSocketUser sender, T data, HermesSocketManager sockets)
|
||||||
{
|
{
|
||||||
if (data is not LoggingMessage message || sender.Id == null)
|
if (data is not LoggingMessage message || sender.Id == null)
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Action<Exception?, string> logging;
|
Action<Exception?, string> logging;
|
||||||
if (message.Level == HermesLoggingLevel.Trace)
|
if (message.Level == HermesLoggingLevel.Trace)
|
||||||
logging = _logger.Verbose;
|
logging = _logger.Verbose;
|
||||||
@@ -35,10 +35,11 @@ namespace HermesSocketServer.Socket.Handlers
|
|||||||
logging = _logger.Fatal;
|
logging = _logger.Fatal;
|
||||||
else {
|
else {
|
||||||
_logger.Warning("Failed to receive a logging level from client.");
|
_logger.Warning("Failed to receive a logging level from client.");
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.Invoke(message.Exception, message.Message + $" [ip: {sender.IPAddress}][id: {sender.Id}][name: {sender.Name}][token: {sender.ApiKey}][uid: {sender.UID}]");
|
logging.Invoke(message.Exception, message.Message + $" [ip: {sender.IPAddress}][id: {sender.Id}][name: {sender.Name}][token: {sender.ApiKey}][uid: {sender.UID}]");
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ namespace HermesSocketServer.Socket
|
|||||||
public IPAddress? IPAddress { get => _ipAddress; }
|
public IPAddress? IPAddress { get => _ipAddress; }
|
||||||
public bool Connected { get => _connected; }
|
public bool Connected { get => _connected; }
|
||||||
public string UID { get; }
|
public string UID { get; }
|
||||||
public string ApiKey { get; set; }
|
public string? ApiKey { get; set; }
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
public bool Admin { get; set; }
|
public bool Admin { get; set; }
|
||||||
|
|||||||
21
Startup.cs
21
Startup.cs
@@ -15,6 +15,8 @@ using Microsoft.AspNetCore.Connections;
|
|||||||
using HermesSocketServer.Validators;
|
using HermesSocketServer.Validators;
|
||||||
using HermesSocketServer.Store;
|
using HermesSocketServer.Store;
|
||||||
using HermesSocketServer.Services;
|
using HermesSocketServer.Services;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
|
||||||
var yamlDeserializer = new DeserializerBuilder()
|
var yamlDeserializer = new DeserializerBuilder()
|
||||||
@@ -78,15 +80,26 @@ s.AddSingleton<ISocketHandler, EmoteUsageHandler>();
|
|||||||
s.AddSingleton<VoiceIdValidator>();
|
s.AddSingleton<VoiceIdValidator>();
|
||||||
s.AddSingleton<VoiceNameValidator>();
|
s.AddSingleton<VoiceNameValidator>();
|
||||||
|
|
||||||
|
// Database Tables
|
||||||
|
if (configuration.Database.Tables != null)
|
||||||
|
{
|
||||||
|
foreach (var table in configuration.Database.Tables)
|
||||||
|
s.AddKeyedTransient<DatabaseTable>(table.Key, (sp, _) => table.Value);
|
||||||
|
}
|
||||||
|
|
||||||
// Stores
|
// Stores
|
||||||
s.AddSingleton<VoiceStore>();
|
s.AddSingleton<VoiceStore>();
|
||||||
s.AddSingleton<UserStore>();
|
s.AddSingleton<UserStore>();
|
||||||
|
|
||||||
// Request handlers
|
// Request handlers
|
||||||
s.AddSingleton<IRequest, CreatePolicy>();
|
s.AddSingleton<IRequest, CreatePolicy>();
|
||||||
|
s.AddSingleton<IRequest, CreateRedeemableAction>();
|
||||||
|
s.AddSingleton<IRequest, CreateRedemption>();
|
||||||
s.AddSingleton<IRequest, CreateTTSFilter>();
|
s.AddSingleton<IRequest, CreateTTSFilter>();
|
||||||
s.AddSingleton<IRequest, CreateTTSUser>();
|
s.AddSingleton<IRequest, CreateTTSUser>();
|
||||||
s.AddSingleton<IRequest, CreateTTSVoice>();
|
s.AddSingleton<IRequest, CreateTTSVoice>();
|
||||||
|
s.AddSingleton<IRequest, DeleteRedeemableAction>();
|
||||||
|
s.AddSingleton<IRequest, DeleteRedemption>();
|
||||||
s.AddSingleton<IRequest, DeletePolicy>();
|
s.AddSingleton<IRequest, DeletePolicy>();
|
||||||
s.AddSingleton<IRequest, DeleteTTSFilter>();
|
s.AddSingleton<IRequest, DeleteTTSFilter>();
|
||||||
s.AddSingleton<IRequest, DeleteTTSVoice>();
|
s.AddSingleton<IRequest, DeleteTTSVoice>();
|
||||||
@@ -96,18 +109,20 @@ s.AddSingleton<IRequest, GetDefaultTTSVoice>();
|
|||||||
s.AddSingleton<IRequest, GetEmotes>();
|
s.AddSingleton<IRequest, GetEmotes>();
|
||||||
s.AddSingleton<IRequest, GetEnabledTTSVoices>();
|
s.AddSingleton<IRequest, GetEnabledTTSVoices>();
|
||||||
s.AddSingleton<IRequest, GetPermissions>();
|
s.AddSingleton<IRequest, GetPermissions>();
|
||||||
s.AddSingleton<IRequest, GetRedemptions>();
|
|
||||||
s.AddSingleton<IRequest, GetRedeemableActions>();
|
s.AddSingleton<IRequest, GetRedeemableActions>();
|
||||||
|
s.AddSingleton<IRequest, GetRedemptions>();
|
||||||
s.AddSingleton<IRequest, GetPolicies>();
|
s.AddSingleton<IRequest, GetPolicies>();
|
||||||
s.AddSingleton<IRequest, GetTTSUsers>();
|
s.AddSingleton<IRequest, GetTTSUsers>();
|
||||||
s.AddSingleton<IRequest, GetTTSVoices>();
|
s.AddSingleton<IRequest, GetTTSVoices>();
|
||||||
s.AddSingleton<IRequest, GetTTSWordFilters>();
|
s.AddSingleton<IRequest, GetTTSWordFilters>();
|
||||||
|
s.AddSingleton<IRequest, UpdateDefaultTTSVoice>();
|
||||||
|
s.AddSingleton<IRequest, UpdatePolicy>();
|
||||||
|
s.AddSingleton<IRequest, UpdateRedeemableAction>();
|
||||||
|
s.AddSingleton<IRequest, UpdateRedemption>();
|
||||||
s.AddSingleton<IRequest, UpdateTTSFilter>();
|
s.AddSingleton<IRequest, UpdateTTSFilter>();
|
||||||
s.AddSingleton<IRequest, UpdateTTSUser>();
|
s.AddSingleton<IRequest, UpdateTTSUser>();
|
||||||
s.AddSingleton<IRequest, UpdateTTSVoice>();
|
s.AddSingleton<IRequest, UpdateTTSVoice>();
|
||||||
s.AddSingleton<IRequest, UpdateDefaultTTSVoice>();
|
|
||||||
s.AddSingleton<IRequest, UpdateTTSVoiceState>();
|
s.AddSingleton<IRequest, UpdateTTSVoiceState>();
|
||||||
s.AddSingleton<IRequest, UpdatePolicy>();
|
|
||||||
|
|
||||||
// Managers
|
// Managers
|
||||||
s.AddSingleton<ChannelManager>();
|
s.AddSingleton<ChannelManager>();
|
||||||
|
|||||||
53
Store/ActionStore.cs
Normal file
53
Store/ActionStore.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using HermesSocketLibrary.db;
|
||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Store
|
||||||
|
{
|
||||||
|
public class ActionStore : AutoSavedStore<string, RedeemableAction>
|
||||||
|
{
|
||||||
|
private readonly string _userId;
|
||||||
|
private readonly Database _database;
|
||||||
|
private readonly Serilog.ILogger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public ActionStore(string userId, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
|
{
|
||||||
|
_userId = userId;
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Load()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>() { { "user", _userId } };
|
||||||
|
string sql = $"SELECT name, type, data FROM \"Action\" WHERE \"userId\" = @user";
|
||||||
|
await _database.Execute(sql, data, (reader) =>
|
||||||
|
{
|
||||||
|
var name = reader.GetString(0);
|
||||||
|
_store.Add(name.ToString(), new RedeemableAction()
|
||||||
|
{
|
||||||
|
UserId = _userId,
|
||||||
|
Name = name,
|
||||||
|
Type = reader.GetString(1),
|
||||||
|
Data = JsonSerializer.Deserialize<IDictionary<string, string>>(reader.GetString(2))!
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_logger.Information($"Loaded {_store.Count} TTS chatter voices from database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialAdd(string key, RedeemableAction value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialModify(string key, RedeemableAction value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialRemove(string key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,22 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store
|
||||||
{
|
{
|
||||||
public class ChatterStore : GroupSaveStore<string, ChatterVoice>
|
public class ChatterStore : AutoSavedStore<string, ChatterVoice>
|
||||||
{
|
{
|
||||||
private readonly string _userId;
|
private readonly string _userId;
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly GroupSaveSqlGenerator<ChatterVoice> _generator;
|
|
||||||
|
|
||||||
|
|
||||||
public ChatterStore(string userId, Database database, Serilog.ILogger logger) : base(logger)
|
public ChatterStore(string userId, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
{
|
{
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
_database = database;
|
_database = database;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var ctp = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "chatterId", "ChatterId" },
|
|
||||||
{ "ttsVoiceId", "VoiceId" },
|
|
||||||
{ "userId", "UserId" },
|
|
||||||
};
|
|
||||||
_generator = new GroupSaveSqlGenerator<ChatterVoice>(ctp, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Load()
|
public override async Task Load()
|
||||||
@@ -55,54 +47,5 @@ namespace HermesSocketServer.Store
|
|||||||
protected override void OnInitialRemove(string key)
|
protected override void OnInitialRemove(string key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Save()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
string sql = string.Empty;
|
|
||||||
ImmutableList<string>? list = null;
|
|
||||||
|
|
||||||
if (_added.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _added.ToImmutableList();
|
|
||||||
_added.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedInsertSql("TtsChatVoice", count, ["userId", "chatterId", "ttsVoiceId"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Chatter - Adding {count} rows to database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["userId", "chatterId", "ttsVoiceId"]);
|
|
||||||
}
|
|
||||||
if (_modified.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _modified.ToImmutableList();
|
|
||||||
_modified.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedUpdateSql("TtsChatVoice", count, ["userId", "chatterId"], ["ttsVoiceId"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Chatter - Modifying {count} rows in database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["userId", "chatterId", "ttsVoiceId"]);
|
|
||||||
}
|
|
||||||
if (_deleted.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _deleted.ToImmutableList();
|
|
||||||
_deleted.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedDeleteSql("TtsChatVoice", count, ["userId", "chatterId"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Chatter - Deleting {count} rows from database: {sql}");
|
|
||||||
await _generator.DoPreparedStatementRaw(_database, sql, list, ["userId", "chatterId"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ namespace HermesSocketServer.Store
|
|||||||
IDictionary<K, V> Get();
|
IDictionary<K, V> Get();
|
||||||
Task Load();
|
Task Load();
|
||||||
bool Modify(K? key, Action<V> action);
|
bool Modify(K? key, Action<V> action);
|
||||||
void Remove(K? key);
|
bool Remove(K? key);
|
||||||
Task Save();
|
Task Save();
|
||||||
bool Set(K? key, V? value);
|
bool Set(K? key, V? value);
|
||||||
}
|
}
|
||||||
|
|||||||
11
Store/Internal/DatabaseTable.cs
Normal file
11
Store/Internal/DatabaseTable.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace HermesSocketServer.Store.Internal
|
||||||
|
{
|
||||||
|
public class DatabaseTable
|
||||||
|
{
|
||||||
|
public required string TableName { get; set; }
|
||||||
|
public required string[] KeyColumns { get; set; }
|
||||||
|
public required string[] DataColumns { get; set; }
|
||||||
|
public required IDictionary<string, string> PropertyMapping { get; set; }
|
||||||
|
public IDictionary<string, string>? TypeMapping { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,29 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
|
using NpgsqlTypes;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store.Internal
|
||||||
{
|
{
|
||||||
public class GroupSaveSqlGenerator<T>
|
public class GroupSaveSqlGenerator<T>
|
||||||
{
|
{
|
||||||
private readonly IDictionary<string, PropertyInfo?> columnPropertyRelations;
|
private readonly IDictionary<string, PropertyInfo?> _columnPropertyRelations;
|
||||||
|
private readonly IDictionary<string, NpgsqlDbType> _columnTypes;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
|
|
||||||
public GroupSaveSqlGenerator(IDictionary<string, string> columnsToProperties, Serilog.ILogger logger)
|
public GroupSaveSqlGenerator(IDictionary<string, string> columnsToProperties, Serilog.ILogger logger)
|
||||||
|
: this(columnsToProperties, new Dictionary<string, NpgsqlDbType>(), logger)
|
||||||
{
|
{
|
||||||
columnPropertyRelations = columnsToProperties.ToDictionary(p => p.Key, p => typeof(T).GetProperty(p.Value));
|
}
|
||||||
|
|
||||||
|
public GroupSaveSqlGenerator(IDictionary<string, string> columnsToProperties, IDictionary<string, NpgsqlDbType> columnTypes, Serilog.ILogger logger)
|
||||||
|
{
|
||||||
|
_columnPropertyRelations = columnsToProperties.ToDictionary(p => p.Key, p => typeof(T).GetProperty(p.Value));
|
||||||
|
_columnTypes = columnTypes;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var nullProperties = columnPropertyRelations.Where(p => p.Value == null)
|
var nullProperties = _columnPropertyRelations.Where(p => p.Value == null)
|
||||||
.Select(p => columnsToProperties[p.Key]);
|
.Select(p => columnsToProperties[p.Key]);
|
||||||
if (nullProperties.Any())
|
if (nullProperties.Any())
|
||||||
throw new ArgumentException("Some properties do not exist on the values given: " + string.Join(", ", nullProperties));
|
throw new ArgumentException("Some properties do not exist on the values given: " + string.Join(", ", nullProperties));
|
||||||
@@ -31,8 +40,15 @@ namespace HermesSocketServer.Store
|
|||||||
{
|
{
|
||||||
foreach (var column in columns)
|
foreach (var column in columns)
|
||||||
{
|
{
|
||||||
var propValue = columnPropertyRelations[column]!.GetValue(value);
|
var propValue = _columnPropertyRelations[column]!.GetValue(value);
|
||||||
c.Parameters.AddWithValue(column.ToLower() + valueCounter, propValue ?? DBNull.Value);
|
if (_columnTypes.Any() && _columnTypes.TryGetValue(column, out var type))
|
||||||
|
{
|
||||||
|
if (type == NpgsqlDbType.Jsonb)
|
||||||
|
propValue = JsonSerializer.Serialize(propValue);
|
||||||
|
c.Parameters.AddWithValue(column.ToLower() + valueCounter, type, propValue ?? DBNull.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
c.Parameters.AddWithValue(column.ToLower() + valueCounter, propValue ?? DBNull.Value);
|
||||||
}
|
}
|
||||||
valueCounter++;
|
valueCounter++;
|
||||||
}
|
}
|
||||||
@@ -81,7 +97,7 @@ namespace HermesSocketServer.Store
|
|||||||
if (!columns.Any())
|
if (!columns.Any())
|
||||||
throw new ArgumentException("Empty list given.", nameof(columns));
|
throw new ArgumentException("Empty list given.", nameof(columns));
|
||||||
|
|
||||||
var ctp = columns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = columns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"INSERT INTO \"{table}\" (\"{string.Join("\", \"", columns)}\") VALUES ");
|
sb.Append($"INSERT INTO \"{table}\" (\"{string.Join("\", \"", columns)}\") VALUES ");
|
||||||
foreach (var value in values)
|
foreach (var value in values)
|
||||||
@@ -89,8 +105,8 @@ namespace HermesSocketServer.Store
|
|||||||
sb.Append("(");
|
sb.Append("(");
|
||||||
foreach (var column in columns)
|
foreach (var column in columns)
|
||||||
{
|
{
|
||||||
var propValue = columnPropertyRelations[column]!.GetValue(value);
|
var propValue = _columnPropertyRelations[column]!.GetValue(value);
|
||||||
var propType = columnPropertyRelations[column]!.PropertyType;
|
var propType = _columnPropertyRelations[column]!.PropertyType;
|
||||||
WriteValue(sb, propValue ?? DBNull.Value, propType);
|
WriteValue(sb, propValue ?? DBNull.Value, propType);
|
||||||
sb.Append(",");
|
sb.Append(",");
|
||||||
}
|
}
|
||||||
@@ -111,7 +127,7 @@ namespace HermesSocketServer.Store
|
|||||||
if (!columns.Any())
|
if (!columns.Any())
|
||||||
throw new ArgumentException("Empty list given.", nameof(columns));
|
throw new ArgumentException("Empty list given.", nameof(columns));
|
||||||
|
|
||||||
var ctp = columns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = columns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var columnsLower = columns.Select(c => c.ToLower());
|
var columnsLower = columns.Select(c => c.ToLower());
|
||||||
sb.Append($"INSERT INTO \"{table}\" (\"{string.Join("\", \"", columns)}\") VALUES ");
|
sb.Append($"INSERT INTO \"{table}\" (\"{string.Join("\", \"", columns)}\") VALUES ");
|
||||||
@@ -151,7 +167,7 @@ namespace HermesSocketServer.Store
|
|||||||
throw new ArgumentException("Empty list given.", nameof(updateColumns));
|
throw new ArgumentException("Empty list given.", nameof(updateColumns));
|
||||||
|
|
||||||
var columns = keyColumns.Union(updateColumns);
|
var columns = keyColumns.Union(updateColumns);
|
||||||
var ctp = columns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = columns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"UPDATE \"{table}\" as t SET {string.Join(", ", updateColumns.Select(c => "\"" + c + "\" = c.\"" + c + "\""))} FROM (VALUES ");
|
sb.Append($"UPDATE \"{table}\" as t SET {string.Join(", ", updateColumns.Select(c => "\"" + c + "\" = c.\"" + c + "\""))} FROM (VALUES ");
|
||||||
foreach (var value in values)
|
foreach (var value in values)
|
||||||
@@ -159,8 +175,8 @@ namespace HermesSocketServer.Store
|
|||||||
sb.Append("(");
|
sb.Append("(");
|
||||||
foreach (var column in columns)
|
foreach (var column in columns)
|
||||||
{
|
{
|
||||||
var propValue = columnPropertyRelations[column]!.GetValue(value);
|
var propValue = _columnPropertyRelations[column]!.GetValue(value);
|
||||||
var propType = columnPropertyRelations[column]!.PropertyType;
|
var propType = _columnPropertyRelations[column]!.PropertyType;
|
||||||
WriteValue(sb, propValue, propType);
|
WriteValue(sb, propValue, propType);
|
||||||
sb.Append(",");
|
sb.Append(",");
|
||||||
}
|
}
|
||||||
@@ -189,7 +205,7 @@ namespace HermesSocketServer.Store
|
|||||||
throw new ArgumentException("Empty list given.", nameof(updateColumns));
|
throw new ArgumentException("Empty list given.", nameof(updateColumns));
|
||||||
|
|
||||||
var columns = keyColumns.Union(updateColumns);
|
var columns = keyColumns.Union(updateColumns);
|
||||||
var ctp = columns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = columns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"UPDATE \"{table}\" as t SET {string.Join(", ", updateColumns.Select(c => "\"" + c + "\" = c.\"" + c + "\""))} FROM (VALUES ");
|
sb.Append($"UPDATE \"{table}\" as t SET {string.Join(", ", updateColumns.Select(c => "\"" + c + "\" = c.\"" + c + "\""))} FROM (VALUES ");
|
||||||
for (var row = 0; row < rows; row++)
|
for (var row = 0; row < rows; row++)
|
||||||
@@ -226,7 +242,7 @@ namespace HermesSocketServer.Store
|
|||||||
if (!keyColumns.Any())
|
if (!keyColumns.Any())
|
||||||
throw new ArgumentException("Empty list given.", nameof(keyColumns));
|
throw new ArgumentException("Empty list given.", nameof(keyColumns));
|
||||||
|
|
||||||
var ctp = keyColumns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = keyColumns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"DELETE FROM \"{table}\" WHERE (\"{string.Join("\", \"", keyColumns)}\") IN (");
|
sb.Append($"DELETE FROM \"{table}\" WHERE (\"{string.Join("\", \"", keyColumns)}\") IN (");
|
||||||
foreach (var k in keys)
|
foreach (var k in keys)
|
||||||
@@ -234,7 +250,7 @@ namespace HermesSocketServer.Store
|
|||||||
sb.Append("(");
|
sb.Append("(");
|
||||||
foreach (var column in keyColumns)
|
foreach (var column in keyColumns)
|
||||||
{
|
{
|
||||||
var propType = columnPropertyRelations[column]!.PropertyType;
|
var propType = _columnPropertyRelations[column]!.PropertyType;
|
||||||
WriteValue(sb, k, propType);
|
WriteValue(sb, k, propType);
|
||||||
sb.Append(",");
|
sb.Append(",");
|
||||||
}
|
}
|
||||||
@@ -256,7 +272,7 @@ namespace HermesSocketServer.Store
|
|||||||
if (!keyColumns.Any())
|
if (!keyColumns.Any())
|
||||||
throw new ArgumentException("Empty list given.", nameof(keyColumns));
|
throw new ArgumentException("Empty list given.", nameof(keyColumns));
|
||||||
|
|
||||||
var ctp = keyColumns.ToDictionary(c => c, c => columnPropertyRelations[c]);
|
var ctp = keyColumns.ToDictionary(c => c, c => _columnPropertyRelations[c]);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"DELETE FROM \"{table}\" WHERE (\"{string.Join("\", \"", keyColumns)}\") IN (");
|
sb.Append($"DELETE FROM \"{table}\" WHERE (\"{string.Join("\", \"", keyColumns)}\") IN (");
|
||||||
for (var row = 0; row < rows; row++)
|
for (var row = 0; row < rows; row++)
|
||||||
@@ -289,7 +305,12 @@ namespace HermesSocketServer.Store
|
|||||||
.Append(value?.ToString())
|
.Append(value?.ToString())
|
||||||
.Append("')");
|
.Append("')");
|
||||||
else if (type == typeof(TimeSpan))
|
else if (type == typeof(TimeSpan))
|
||||||
sb.Append(((TimeSpan)value).TotalMilliseconds);
|
{
|
||||||
|
if (value == null)
|
||||||
|
sb.Append("0");
|
||||||
|
else
|
||||||
|
sb.Append(((TimeSpan)value).TotalMilliseconds);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sb.Append(value);
|
sb.Append(value);
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store.Internal
|
||||||
{
|
{
|
||||||
public abstract class GroupSaveStore<K, V> : IStore<K, V> where K : class where V : class
|
public abstract class GroupSaveStore<K, V> : IStore<K, V> where K : class where V : class
|
||||||
{
|
{
|
||||||
@@ -60,30 +60,30 @@ namespace HermesSocketServer.Store
|
|||||||
if (value == null)
|
if (value == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
OnInitialModify(key, value);
|
||||||
action(value);
|
action(value);
|
||||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||||
{
|
{
|
||||||
_modified.Add(key);
|
_modified.Add(key);
|
||||||
_logger.Information($"added key to _modified {key}");
|
_logger.Information($"added key to _modified {key}");
|
||||||
}
|
}
|
||||||
OnInitialModify(key, value);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(K? key)
|
public bool Remove(K? key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
if (key == null)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
OnInitialRemove(key);
|
||||||
if (_store.Remove(key))
|
if (_store.Remove(key))
|
||||||
{
|
{
|
||||||
_logger.Information($"removed key from _deleted {key}");
|
_logger.Information($"removed key from _deleted {key}");
|
||||||
OnInitialRemove(key);
|
|
||||||
if (!_added.Remove(key))
|
if (!_added.Remove(key))
|
||||||
{
|
{
|
||||||
_modified.Remove(key);
|
_modified.Remove(key);
|
||||||
@@ -94,8 +94,10 @@ namespace HermesSocketServer.Store
|
|||||||
_logger.Information($"added key to _deleted {key}");
|
_logger.Information($"added key to _deleted {key}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Set(K? key, V? value)
|
public bool Set(K? key, V? value)
|
||||||
61
Store/Internal/SelfGeneratedStore.cs
Normal file
61
Store/Internal/SelfGeneratedStore.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using HermesSocketLibrary.db;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Store.Internal
|
||||||
|
{
|
||||||
|
public abstract class AutoSavedStore<K, V> : GroupSaveStore<K, V> where K : class where V : class
|
||||||
|
{
|
||||||
|
private readonly GroupSaveSqlGenerator<V> _generator;
|
||||||
|
private readonly DatabaseTable _table;
|
||||||
|
private readonly Database _database;
|
||||||
|
private readonly Serilog.ILogger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public AutoSavedStore(DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(logger)
|
||||||
|
{
|
||||||
|
_generator = new GroupSaveSqlGenerator<V>(table.PropertyMapping, logger);
|
||||||
|
_table = table;
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Save()
|
||||||
|
{
|
||||||
|
var allColumns = _table.KeyColumns.Union(_table.DataColumns).ToArray();
|
||||||
|
|
||||||
|
await GenerateQuery(_added,
|
||||||
|
(size) => _generator.GeneratePreparedInsertSql(_table.TableName, size, allColumns),
|
||||||
|
async (query, _, values) => await _generator.DoPreparedStatement(_database, query, values, allColumns));
|
||||||
|
|
||||||
|
await GenerateQuery(_modified,
|
||||||
|
(size) => _generator.GeneratePreparedUpdateSql(_table.TableName, size, _table.KeyColumns, _table.DataColumns),
|
||||||
|
async (query, _, values) => await _generator.DoPreparedStatement(_database, query, values, allColumns));
|
||||||
|
|
||||||
|
await GenerateQuery(_deleted,
|
||||||
|
(size) => _generator.GeneratePreparedDeleteSql(_table.TableName, size, _table.KeyColumns),
|
||||||
|
async (query, keys, _) => await _generator.DoPreparedStatementRaw(_database, query, keys, _table.KeyColumns));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GenerateQuery(IList<K> keys, Func<int, string> generate, Func<string, IEnumerable<K>, IEnumerable<V>, Task> execute)
|
||||||
|
{
|
||||||
|
ImmutableList<K>? list = null;
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (!keys.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
list = keys.ToImmutableList();
|
||||||
|
keys.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = generate(list.Count);
|
||||||
|
_logger.Debug($"{_table.TableName} - Adding {list.Count} rows to database: {query}");
|
||||||
|
|
||||||
|
var values = list.Select(id => _store[id]).Where(v => v != null);
|
||||||
|
await execute(query, list, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +1,22 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store
|
||||||
{
|
{
|
||||||
public class PolicyStore : GroupSaveStore<string, PolicyMessage>
|
public class PolicyStore : AutoSavedStore<string, PolicyMessage>
|
||||||
{
|
{
|
||||||
private readonly string _userId;
|
private readonly string _userId;
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly GroupSaveSqlGenerator<PolicyMessage> _generator;
|
|
||||||
|
|
||||||
|
|
||||||
public PolicyStore(string userId, Database database, Serilog.ILogger logger) : base(logger)
|
public PolicyStore(string userId, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
{
|
{
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
_database = database;
|
_database = database;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var ctp = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "id", "Id" },
|
|
||||||
{ "userId", "UserId" },
|
|
||||||
{ "groupId", "GroupId" },
|
|
||||||
{ "path", "Path" },
|
|
||||||
{ "count", "Usage" },
|
|
||||||
{ "timespan", "Span" },
|
|
||||||
};
|
|
||||||
_generator = new GroupSaveSqlGenerator<PolicyMessage>(ctp, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Load()
|
public override async Task Load()
|
||||||
@@ -61,54 +50,5 @@ namespace HermesSocketServer.Store
|
|||||||
protected override void OnInitialRemove(string key)
|
protected override void OnInitialRemove(string key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Save()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
string sql = string.Empty;
|
|
||||||
ImmutableList<string>? list = null;
|
|
||||||
|
|
||||||
if (_added.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _added.ToImmutableList();
|
|
||||||
_added.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedInsertSql("GroupPermissionPolicy", count, ["id", "userId", "groupId", "path", "count", "timespan"]);
|
|
||||||
|
|
||||||
_logger.Debug($"GroupPermissionPolicy - Adding {count} rows to database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "groupId", "path", "count", "timespan"]);
|
|
||||||
}
|
|
||||||
if (_modified.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _modified.ToImmutableList();
|
|
||||||
_modified.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedUpdateSql("GroupPermissionPolicy", count, ["id"], ["userId", "groupId", "path", "count", "timespan"]);
|
|
||||||
|
|
||||||
_logger.Debug($"GroupPermissionPolicy - Modifying {count} rows in database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "groupId", "path", "count", "timespan"]);
|
|
||||||
}
|
|
||||||
if (_deleted.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _deleted.ToImmutableList();
|
|
||||||
_deleted.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedDeleteSql("GroupPermissionPolicy", count, ["id"]);
|
|
||||||
|
|
||||||
_logger.Debug($"GroupPermissionPolicy - Deleting {count} rows from database: {sql}");
|
|
||||||
await _generator.DoPreparedStatementRaw(_database, sql, list.Select(id => new Guid(id)), ["id"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
54
Store/RedemptionStore.cs
Normal file
54
Store/RedemptionStore.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using HermesSocketLibrary.db;
|
||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Store
|
||||||
|
{
|
||||||
|
public class RedemptionStore : AutoSavedStore<string, Redemption>
|
||||||
|
{
|
||||||
|
private readonly string _userId;
|
||||||
|
private readonly Database _database;
|
||||||
|
private readonly Serilog.ILogger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public RedemptionStore(string userId, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
|
{
|
||||||
|
_userId = userId;
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Load()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>() { { "user", _userId } };
|
||||||
|
string sql = $"SELECT id, \"redemptionId\", \"order\", \"state\", \"actionName\" FROM \"Redemption\" WHERE \"userId\" = @user";
|
||||||
|
await _database.Execute(sql, data, (reader) =>
|
||||||
|
{
|
||||||
|
var id = reader.GetGuid(0);
|
||||||
|
_store.Add(id.ToString(), new Redemption()
|
||||||
|
{
|
||||||
|
Id = id.ToString(),
|
||||||
|
UserId = _userId,
|
||||||
|
RedemptionId = reader.GetString(1),
|
||||||
|
Order = reader.GetInt32(2),
|
||||||
|
State = reader.GetBoolean(3),
|
||||||
|
ActionName = reader.GetString(4),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_logger.Information($"Loaded {_store.Count} TTS chatter voices from database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialAdd(string key, Redemption value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialModify(string key, Redemption value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialRemove(string key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,31 +1,22 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketLibrary.Requests.Messages;
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store
|
||||||
{
|
{
|
||||||
public class TTSFilterStore : GroupSaveStore<string, TTSWordFilter>
|
public class TTSFilterStore : AutoSavedStore<string, TTSWordFilter>
|
||||||
{
|
{
|
||||||
private readonly string _userId;
|
private readonly string _userId;
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly GroupSaveSqlGenerator<TTSWordFilter> _generator;
|
|
||||||
|
|
||||||
|
|
||||||
public TTSFilterStore(string userId, Database database, Serilog.ILogger logger) : base(logger)
|
public TTSFilterStore(string userId, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
{
|
{
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
_database = database;
|
_database = database;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var ctp = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "id", "Id" },
|
|
||||||
{ "userId", "UserId" },
|
|
||||||
{ "search", "Search" },
|
|
||||||
{ "replace", "Replace" },
|
|
||||||
};
|
|
||||||
_generator = new GroupSaveSqlGenerator<TTSWordFilter>(ctp, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Load()
|
public override async Task Load()
|
||||||
@@ -56,54 +47,5 @@ namespace HermesSocketServer.Store
|
|||||||
protected override void OnInitialRemove(string key)
|
protected override void OnInitialRemove(string key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Save()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
string sql = string.Empty;
|
|
||||||
ImmutableList<string>? list = null;
|
|
||||||
|
|
||||||
if (_added.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _added.ToImmutableList();
|
|
||||||
_added.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedInsertSql("TtsWordFilter", count, ["id", "userId", "search", "replace"]);
|
|
||||||
|
|
||||||
_logger.Debug($"TTS Filter - Adding {count} rows to database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "search", "replace"]);
|
|
||||||
}
|
|
||||||
if (_modified.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _modified.ToImmutableList();
|
|
||||||
_modified.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedUpdateSql("TtsWordFilter", count, ["id"], ["userId", "search", "replace"]);
|
|
||||||
|
|
||||||
_logger.Debug($"TTS Filter - Modifying {count} rows in database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "search", "replace"]);
|
|
||||||
}
|
|
||||||
if (_deleted.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _deleted.ToImmutableList();
|
|
||||||
_deleted.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedDeleteSql("TtsWordFilter", count, ["id"]);
|
|
||||||
|
|
||||||
_logger.Debug($"TTS Filter - Deleting {count} rows from database: {sql}");
|
|
||||||
await _generator.DoPreparedStatementRaw(_database, sql, list, ["id"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,20 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketServer.Models;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store
|
||||||
{
|
{
|
||||||
public class UserStore : GroupSaveStore<string, User>
|
public class UserStore : AutoSavedStore<string, User>
|
||||||
{
|
{
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly GroupSaveSqlGenerator<User> _generator;
|
|
||||||
|
|
||||||
|
|
||||||
public UserStore(Database database, Serilog.ILogger logger) : base(logger)
|
public UserStore([FromKeyedServices("User")] DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var ctp = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "id", "Id" },
|
|
||||||
{ "name", "Name" },
|
|
||||||
{ "email", "Email" },
|
|
||||||
{ "role", "Role" },
|
|
||||||
{ "ttsDefaultVoice", "DefaultVoice" }
|
|
||||||
};
|
|
||||||
_generator = new GroupSaveSqlGenerator<User>(ctp, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Load()
|
public override async Task Load()
|
||||||
@@ -56,54 +46,5 @@ namespace HermesSocketServer.Store
|
|||||||
protected override void OnInitialRemove(string key)
|
protected override void OnInitialRemove(string key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Save()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
string sql = string.Empty;
|
|
||||||
ImmutableList<string>? list = null;
|
|
||||||
|
|
||||||
if (_added.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _added.ToImmutableList();
|
|
||||||
_added.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedInsertSql("User", count, ["id", "name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
|
|
||||||
_logger.Debug($"User - Adding {count} rows to database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
}
|
|
||||||
if (_modified.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _modified.ToImmutableList();
|
|
||||||
_modified.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedUpdateSql("User", count, ["id"], ["name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
|
|
||||||
_logger.Debug($"User - Modifying {count} rows in database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
}
|
|
||||||
if (_deleted.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _deleted.ToImmutableList();
|
|
||||||
_deleted.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedDeleteSql("User", count, ["id"]);
|
|
||||||
|
|
||||||
_logger.Debug($"User - Deleting {count} rows from database: {sql}");
|
|
||||||
await _generator.DoPreparedStatementRaw(_database, sql, list, ["id"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
55
Store/VoiceStateStore.cs
Normal file
55
Store/VoiceStateStore.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using HermesSocketLibrary.db;
|
||||||
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
|
using HermesSocketServer.Validators;
|
||||||
|
|
||||||
|
namespace HermesSocketServer.Store
|
||||||
|
{
|
||||||
|
public class VoiceStateStore : AutoSavedStore<string, TTSVoiceState>
|
||||||
|
{
|
||||||
|
private readonly string _userId;
|
||||||
|
private readonly VoiceIdValidator _idValidator;
|
||||||
|
private readonly Database _database;
|
||||||
|
private readonly Serilog.ILogger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public VoiceStateStore(string userId, VoiceIdValidator voiceIdValidator, DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
|
{
|
||||||
|
_userId = userId;
|
||||||
|
_idValidator = voiceIdValidator;
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Load()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>() { { "user", _userId } };
|
||||||
|
string sql = "SELECT \"ttsVoiceId\", state FROM \"TtsVoiceState\" WHERE \"userId\" = @user";
|
||||||
|
await _database.Execute(sql, data, (reader) =>
|
||||||
|
{
|
||||||
|
string id = reader.GetString(0);
|
||||||
|
_store.Add(id, new TTSVoiceState()
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
Enabled = reader.GetBoolean(1),
|
||||||
|
UserId = _userId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_logger.Information($"Loaded {_store.Count} TTS voice states from database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialAdd(string key, TTSVoiceState value)
|
||||||
|
{
|
||||||
|
_idValidator.Check(value.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialModify(string key, TTSVoiceState value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialRemove(string key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +1,25 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using HermesSocketLibrary.db;
|
using HermesSocketLibrary.db;
|
||||||
using HermesSocketServer.Models;
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
|
using HermesSocketServer.Store.Internal;
|
||||||
using HermesSocketServer.Validators;
|
using HermesSocketServer.Validators;
|
||||||
|
|
||||||
namespace HermesSocketServer.Store
|
namespace HermesSocketServer.Store
|
||||||
{
|
{
|
||||||
public class VoiceStore : GroupSaveStore<string, Voice>
|
public class VoiceStore : AutoSavedStore<string, TTSVoice>
|
||||||
{
|
{
|
||||||
private readonly VoiceIdValidator _idValidator;
|
private readonly VoiceIdValidator _idValidator;
|
||||||
private readonly VoiceNameValidator _nameValidator;
|
private readonly VoiceNameValidator _nameValidator;
|
||||||
private readonly Database _database;
|
private readonly Database _database;
|
||||||
private readonly Serilog.ILogger _logger;
|
private readonly Serilog.ILogger _logger;
|
||||||
private readonly GroupSaveSqlGenerator<Voice> _generator;
|
|
||||||
|
|
||||||
|
|
||||||
public VoiceStore(VoiceIdValidator voiceIdValidator, VoiceNameValidator voiceNameValidator, Database database, Serilog.ILogger logger) : base(logger)
|
public VoiceStore(VoiceIdValidator voiceIdValidator, VoiceNameValidator voiceNameValidator, [FromKeyedServices("Voice")] DatabaseTable table, Database database, Serilog.ILogger logger)
|
||||||
|
: base(table, database, logger)
|
||||||
{
|
{
|
||||||
_idValidator = voiceIdValidator;
|
_idValidator = voiceIdValidator;
|
||||||
_nameValidator = voiceNameValidator;
|
_nameValidator = voiceNameValidator;
|
||||||
_database = database;
|
_database = database;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
var ctp = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "id", "Id" },
|
|
||||||
{ "name", "Name" }
|
|
||||||
};
|
|
||||||
_generator = new GroupSaveSqlGenerator<Voice>(ctp, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Load()
|
public override async Task Load()
|
||||||
@@ -35,7 +28,7 @@ namespace HermesSocketServer.Store
|
|||||||
await _database.Execute(sql, new Dictionary<string, object>(), (reader) =>
|
await _database.Execute(sql, new Dictionary<string, object>(), (reader) =>
|
||||||
{
|
{
|
||||||
string id = reader.GetString(0);
|
string id = reader.GetString(0);
|
||||||
_store.Add(id, new Voice()
|
_store.Add(id, new TTSVoice()
|
||||||
{
|
{
|
||||||
Id = id,
|
Id = id,
|
||||||
Name = reader.GetString(1),
|
Name = reader.GetString(1),
|
||||||
@@ -44,13 +37,13 @@ namespace HermesSocketServer.Store
|
|||||||
_logger.Information($"Loaded {_store.Count} TTS voices from database.");
|
_logger.Information($"Loaded {_store.Count} TTS voices from database.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInitialAdd(string key, Voice value)
|
protected override void OnInitialAdd(string key, TTSVoice value)
|
||||||
{
|
{
|
||||||
_idValidator.Check(value.Id);
|
_idValidator.Check(value.Id);
|
||||||
_nameValidator.Check(value.Name);
|
_nameValidator.Check(value.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInitialModify(string key, Voice value)
|
protected override void OnInitialModify(string key, TTSVoice value)
|
||||||
{
|
{
|
||||||
_nameValidator.Check(value.Name);
|
_nameValidator.Check(value.Name);
|
||||||
}
|
}
|
||||||
@@ -58,54 +51,5 @@ namespace HermesSocketServer.Store
|
|||||||
protected override void OnInitialRemove(string key)
|
protected override void OnInitialRemove(string key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Save()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
string sql = string.Empty;
|
|
||||||
ImmutableList<string>? list = null;
|
|
||||||
|
|
||||||
if (_added.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _added.ToImmutableList();
|
|
||||||
_added.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedInsertSql("TtsVoice", count, ["id", "name"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Voice - Adding {count} rows to database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
}
|
|
||||||
if (_modified.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _modified.ToImmutableList();
|
|
||||||
_modified.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedUpdateSql("TtsVoice", count, ["id"], ["name"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Voice - Modifying {count} rows in database: {sql}");
|
|
||||||
var values = list.Select(id => _store[id]).Where(v => v != null);
|
|
||||||
await _generator.DoPreparedStatement(_database, sql, values, ["id", "name", "email", "role", "ttsDefaultVoice"]);
|
|
||||||
}
|
|
||||||
if (_deleted.Any())
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
list = _deleted.ToImmutableList();
|
|
||||||
_deleted.Clear();
|
|
||||||
}
|
|
||||||
count = list.Count;
|
|
||||||
sql = _generator.GeneratePreparedDeleteSql("TtsVoice", count, ["id"]);
|
|
||||||
|
|
||||||
_logger.Debug($"Voice - Deleting {count} rows from database: {sql}");
|
|
||||||
await _generator.DoPreparedStatementRaw(_database, sql, list, ["id"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user