Merge pull request #1167 from wabbajack-tools/rework-nexus-network-limits

Rework how we handle API limits.
This commit is contained in:
Timothy Baldridge 2020-11-05 15:41:12 -07:00 committed by GitHub
commit a7349f9d5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 28 deletions

View File

@ -195,6 +195,12 @@ namespace Wabbajack.Lib
await Task.WhenAll(dispatchers.Select(d => d.Prepare()));
var nexusDownloader = dispatchers.OfType<NexusDownloader>().FirstOrDefault();
if (nexusDownloader != null && !await nexusDownloader.HaveEnoughAPICalls(missing))
{
throw new Exception($"Not enough Nexus API calls to download this list, please try again after midnight GMT when your API limits reset");
}
await DownloadMissingArchives(missing);
}
@ -210,6 +216,7 @@ namespace Wabbajack.Lib
}
DesiredThreads.OnNext(DownloadThreads);
await missing.Where(a => a.State.GetType() != typeof(ManualDownloader.State))
.PMap(Queue, UpdateTracker, async archive =>
{

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reactive;
@ -142,6 +143,16 @@ namespace Wabbajack.Lib.Downloaders
}
}
public async Task<bool> HaveEnoughAPICalls(IEnumerable<Archive> archives)
{
if (await Client!.IsPremium())
return true;
var count = archives.Select(a => a.State).OfType<State>().Count();
return count < Client!.RemainingAPICalls;
}
[JsonName("NexusDownloader")]
public class State : AbstractDownloadState, IMetaState, IUpgradingState
{
@ -191,12 +202,9 @@ namespace Wabbajack.Lib.Downloaders
}
catch (Exception ex)
{
Utils.Log($"{a.Name} - Error getting Nexus download URL - {ex.Message}");
return false;
}
Utils.Log($"Downloading Nexus Archive - {a.Name} - {Game} - {ModID} - {FileID}");
return await new HTTPDownloader.State(url).Download(a, destination);
}

View File

@ -13,5 +13,7 @@ namespace Wabbajack.Lib.NexusApi
public Task<UserStatus> GetUserStatus();
public Task<bool> IsPremium();
public bool IsAuthenticated { get; }
public int RemainingAPICalls { get; }
}
}

View File

@ -27,6 +27,7 @@ namespace Wabbajack.Lib.NexusApi
public static string? ApiKey { get; set; }
public bool IsAuthenticated => ApiKey != null;
public int RemainingAPICalls => Math.Max(HourlyRemaining, DailyRemaining);
private Task<UserStatus>? _userStatus;
public Task<UserStatus> UserStatus
@ -213,24 +214,12 @@ namespace Wabbajack.Lib.NexusApi
}
protected virtual async Task UpdateRemaining(HttpResponseMessage response)
{
try
{
var oldDaily = _dailyRemaining;
var oldHourly = _hourlyRemaining;
var dailyRemaining = int.Parse(response.Headers.GetValues("x-rl-daily-remaining").First());
var hourlyRemaining = int.Parse(response.Headers.GetValues("x-rl-hourly-remaining").First());
lock (RemainingLock)
{
_dailyRemaining = Math.Min(_dailyRemaining, dailyRemaining);
_hourlyRemaining = Math.Min(_hourlyRemaining, hourlyRemaining);
}
if (oldDaily != _dailyRemaining || oldHourly != _hourlyRemaining)
Utils.Log($"Nexus requests remaining: {_dailyRemaining} daily - {_hourlyRemaining} hourly");
_dailyRemaining = int.Parse(response.Headers.GetValues("x-rl-daily-remaining").First());
_hourlyRemaining = int.Parse(response.Headers.GetValues("x-rl-hourly-remaining").First());
this.RaisePropertyChanged(nameof(DailyRemaining));
this.RaisePropertyChanged(nameof(HourlyRemaining));
@ -317,20 +306,17 @@ namespace Wabbajack.Lib.NexusApi
var info = await GetModInfo(archive.Game, archive.ModID);
if (!info.available)
throw new Exception("Mod unavailable");
var url = $"https://api.nexusmods.com/v1/games/{archive.Game.MetaData().NexusName}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";
try
{
return (await Get<List<DownloadLink>>(url)).First().URI;
}
catch (HttpException ex)
{
if (ex.Code != 403 || await IsPremium())
if (await IsPremium())
{
if (HourlyRemaining <= 0 && DailyRemaining <= 0)
{
throw;
throw new Exception($"You have run out of Nexus API requests, please try again after midnight GMT when the API limits reset");
}
var url =
$"https://api.nexusmods.com/v1/games/{archive.Game.MetaData().NexusName}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";
return (await Get<List<DownloadLink>>(url)).First().URI;
}
try