/
d.alekseev
/
SmartMenuBot
Обзор
Документация
Войти
/
d.alekseev
/
SmartMenuBot
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ConsoleBot/Infrastructure/DataAccess/FileUserRepository.cs
150 строк
5 KB
d.alekseev
feat: нотификации и фоновые задачи доставки уведомлений
26 фев 2026, 10:55
26 фев 2026, 10:55
4338916
Код
Авторство
О чём код?
using System.Text.Json; using SmartMenuBot.Core.DataAccess; using SmartMenuBot.Core.Entities; using SmartMenuBot.Infrastructure.DataAccess.StorageModels; namespace SmartMenuBot.Infrastructure.DataAccess { public class FileUserRepository : IUserRepository { private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true }; private readonly string _baseDirectoryPath; private readonly SemaphoreSlim _gate = new(1, 1); public FileUserRepository(string baseDirectoryPath) { if (string.IsNullOrWhiteSpace(baseDirectoryPath)) throw new ArgumentException("Базовый путь не может быть пустым", nameof(baseDirectoryPath)); _baseDirectoryPath = baseDirectoryPath; Directory.CreateDirectory(_baseDirectoryPath); } public async Task AddAsync(ToDoUser user, CancellationToken ct) { ArgumentNullException.ThrowIfNull(user); var stored = MapToStored(user); var json = JsonSerializer.Serialize(stored, JsonOptions); var path = GetUserFilePath(user.UserId); await _gate.WaitAsync(ct); try { await File.WriteAllTextAsync(path, json, ct); } finally { _gate.Release(); } } public async Task<ToDoUser?> GetUserAsync(Guid userId, CancellationToken ct) { var path = GetUserFilePath(userId); await _gate.WaitAsync(ct); try { if (!File.Exists(path)) return null; var json = await File.ReadAllTextAsync(path, ct); var stored = JsonSerializer.Deserialize<StoredToDoUser>(json); if (stored == null) return null; return MapToDomain(stored); } finally { _gate.Release(); } } public async Task<ToDoUser?> GetUserByTelegramUserIdAsync(long telegramUserId, CancellationToken ct) { await _gate.WaitAsync(ct); try { var files = Directory.GetFiles(_baseDirectoryPath, "*.json", SearchOption.TopDirectoryOnly); foreach (var file in files) { ct.ThrowIfCancellationRequested(); var json = await File.ReadAllTextAsync(file, ct); var stored = JsonSerializer.Deserialize<StoredToDoUser>(json); if (stored == null) continue; if (stored.TelegramUserId != telegramUserId) continue; return MapToDomain(stored); } return null; } finally { _gate.Release(); } } public async Task<IReadOnlyList<ToDoUser>> GetUsers(CancellationToken ct) { await _gate.WaitAsync(ct); try { var users = new List<ToDoUser>(); var files = Directory.GetFiles(_baseDirectoryPath, "*.json", SearchOption.TopDirectoryOnly); foreach (var file in files) { ct.ThrowIfCancellationRequested(); var json = await File.ReadAllTextAsync(file, ct); var stored = JsonSerializer.Deserialize<StoredToDoUser>(json); if (stored is null) continue; users.Add(MapToDomain(stored)); } return users.AsReadOnly(); } finally { _gate.Release(); } } private string GetUserFilePath(Guid userId) { return Path.Combine(_baseDirectoryPath, $"{userId}.json"); } private static StoredToDoUser MapToStored(ToDoUser user) { return new StoredToDoUser { UserId = user.UserId, TelegramUserId = user.TelegramUserId, TelegramUserName = user.TelegramUserName, RegisteredAt = user.RegisteredAt }; } private static ToDoUser MapToDomain(StoredToDoUser stored) { return ToDoUser.Restore( stored.UserId, stored.TelegramUserId, stored.TelegramUserName, stored.RegisteredAt); } } }