using DotBased.Monads; using Manager.App.Models.Library; using Manager.App.Models.Settings; using Manager.Data.Contexts; using Manager.Data.Entities.LibraryContext; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace Manager.App.Services; public class LibraryService : ILibraryService { private readonly ILogger _logger; private readonly LibrarySettings _librarySettings; private readonly IDbContextFactory _dbContextFactory; private readonly DirectoryInfo _libraryDirectory; private const string SubDirMedia = "Media"; private const string SubDirChannels = "Channels"; public LibraryService(ILogger logger, IOptions librarySettings, IDbContextFactory contextFactory) { _logger = logger; _librarySettings = librarySettings.Value; _dbContextFactory = contextFactory; _libraryDirectory = Directory.CreateDirectory(_librarySettings.Path); logger.LogDebug("Working dir for library: {LibraryWorkingDir}", _libraryDirectory.FullName); Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirMedia)); Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirChannels)); } public async Task> GetLibraryInfoAsync(CancellationToken cancellationToken = default) { try { await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken); var libInfo = new LibraryInformation { LibraryPath = _libraryDirectory.FullName, CreatedAtUtc = _libraryDirectory.CreationTimeUtc, LastModifiedUtc = _libraryDirectory.LastWriteTimeUtc, TotalChannels = await context.Channels.CountAsync(cancellationToken: cancellationToken), TotalMedia = await context.Media.CountAsync(cancellationToken: cancellationToken), TotalSizeBytes = GetDirectorySize(_libraryDirectory) }; return libInfo; } catch (Exception e) { return HandleException(e); } } public async Task>> GetAccountsAsync(int total = 20, int offset = 0, CancellationToken cancellationToken = default) { try { await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken); var orderedAccounts = context.Channels.Include(x => x.ClientAccount).Where(x => x.ClientAccount != null).OrderBy(x => x.Id).Skip(offset).Take(total); return orderedAccounts.ToList(); } catch (Exception e) { return HandleException(e); } } private long GetDirectorySize(DirectoryInfo dir) { try { var size = dir.EnumerateFiles("*", SearchOption.AllDirectories).Select(f => f.Length).Sum(); return size; } catch (Exception e) { _logger.LogError(e, "Error while getting directory size."); throw; } } private ResultError HandleException(Exception exception) { if (exception is OperationCanceledException) { return ResultError.Fail("Library service operation cancelled"); } _logger.LogError(exception, "Failed to get library information"); return ResultError.Fail("Failed to get library information"); } }