2020-05-13 03:39:03 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO.Compression;
|
2020-07-16 21:17:37 +00:00
|
|
|
|
using System.Linq;
|
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
|
|
|
|
|
{
|
2021-02-04 03:48:30 +00:00
|
|
|
|
public class ModListDownloader : AbstractService<ModListDownloader, int>
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
2021-02-04 03:48:30 +00:00
|
|
|
|
public ModListDownloader(ILogger<ModListDownloader> logger, AppSettings settings, ArchiveMaintainer maintainer, SqlService sql, DiscordWebHook discord, QuickSync quickSync)
|
|
|
|
|
: base(logger, settings, quickSync, TimeSpan.FromMinutes(1))
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-02-04 03:48:30 +00:00
|
|
|
|
public override async Task<int> Execute()
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
2020-05-13 12:09:20 +00:00
|
|
|
|
int downloaded = 0;
|
2020-07-16 21:17:37 +00:00
|
|
|
|
var lists = (await ModlistMetadata.LoadFromGithub())
|
|
|
|
|
.Concat(await ModlistMetadata.LoadUnlistedFromGithub()).ToList();
|
|
|
|
|
|
2020-05-13 03:39:03 +00:00
|
|
|
|
foreach (var list in lists)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-02-04 03:48:30 +00:00
|
|
|
|
ReportStarting(list.Links.MachineURL);
|
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,
|
2021-02-04 03:48:30 +00:00
|
|
|
|
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-25 17:34:25 +00:00
|
|
|
|
await using (var fs = await 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,
|
2021-02-04 03:48:30 +00:00
|
|
|
|
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>();
|
|
|
|
|
}
|
2020-10-01 03:50:09 +00:00
|
|
|
|
catch (JsonReaderException)
|
2020-05-13 03:39:03 +00:00
|
|
|
|
{
|
2020-05-16 15:08:40 +00:00
|
|
|
|
_logger.LogWarning($"Bad Modlist {list.Links.MachineURL}");
|
|
|
|
|
await _discord.Send(Channel.Ham,
|
2021-02-04 03:48:30 +00:00
|
|
|
|
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,
|
2021-02-04 03:48:30 +00:00
|
|
|
|
new DiscordMessage
|
|
|
|
|
{
|
|
|
|
|
Content =
|
|
|
|
|
$"Error downloading modlist {list.Links.MachineURL} - {list.DownloadMetadata.Hash}"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
ReportEnding(list.Links.MachineURL);
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|