/
d.alekseev
/
SmartMenuBot
Обзор
Документация
Войти
/
d.alekseev
/
SmartMenuBot
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ConsoleBot/Infrastructure/DataAccess/FileToDoListRepository.cs
208 строк
7 KB
d.alekseev
feat: списки задач, callback-сценарии и рефактор маршрутизации UpdateHandler
13 фев 2026, 17:30
13 фев 2026, 17:30
a225948
Код
Авторство
О чём код?
using System.Text.Json; using SmartMenuBot.Core.DataAccess; using SmartMenuBot.Core.Entities; using SmartMenuBot.Infrastructure.DataAccess.StorageModels; namespace SmartMenuBot.Infrastructure.DataAccess { public class FileToDoListRepository : IToDoListRepository { private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true }; private readonly string _baseDirectoryPath; private readonly SemaphoreSlim _gate = new(1, 1); public FileToDoListRepository(string baseDirectoryPath) { if (string.IsNullOrWhiteSpace(baseDirectoryPath)) throw new ArgumentException("Базовый путь не может быть пустым", nameof(baseDirectoryPath)); _baseDirectoryPath = baseDirectoryPath; Directory.CreateDirectory(_baseDirectoryPath); } public async Task AddAsync(ToDoList list, CancellationToken ct) { ArgumentNullException.ThrowIfNull(list); var stored = MapToStored(list); var path = GetListFilePath(list.User.UserId, list.Id); Directory.CreateDirectory(GetUserDirectoryPath(list.User.UserId)); var json = JsonSerializer.Serialize(stored, JsonOptions); await _gate.WaitAsync(ct); try { await File.WriteAllTextAsync(path, json, ct); } finally { _gate.Release(); } } public async Task<ToDoList?> GetAsync(Guid id, CancellationToken ct) { await _gate.WaitAsync(ct); try { var path = FindListFilePathByIdLocked(id); if (path is null || !File.Exists(path)) return null; var json = await File.ReadAllTextAsync(path, ct); var stored = JsonSerializer.Deserialize<StoredToDoList>(json, JsonOptions); if (stored is null) return null; return MapToDomain(stored); } finally { _gate.Release(); } } public async Task<IReadOnlyList<ToDoList>> GetByUserIdAsync(Guid userId, CancellationToken ct) { await _gate.WaitAsync(ct); try { var userDirectoryPath = GetUserDirectoryPath(userId); if (!Directory.Exists(userDirectoryPath)) return Array.Empty<ToDoList>(); var result = new List<ToDoList>(); var files = Directory.GetFiles(userDirectoryPath, "*.json", SearchOption.TopDirectoryOnly); foreach (var file in files) { ct.ThrowIfCancellationRequested(); var json = await File.ReadAllTextAsync(file, ct); var stored = JsonSerializer.Deserialize<StoredToDoList>(json, JsonOptions); if (stored is null) continue; result.Add(MapToDomain(stored)); } return result.AsReadOnly(); } finally { _gate.Release(); } } public async Task DeleteAsync(Guid id, CancellationToken ct) { await _gate.WaitAsync(ct); try { var path = FindListFilePathByIdLocked(id); if (path is null || !File.Exists(path)) return; File.Delete(path); } finally { _gate.Release(); } } public async Task<bool> ExistsByNameAsync(Guid userId, string name, CancellationToken ct) { await _gate.WaitAsync(ct); try { var userDirectoryPath = GetUserDirectoryPath(userId); if (!Directory.Exists(userDirectoryPath)) return false; var files = Directory.GetFiles(userDirectoryPath, "*.json", SearchOption.TopDirectoryOnly); foreach (var file in files) { ct.ThrowIfCancellationRequested(); var json = await File.ReadAllTextAsync(file, ct); var stored = JsonSerializer.Deserialize<StoredToDoList>(json, JsonOptions); if (stored is null) continue; if (stored.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) return true; } return false; } finally { _gate.Release(); } } private string GetUserDirectoryPath(Guid userId) { return Path.Combine(_baseDirectoryPath, userId.ToString()); } private string GetListFilePath(Guid userId, Guid listId) { return Path.Combine(GetUserDirectoryPath(userId), $"{listId}.json"); } private string? FindListFilePathByIdLocked(Guid listId) { if (!Directory.Exists(_baseDirectoryPath)) return null; var userDirectories = Directory.GetDirectories(_baseDirectoryPath, "*", SearchOption.TopDirectoryOnly); foreach (var userDirectory in userDirectories) { var userDirectoryName = Path.GetFileName(userDirectory); if (!Guid.TryParse(userDirectoryName, out _)) continue; var candidatePath = Path.Combine(userDirectory, $"{listId}.json"); if (File.Exists(candidatePath)) return candidatePath; } return null; } private static StoredToDoList MapToStored(ToDoList list) { return new StoredToDoList { Id = list.Id, Name = list.Name, CreatedAt = list.CreatedAt, UserId = list.User.UserId, UserTelegramUserId = list.User.TelegramUserId, UserTelegramUserName = list.User.TelegramUserName, UserRegisteredAt = list.User.RegisteredAt }; } private static ToDoList MapToDomain(StoredToDoList stored) { var user = ToDoUser.Restore( stored.UserId, stored.UserTelegramUserId, stored.UserTelegramUserName, stored.UserRegisteredAt); return ToDoList.Restore( stored.Id, stored.Name, user, stored.CreatedAt); } } }