Skip to content

Commit

Permalink
Fixes performance regression in downloading
Browse files Browse the repository at this point in the history
Rollback to  Refit. The performance in downloading while using restsharp is incredibly
slow and falling back to refit solves the performance issue.

I may wrongly use restsharp though.
  • Loading branch information
fumiichan committed Apr 6, 2024
1 parent 56cb89a commit a3158d7
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 66 deletions.
17 changes: 17 additions & 0 deletions asuka.Provider.Nhentai/Api/IGalleryApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using asuka.Provider.Nhentai.Api.Requests;
using asuka.Provider.Nhentai.Contracts;
using Refit;

namespace asuka.Provider.Nhentai.Api;

internal interface IGalleryApi
{
[Get("/api/gallery/{code}")]
Task<GalleryResponse> FetchSingle(string code, CancellationToken cancellationToken = default);

[Get("/api/gallery/{code}/related")]
Task<GalleryListResponse> FetchRecommended(string code, CancellationToken cancellationToken = default);

[Get("/api/galleries/search")]
Task<GallerySearchResponse> SearchGallery(GallerySearchQuery queries, CancellationToken cancellationToken = default);
}
9 changes: 9 additions & 0 deletions asuka.Provider.Nhentai/Api/IGalleryImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Refit;

namespace asuka.Provider.Nhentai.Api;

internal interface IGalleryImage
{
[Get("/galleries/{mediaId}/{filename}")]
Task<HttpContent> GetImage(string mediaId, string filename, CancellationToken cancellationToken = default);
}
15 changes: 15 additions & 0 deletions asuka.Provider.Nhentai/Api/Requests/GallerySearchQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Refit;

namespace asuka.Provider.Nhentai.Api.Requests;

internal sealed class GallerySearchQuery
{
[AliasAs("query")]
public required string Queries { get; init; }

[AliasAs("page")]
public int PageNumber { get; init; }

[AliasAs("sort")]
public required string Sort { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static Series ToSeries(this GalleryResponse response)
return new Chapter.ChapterImages
{
ImageRemotePath = $"/galleries/{response.MediaId}/{pageNumber}{extension}",
ImageRemotePath = $"{response.MediaId},{pageNumber}{extension}",
Filename = filename
};
})
Expand Down
114 changes: 52 additions & 62 deletions asuka.Provider.Nhentai/Provider.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,42 @@
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.RegularExpressions;
using asuka.Provider.Nhentai.Contracts;
using asuka.Provider.Nhentai.Api;
using asuka.Provider.Nhentai.Api.Requests;
using asuka.Provider.Nhentai.Mappers;
using asuka.ProviderSdk;
using RestSharp;
using Refit;

namespace asuka.Provider.Nhentai;

public sealed partial class Provider : MetaInfo
{
private readonly RestClientOptions _clientOptions;
private readonly RestClientOptions _imageClientOptions;
private readonly IGalleryApi _gallery;
private readonly IGalleryImage _galleryImage;

public Provider()
{
Id = "asuka.provider.nhentai";
Version = new Version(1, 0, 0, 0);
Version = new Version(1, 1, 0, 0);
ProviderAliases =
[
"nh",
"nhentai"
];

// Configure request
_clientOptions = new RestClientOptions("https://nhentai.net/")
_gallery = RestService.For<IGalleryApi>(CreateHttpClient("https://nhentai.net/"), new RefitSettings
{
ThrowOnAnyError = true,
UserAgent = GetUserAgentFromFile() ?? $"asuka.Provider.Nhentai {Version.Major}.{Version.Minor}",
CookieContainer = new CookieContainer()
};

_imageClientOptions = new RestClientOptions("https://i.nhentai.net/")
{
ThrowOnAnyError = true,
UserAgent = GetUserAgentFromFile() ?? $"asuka.Provider.Nhentai {Version.Major}.{Version.Minor}",
CookieContainer = new CookieContainer()
};

// Read cookies from file and load them into RestClientOptions
foreach (var cookie in ReadCookiesFromFile())
{
_clientOptions.CookieContainer.Add(cookie);
_imageClientOptions.CookieContainer.Add(cookie);
}
ContentSerializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
})
});

_galleryImage = RestService.For<IGalleryImage>(CreateHttpClient("https://i.nhentai.net/"));
}

public override bool IsGallerySupported(string galleryId)
Expand All @@ -68,33 +60,20 @@ public override async Task<Series> GetSeries(string galleryId, CancellationToken
var code = codeRegex.Match(galleryId).Value;

// Request
var client = new RestClient(_clientOptions);
var request = new RestRequest($"/api/gallery/{code}");

var response = await client.GetAsync<GalleryResponse>(request, cancellationToken);
if (response == null)
{
throw new Exception("Failed to deserialize request.");
}
return response.ToSeries();
var request = await _gallery.FetchSingle(code, cancellationToken);
return request.ToSeries();
}

public override async Task<List<Series>> Search(SearchQuery query, CancellationToken cancellationToken = default)
{
var client = new RestClient(_clientOptions);
var request = new RestRequest("/api/galleries/search");

request.AddParameter("query", string.Join(" ", query.SearchQueries));
request.AddParameter("page", query.PageNumber);
request.AddParameter("sort", query.Sort);

var response = await client.GetAsync<GallerySearchResponse>(request, cancellationToken);
if (response?.Result == null)
var request = await _gallery.SearchGallery(new GallerySearchQuery
{
throw new Exception($"Unable to retrieve search results. Request URL: {client.BuildUri(request).ToString()}");
}
Queries = string.Join(" ", query.SearchQueries),
PageNumber = query.PageNumber,
Sort = query.Sort ?? "popularity"
}, cancellationToken);

return response.Result
return request.Result
.Select(x => x.ToSeries())
.ToList();
}
Expand All @@ -117,31 +96,22 @@ public override async Task<List<Series>> GetRecommendations(string galleryId, Ca
var codeRegex = CodeOnlyRegex();
var code = codeRegex.Match(galleryId).Value;

var client = new RestClient(_clientOptions);
var request = new RestRequest($"/api/gallery/{code}/related");

var response = await client.GetAsync<GalleryListResponse>(request, cancellationToken);
if (response == null)
{
throw new Exception("Unable to fetch recommendations");
}

return response.Result
var request = await _gallery.FetchRecommended(code, cancellationToken);
return request.Result
.Select(x => x.ToSeries())
.ToList();
}

public override async Task<byte[]> GetImage(string remotePath, CancellationToken cancellationToken = default)
{
var client = new RestClient(_imageClientOptions);
var request = new RestRequest(remotePath);

var data = await client.DownloadDataAsync(request, cancellationToken);
if (data == null)
var pathArguments = remotePath.Split(",");
if (pathArguments.Length != 2)
{
throw new Exception("Unable to download file.");
throw new Exception($"Unable to download due to malformed remote path. remotePath: {remotePath}");
}
return data;

var request = await _galleryImage.GetImage(pathArguments[0], pathArguments[1], cancellationToken);
return await request.ReadAsByteArrayAsync(cancellationToken);
}

/// <summary>
Expand Down Expand Up @@ -194,6 +164,26 @@ private static List<Cookie> ReadCookiesFromFile()
: [];
}

private HttpClient CreateHttpClient(string hostname)
{
var handler = new HttpClientHandler();

// Read cookies from file and load them into RestClientOptions
foreach (var cookie in ReadCookiesFromFile())
{
handler.CookieContainer.Add(cookie);
}

var httpClient = new HttpClient(handler)
{
BaseAddress = new Uri(hostname)
};
httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(
GetUserAgentFromFile() ?? $"asuka.Provider.Nhentai {Version.Major}.{Version.Minor}");

return httpClient;
}

[GeneratedRegex(@"^http(s)?:\/\/(nhentai\.net)\b([//g]*)\b([\d]{1,6})\/?$")]
private static partial Regex FullUrlRegex();

Expand Down
6 changes: 3 additions & 3 deletions asuka.Provider.Nhentai/asuka.Provider.Nhentai.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
<LangVersion>latestmajor</LangVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<IsPackable>false</IsPackable>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
<FileVersion>1.1.0.0</FileVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\asuka.ProviderSdk\asuka.ProviderSdk.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="Refit" Version="7.0.0" />
</ItemGroup>

</Project>

0 comments on commit a3158d7

Please sign in to comment.