2020-05-13 03:39:03 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO.Compression;
|
2020-05-13 12:09:20 +00:00
|
|
|
|
using System.Runtime.CompilerServices;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Wabbajack.BuildServer;
|
|
|
|
|
using Wabbajack.Common;
|
|
|
|
|
using Wabbajack.Lib;
|
|
|
|
|
using Wabbajack.Lib.Downloaders;
|
|
|
|
|
using Wabbajack.Lib.ModListRegistry;
|
|
|
|
|
using Wabbajack.Server.DataLayer;
|
2020-05-16 15:08:40 +00:00
|
|
|
|
using Wabbajack.Server.DTOs;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Server.Services
|
|
|
|
|
{
|
|
|
|
|
public class ModListDownloader
|
|
|
|
|
{
|
|
|
|
|
private ILogger<ModListDownloader> _logger;
|
|
|
|
|
private AppSettings _settings;
|
|
|
|
|
private ArchiveMaintainer _maintainer;
|
|
|
|
|
private SqlService _sql;
|
2020-05-16 15:08:40 +00:00
|
|
|
|
private DiscordWebHook _discord;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
|
2020-05-16 15:08:40 +00:00
|
|
|
|
public ModListDownloader(ILogger<ModListDownloader> logger, AppSettings settings, ArchiveMaintainer maintainer, SqlService sql, DiscordWebHook discord)
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_settings = settings;
|
|
|
|
|
_maintainer = maintainer;
|
|
|
|
|
_sql = sql;
|
2020-05-16 15:08:40 +00:00
|
|
|
|
_discord = discord;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
|
|
|
|
if (_settings.RunBackEndJobs)
|
|
|
|
|
{
|
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-05-13 12:09:20 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, "Checking for updated mod lists");
|
2020-05-13 03:39:03 +00:00
|
|
|
|
await CheckForNewLists();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "Error checking list");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Task.Delay(TimeSpan.FromMinutes(5));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 12:09:20 +00:00
|
|
|
|
public async Task<int> CheckForNewLists()
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
2020-05-13 12:09:20 +00:00
|
|
|
|
int downloaded = 0;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
var lists = await ModlistMetadata.LoadFromGithub();
|
|
|
|
|
foreach (var list in lists)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-05-13 12:09:20 +00:00
|
|
|
|
if (await _sql.HaveIndexedModlist(list.Links.MachineURL, list.DownloadMetadata.Hash))
|
2020-05-13 03:39:03 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
2020-05-13 12:09:20 +00:00
|
|
|
|
|
|
|
|
|
if (!_maintainer.HaveArchive(list.DownloadMetadata!.Hash))
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
2020-05-13 12:09:20 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, $"Downloading {list.Links.MachineURL}");
|
2020-05-16 15:08:40 +00:00
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Downloading {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"});
|
2020-05-13 12:09:20 +00:00
|
|
|
|
var tf = new TempFile();
|
|
|
|
|
var state = DownloadDispatcher.ResolveArchive(list.Links.Download);
|
|
|
|
|
if (state == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.Log(LogLevel.Error,
|
|
|
|
|
$"Now downloader found for list {list.Links.MachineURL} : {list.Links.Download}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
downloaded += 1;
|
|
|
|
|
await state.Download(new Archive(state) {Name = $"{list.Links.MachineURL}.wabbajack"}, tf.Path);
|
|
|
|
|
var hash = await tf.Path.FileHashAsync();
|
|
|
|
|
if (hash != list.DownloadMetadata.Hash)
|
|
|
|
|
{
|
|
|
|
|
_logger.Log(LogLevel.Error,
|
|
|
|
|
$"Downloaded modlist {list.Links.MachineURL} {list.DownloadMetadata.Hash} didn't match metadata hash of {hash}");
|
|
|
|
|
await _sql.IngestModList(list.DownloadMetadata.Hash, list, new ModList(), true);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await _maintainer.Ingest(tf.Path);
|
2020-05-13 03:39:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 12:09:20 +00:00
|
|
|
|
_maintainer.TryGetPath(list.DownloadMetadata.Hash, out var modlistPath);
|
2020-05-13 03:39:03 +00:00
|
|
|
|
ModList modlist;
|
2020-05-13 12:09:20 +00:00
|
|
|
|
await using (var fs = modlistPath.OpenRead())
|
2020-05-13 03:39:03 +00:00
|
|
|
|
using (var zip = new ZipArchive(fs, ZipArchiveMode.Read))
|
|
|
|
|
await using (var entry = zip.GetEntry("modlist")?.Open())
|
|
|
|
|
{
|
|
|
|
|
if (entry == null)
|
|
|
|
|
{
|
2020-05-16 15:08:40 +00:00
|
|
|
|
_logger.LogWarning($"Bad Modlist {list.Links.MachineURL}");
|
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"});
|
2020-05-13 03:39:03 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
modlist = entry.FromJson<ModList>();
|
|
|
|
|
}
|
|
|
|
|
catch (JsonReaderException ex)
|
|
|
|
|
{
|
2020-05-16 15:08:40 +00:00
|
|
|
|
_logger.LogWarning($"Bad Modlist {list.Links.MachineURL}");
|
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Bad Modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"});
|
2020-05-13 03:39:03 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 12:09:20 +00:00
|
|
|
|
await _sql.IngestModList(list.DownloadMetadata!.Hash, list, modlist, false);
|
2020-05-13 03:39:03 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, $"Error downloading modlist {list.Links.MachineURL}");
|
2020-05-16 15:08:40 +00:00
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Error downloading modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"});
|
2020-05-13 03:39:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-13 12:09:20 +00:00
|
|
|
|
_logger.Log(LogLevel.Information, $"Done checking modlists. Downloaded {downloaded} new lists");
|
2020-05-16 15:08:40 +00:00
|
|
|
|
if (downloaded > 0)
|
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Downloaded {downloaded} new lists"});
|
2020-05-14 04:08:27 +00:00
|
|
|
|
|
|
|
|
|
var fc = await _sql.EnqueueModListFilesForIndexing();
|
|
|
|
|
_logger.Log(LogLevel.Information, $"Enqueing {fc} files for downloading");
|
2020-05-16 15:08:40 +00:00
|
|
|
|
if (fc > 0)
|
|
|
|
|
await _discord.Send(Channel.Ham,
|
|
|
|
|
new DiscordMessage {Content = $"Enqueing {fc} files for downloading"});
|
2020-05-14 04:08:27 +00:00
|
|
|
|
|
2020-05-13 12:09:20 +00:00
|
|
|
|
return downloaded;
|
2020-05-13 03:39:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class ModListDownloaderExtensions
|
|
|
|
|
{
|
|
|
|
|
public static void UseModListDownloader(this IApplicationBuilder b)
|
|
|
|
|
{
|
|
|
|
|
var poll = (ModListDownloader)b.ApplicationServices.GetService(typeof(ModListDownloader));
|
|
|
|
|
poll.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|