2020-05-09 03:56:06 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Wabbajack.BuildServer;
|
|
|
|
|
using Wabbajack.Common;
|
|
|
|
|
using Wabbajack.Lib.NexusApi;
|
|
|
|
|
using Wabbajack.Server.DataLayer;
|
|
|
|
|
using Wabbajack.Server.DTOs;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Server.Services
|
|
|
|
|
{
|
|
|
|
|
public class NexusPoll
|
|
|
|
|
{
|
|
|
|
|
private SqlService _sql;
|
|
|
|
|
private AppSettings _settings;
|
|
|
|
|
private GlobalInformation _globalInformation;
|
|
|
|
|
private ILogger<NexusPoll> _logger;
|
|
|
|
|
|
|
|
|
|
public NexusPoll(ILogger<NexusPoll> logger, AppSettings settings, SqlService service, GlobalInformation globalInformation)
|
|
|
|
|
{
|
|
|
|
|
_sql = service;
|
|
|
|
|
_settings = settings;
|
|
|
|
|
_globalInformation = globalInformation;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task UpdateNexusCacheRSS()
|
|
|
|
|
{
|
|
|
|
|
using var _ = _logger.BeginScope("Nexus Update via RSS");
|
|
|
|
|
_logger.Log(LogLevel.Information, "Starting");
|
|
|
|
|
|
|
|
|
|
var results = await NexusUpdatesFeeds.GetUpdates();
|
|
|
|
|
NexusApiClient client = null;
|
|
|
|
|
long updated = 0;
|
|
|
|
|
foreach (var result in results)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var purgedMods =
|
|
|
|
|
await _sql.DeleteNexusModFilesUpdatedBeforeDate(result.Game, result.ModId, result.TimeStamp);
|
|
|
|
|
var purgedFiles =
|
|
|
|
|
await _sql.DeleteNexusModInfosUpdatedBeforeDate(result.Game, result.ModId, result.TimeStamp);
|
|
|
|
|
|
|
|
|
|
var totalPurged = purgedFiles + purgedMods;
|
|
|
|
|
if (totalPurged > 0)
|
2020-05-09 13:04:38 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, $"Purged {totalPurged} cache items {result.Game} {result.ModId} {result.TimeStamp}");
|
2020-05-09 03:56:06 +00:00
|
|
|
|
|
2020-05-15 05:25:02 +00:00
|
|
|
|
updated += totalPurged;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, $"Failed Nexus update for {result.Game} - {result.ModId} - {result.TimeStamp}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (updated > 0)
|
2020-05-15 05:25:02 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, $"RSS Purged {updated} nexus cache entries");
|
2020-05-09 03:56:06 +00:00
|
|
|
|
|
|
|
|
|
_globalInformation.LastNexusSyncUTC = DateTime.UtcNow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task UpdateNexusCacheAPI()
|
|
|
|
|
{
|
|
|
|
|
using var _ = _logger.BeginScope("Nexus Update via API");
|
2020-05-20 03:25:41 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, "Starting Nexus Update via API");
|
2020-05-09 03:56:06 +00:00
|
|
|
|
var api = await NexusApiClient.Get();
|
|
|
|
|
|
|
|
|
|
var gameTasks = GameRegistry.Games.Values
|
|
|
|
|
.Where(game => game.NexusName != null)
|
|
|
|
|
.Select(async game =>
|
|
|
|
|
{
|
|
|
|
|
var mods = await api.Get<List<NexusUpdateEntry>>(
|
|
|
|
|
$"https://api.nexusmods.com/v1/games/{game.NexusName}/mods/updated.json?period=1m");
|
|
|
|
|
|
|
|
|
|
return (game, mods);
|
|
|
|
|
})
|
|
|
|
|
.Select(async rTask =>
|
|
|
|
|
{
|
|
|
|
|
var (game, mods) = await rTask;
|
|
|
|
|
return mods.Select(mod => new { game = game, mod = mod });
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
_logger.Log(LogLevel.Information, $"Getting update list for {gameTasks.Count} games");
|
|
|
|
|
|
|
|
|
|
var purge = (await Task.WhenAll(gameTasks))
|
|
|
|
|
.SelectMany(i => i)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
_logger.Log(LogLevel.Information, $"Found {purge.Count} updated mods in the last month");
|
|
|
|
|
using var queue = new WorkQueue();
|
|
|
|
|
var collected = purge.Select(d =>
|
|
|
|
|
{
|
|
|
|
|
var a = d.mod.LatestFileUpdate.AsUnixTime();
|
|
|
|
|
// Mod activity could hide files
|
|
|
|
|
var b = d.mod.LastestModActivity.AsUnixTime();
|
|
|
|
|
|
2020-05-16 15:08:40 +00:00
|
|
|
|
return new {Game = d.game.Game, Date = (a > b) ? a : b, ModId = d.mod.ModId};
|
2020-05-09 03:56:06 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var purged = await collected.PMap(queue, async t =>
|
|
|
|
|
{
|
2020-05-16 15:08:40 +00:00
|
|
|
|
long purgeCount = 0;
|
|
|
|
|
purgeCount += await _sql.DeleteNexusModInfosUpdatedBeforeDate(t.Game, t.ModId, t.Date);
|
|
|
|
|
purgeCount += await _sql.DeleteNexusModFilesUpdatedBeforeDate(t.Game, t.ModId, t.Date);
|
|
|
|
|
return purgeCount;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
_logger.Log(LogLevel.Information, $"Purged {purged.Sum()} cache entries");
|
2020-05-09 22:16:16 +00:00
|
|
|
|
_globalInformation.LastNexusSyncUTC = DateTime.UtcNow;
|
|
|
|
|
|
2020-05-09 03:56:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
2020-05-09 13:04:38 +00:00
|
|
|
|
if (!_settings.RunBackEndJobs) return;
|
2020-05-20 03:25:41 +00:00
|
|
|
|
/*
|
2020-05-09 03:56:06 +00:00
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await UpdateNexusCacheRSS();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "Error polling from Nexus");
|
|
|
|
|
}
|
|
|
|
|
await Task.Delay(_globalInformation.NexusRSSPollRate);
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-05-20 03:25:41 +00:00
|
|
|
|
*/
|
2020-05-09 03:56:06 +00:00
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await UpdateNexusCacheAPI();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "Error getting API feed from Nexus");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Task.Delay(_globalInformation.NexusAPIPollRate);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class NexusPollExtensions
|
|
|
|
|
{
|
|
|
|
|
public static void UseNexusPoll(this IApplicationBuilder b)
|
|
|
|
|
{
|
|
|
|
|
var poll = (NexusPoll)b.ApplicationServices.GetService(typeof(NexusPoll));
|
|
|
|
|
poll.Start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|