12
12
using Microsoft . Extensions . Logging ;
13
13
using Modrinth . RestClient ;
14
14
using Modrinth . RestClient . Models ;
15
- using RestEase ;
16
15
using Asterion . Extensions ;
16
+ using Flurl . Http ;
17
17
using Version = Modrinth . RestClient . Models . Version ;
18
18
using Timer = System . Timers . Timer ;
19
19
@@ -22,7 +22,7 @@ namespace Asterion.Services.Modrinth;
22
22
public partial class ModrinthService
23
23
{
24
24
private readonly BackgroundWorker _updateWorker ;
25
- private readonly IModrinthApi _api ;
25
+ private readonly IModrinthClient _api ;
26
26
private readonly ILogger _logger ;
27
27
private readonly IMemoryCache _cache ;
28
28
private readonly MemoryCacheEntryOptions _cacheEntryOptions ;
@@ -33,7 +33,7 @@ public partial class ModrinthService
33
33
public ModrinthService ( IServiceProvider serviceProvider , IHttpClientFactory httpClientFactory )
34
34
{
35
35
_httpClientFactory = httpClientFactory ;
36
- _api = ModrinthApi . NewClient ( userAgent : "Asterion" ) ;
36
+ _api = new ModrinthClient ( userAgent : "Zechiax/ Asterion" ) ;
37
37
_logger = serviceProvider . GetRequiredService < ILogger < ModrinthService > > ( ) ;
38
38
_cache = serviceProvider . GetRequiredService < IMemoryCache > ( ) ;
39
39
_dataService = serviceProvider . GetRequiredService < IDataService > ( ) ;
@@ -87,17 +87,35 @@ private async void CheckUpdates(object? sender, DoWorkEventArgs e)
87
87
88
88
var versions = apiProjects . SelectMany ( p => p . Versions ) . ToArray ( ) ;
89
89
90
+
91
+ const int splitBy = 500 ;
90
92
_logger . LogDebug ( "Getting multiple versions ({Count}) from Modrinth" , versions . Length ) ;
91
93
92
- var apiVersions = await GetMultipleVersionsAsync ( versions ) ;
93
-
94
- if ( apiVersions is null )
94
+ // Make multiple requests to get all versions - we don't want to get 1500+ versions in one request
95
+ // We make sure to split the requests into chunks of 500 versions
96
+ var apiVersions = new List < Version > ( ) ;
97
+ // Split the array into chunks of 500, we use ArraySegment
98
+ var versionChunks = System . Array . Empty < ArraySegment < string > > ( ) ;
99
+
100
+ for ( var i = 0 ; i < versions . Length ; i += splitBy )
95
101
{
96
- _logger . LogWarning ( "Could not get information from API, update search interrupted" ) ;
97
- return ;
102
+ _logger . LogDebug ( "Appending versions {Start} to {End}" , i , Math . Min ( splitBy , versions . Length - i ) ) ;
103
+ versionChunks = versionChunks . Append ( new ArraySegment < string > ( versions , i , Math . Min ( splitBy , versions . Length - i ) ) ) . ToArray ( ) ;
104
+ }
105
+
106
+ foreach ( var chunk in versionChunks )
107
+ {
108
+ _logger . LogDebug ( "Getting versions {Start} to {End}" , chunk . Offset , chunk . Offset + chunk . Count ) ;
109
+ var versionsChunk = await GetMultipleVersionsAsync ( chunk ) ;
110
+ if ( versionsChunk is null )
111
+ {
112
+ _logger . LogWarning ( "Could not get information from API, update search interrupted" ) ;
113
+ return ;
114
+ }
115
+ apiVersions . AddRange ( versionsChunk ) ;
98
116
}
99
117
100
- _logger . LogDebug ( "Got {Count} versions" , apiVersions . Length ) ;
118
+ _logger . LogDebug ( "Got {Count} versions" , apiVersions . Count ) ;
101
119
102
120
foreach ( var project in apiProjects )
103
121
{
@@ -270,14 +288,14 @@ public async Task<SearchResult<ProjectDto>> FindProject(string query)
270
288
var projectFoundById = false ;
271
289
try
272
290
{
273
- project = await _api . GetProjectAsync ( query ) ;
291
+ project = await _api . Project . GetAsync ( query ) ;
274
292
275
- searchResponse = await _api . SearchProjectsAsync ( query ) ;
293
+ searchResponse = await _api . Project . SearchAsync ( query ) ;
276
294
// Won't be set if exception is thrown
277
295
projectFoundById = true ;
278
296
}
279
297
// Not found status code is returned when requested project was not found
280
- catch ( ApiException e ) when ( e . StatusCode == HttpStatusCode . NotFound )
298
+ catch ( FlurlHttpException e ) when ( e . Call . Response . ResponseMessage . StatusCode == HttpStatusCode . NotFound )
281
299
{
282
300
// Project not found by slug or id
283
301
_logger . LogDebug ( "Project query '{Query}' not found with ID or slug" , query ) ;
@@ -304,7 +322,7 @@ public async Task<SearchResult<ProjectDto>> FindProject(string query)
304
322
305
323
try
306
324
{
307
- searchResponse = await _api . SearchProjectsAsync ( query ) ;
325
+ searchResponse = await _api . Project . SearchAsync ( query ) ;
308
326
309
327
// No search results
310
328
if ( searchResponse . TotalHits <= 0 )
@@ -313,7 +331,7 @@ public async Task<SearchResult<ProjectDto>> FindProject(string query)
313
331
}
314
332
315
333
// Return first result
316
- project = await _api . GetProjectAsync ( searchResponse . Hits [ 0 ] . ProjectId ) ;
334
+ project = await _api . Project . GetAsync ( searchResponse . Hits [ 0 ] . ProjectId ) ;
317
335
318
336
var result = new SearchResult < ProjectDto > ( new ProjectDto
319
337
{
@@ -354,10 +372,10 @@ public async Task<SearchResult<UserDto>> FindUser(string query)
354
372
355
373
try
356
374
{
357
- user = await _api . GetUserAsync ( query ) ;
375
+ user = await _api . User . GetAsync ( query ) ;
358
376
_logger . LogDebug ( "User query '{Query}' found" , query ) ;
359
377
}
360
- catch ( ApiException e ) when ( e . StatusCode == HttpStatusCode . NotFound )
378
+ catch ( FlurlHttpException e ) when ( e . Call . Response . ResponseMessage . StatusCode == HttpStatusCode . NotFound )
361
379
{
362
380
// Project not found by slug or id
363
381
_logger . LogDebug ( "User not found '{Query}'" , query ) ;
@@ -371,7 +389,7 @@ public async Task<SearchResult<UserDto>> FindUser(string query)
371
389
// User can't be null from here
372
390
try
373
391
{
374
- var projects = await _api . GetUsersProjectsByUserIdAsync ( user . Id ) ;
392
+ var projects = await _api . User . GetProjectsAsync ( user . Id ) ;
375
393
376
394
var searchResult = new SearchResult < UserDto > ( new UserDto
377
395
{
0 commit comments