using IF.Lastfm.Core.Api; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Quartz; using Selector.Model; using Selector.Model.Extensions; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Selector.CLI.Jobs { [DisallowConcurrentExecution] public class ScrobbleWatcherJob : IJob { private readonly ILogger logger; private readonly ILoggerFactory loggerFactory; private readonly IUserApi userApi; private readonly IScrobbleRepository scrobbleRepo; private readonly ApplicationDbContext db; private readonly ScrobbleWatcherJobOptions options; private static object databaseLock = new(); public bool IsFull { get; set; } public ScrobbleWatcherJob( IUserApi _userApi, IScrobbleRepository _scrobbleRepo, ApplicationDbContext _db, IOptions _options, ILogger _logger, ILoggerFactory _loggerFactory) { logger = _logger; loggerFactory = _loggerFactory; userApi = _userApi; scrobbleRepo = _scrobbleRepo; db = _db; options = _options.Value; } public async Task Execute(IJobExecutionContext context) { try { logger.LogInformation("Starting scrobble watching job"); var users = db.Users .AsEnumerable() .Where(u => u.ScrobbleSavingEnabled()) .ToArray(); foreach (var user in users) { logger.LogInformation("Saving scrobbles for {}/{}", user.UserName, user.LastFmUsername); DateTime? from = null; if (options.From is not null && !IsFull) { from = options.From.Value.ToUniversalTime(); } var saver = new ScrobbleSaver( userApi, new() { User = user, InterRequestDelay = options.InterRequestDelay, From = from, PageSize = options.PageSize, DontAdd = false, DontRemove = false, SimultaneousConnections = options.Simultaneous }, scrobbleRepo, loggerFactory.CreateLogger(), loggerFactory, databaseLock); await saver.Execute(context.CancellationToken); logger.LogInformation("Finished scrobbles for {}/{}", user.UserName, user.LastFmUsername); } } catch (Exception ex) { logger.LogError(ex, "Error occured while saving scrobbles"); } } } }