Skip to content

Commit

Permalink
[v2] Add paged request for trending movies
Browse files Browse the repository at this point in the history
  • Loading branch information
henrikfroehling committed Aug 8, 2024
1 parent 7c2d26d commit c296f39
Show file tree
Hide file tree
Showing 32 changed files with 1,408 additions and 104 deletions.
45 changes: 45 additions & 0 deletions src/libs/Trakt.NET/Internal/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,50 @@ internal static class Json
}
};
}

internal static class ResponseHeaders
{
internal const string HEADER_PAGINATION_PAGE_KEY = "X-Pagination-Page";

internal const string HEADER_PAGINATION_LIMIT_KEY = "X-Pagination-Limit";

internal const string HEADER_PAGINATION_PAGE_COUNT_KEY = "X-Pagination-Page-Count";

internal const string HEADER_PAGINATION_ITEM_COUNT_KEY = "X-Pagination-Item-Count";

internal const string HEADER_TRENDING_USER_COUNT_KEY = "X-Trending-User-Count";

internal const string HEADER_SORT_BY_KEY = "X-Sort-By";

internal const string HEADER_SORT_HOW_KEY = "X-Sort-How";

internal const string HEADER_APPLIED_SORT_BY = "X-Applied-Sort-By";

internal const string HEADER_APPLIED_SORT_HOW = "X-Applied-Sort-How";

internal const string HEADER_STARTDATE_KEY = "X-Start-Date";

internal const string HEADER_ENDDATE_KEY = "X-End-Date";

internal const string HEADER_PRIVATE_USER_KEY = "X-Private-User";

internal const string HEADER_ITEM_ID = "X-Item-ID";

internal const string HEADER_ITEM_TYPE = "X-Item-Type";

internal const string HEADER_RATE_LIMIT = "X-RateLimit";

internal const string HEADER_RETRY_AFTER = "Retry-After";

internal const string HEADER_UPGRADE_URL = "X-Upgrade-URL";

internal const string HEADER_VIP_USER = "X-VIP-User";

internal const string HEADER_ACCOUNT_LIMIT = "X-Account-Limit";

internal const string HEADER_ACCOUNT_LOCKED = "X-Account-Locked";

internal const string HEADER_ACCOUNT_DEACTIVATED = "X-Account-Deactivated";
}
}
}
26 changes: 22 additions & 4 deletions src/libs/Trakt.NET/Internal/Extensions/StreamExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,37 @@ internal static class StreamExtensions
internal static async Task<TJsonObjectType?> ReadAsJsonAsync<TJsonObjectType>(this Stream stream,
CancellationToken cancellationToken = default) where TJsonObjectType : class
{
TJsonObjectType? jsonObjectType;
TJsonObjectType? value;

#if NET6_0_OR_GREATER
JsonSerializerContext jsonSerializerContext = JsonSerializerContextFactory.GetContext<TJsonObjectType>();

jsonObjectType = await JsonSerializer.DeserializeAsync(stream, typeof(TJsonObjectType),
value = await JsonSerializer.DeserializeAsync(stream, typeof(TJsonObjectType),
jsonSerializerContext, cancellationToken).ConfigureAwait(false) as TJsonObjectType;
#else
jsonObjectType = await JsonSerializer.DeserializeAsync<TJsonObjectType>(stream,
value = await JsonSerializer.DeserializeAsync<TJsonObjectType>(stream,
Constants.Json.JsonOptions, cancellationToken).ConfigureAwait(false);
#endif

return jsonObjectType;
return value;
}

internal static async Task<IReadOnlyList<TJsonObjectType>?> ReadAsJsonArrayAsync<TJsonObjectType>(this Stream stream,
CancellationToken cancellationToken = default) where TJsonObjectType : class
{
IReadOnlyList<TJsonObjectType>? values;

#if NET6_0_OR_GREATER
JsonSerializerContext jsonSerializerContext = JsonSerializerContextFactory.GetContext<TJsonObjectType>();

values = await JsonSerializer.DeserializeAsync(stream, typeof(IReadOnlyList<TJsonObjectType>),
jsonSerializerContext, cancellationToken).ConfigureAwait(false) as IReadOnlyList<TJsonObjectType>;
#else
values = await JsonSerializer.DeserializeAsync<IReadOnlyList<TJsonObjectType>>(stream,
Constants.Json.JsonOptions, cancellationToken).ConfigureAwait(false);
#endif

return values;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ internal static JsonSerializerContext GetContext<TJsonObjectType>()
{
typeof(TraktMovie),
typeof(TraktMovieIds),
typeof(TraktMovieMinimal)
typeof(TraktMovieMinimal),
typeof(TraktTrendingMovie)
});

private static readonly FrozenSet<Type> s_peopleJsonTypes = FrozenSet.ToFrozenSet(new[]
Expand Down Expand Up @@ -198,7 +199,8 @@ internal static JsonSerializerContext GetContext<TJsonObjectType>()
private static readonly HashSet<Type> s_movieJsonTypes = [
typeof(TraktMovie),
typeof(TraktMovieIds),
typeof(TraktMovieMinimal)
typeof(TraktMovieMinimal),
typeof(TraktTrendingMovie)
];

private static readonly HashSet<Type> s_peopleJsonTypes = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace TraktNET
[JsonSerializable(typeof(TraktMovie))]
[JsonSerializable(typeof(TraktMovieIds))]
[JsonSerializable(typeof(TraktMovieMinimal))]
[JsonSerializable(typeof(TraktTrendingMovie))]
[JsonSerializable(typeof(IReadOnlyList<TraktTrendingMovie>))]
public sealed partial class MoviesJsonSerializerContext : JsonSerializerContext
{
}
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Trakt.NET/Internal/Modules/BaseModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
{
public class BaseModule
{
internal readonly TraktContext _context;
protected readonly TraktContext _context;

internal BaseModule(TraktContext context)
protected BaseModule(TraktContext context)
{
ArgumentValidator.ThrowIfNull(context);
_context = context;
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Trakt.NET/Internal/Modules/TraktMoviesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private Task<TraktResponse<TraktMovie>> GetMovieImplAsync(string movieIdOrSlug,
ExtendedInfo = extendedInfo
};

return RequestHandler.ExecuteSingleItemRequestAsync<TraktMovie, MovieGetRequest>(_context, request, cancellationToken);
return RequestHandler.ExecuteSingleItemRequestAsync<TraktMovie>(_context, request, cancellationToken);
}
}
}
84 changes: 67 additions & 17 deletions src/libs/Trakt.NET/Internal/Requests/RequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,67 @@ namespace TraktNET
{
internal sealed partial class RequestHandler
{
internal static async Task<TraktResponse<TResponseContentType>> ExecuteSingleItemRequestAsync<TResponseContentType, TRequest>(
TraktContext context, TRequest request, CancellationToken cancellationToken = default)
where TRequest : RequestBase where TResponseContentType : class
internal static async Task<TraktResponse<TResponseContentType>> ExecuteSingleItemRequestAsync<TResponseContentType>(
TraktContext context, RequestBase request, CancellationToken cancellationToken = default)
where TResponseContentType : class
{
using RequestResponse response = await ExecuteRequestAsync(context, request, cancellationToken).ConfigureAwait(false);

TResponseContentType? responseContent =
await response.ResponseContentStream.ReadAsJsonAsync<TResponseContentType>(cancellationToken).ConfigureAwait(false);

return TraktResponse<TResponseContentType>.Create(response.ResponseMessage.StatusCode, responseContent,
response.TraktHeaders, response.ResponseMessage.Headers, response.ResponseMessage.Content.Headers);
}

internal static async Task<TraktPagedResponse<TResponseContentType>> ExecutePagedListRequestAsync<TResponseContentType>(
TraktContext context, RequestBase request, Func<uint?, uint?, RequestBase>? requestBuilder, CancellationToken cancellationToken = default)
where TResponseContentType : class
{
using RequestResponse response = await ExecuteRequestAsync(context, request, cancellationToken).ConfigureAwait(false);

IReadOnlyList<TResponseContentType>? responseContent =
await response.ResponseContentStream.ReadAsJsonArrayAsync<TResponseContentType>(cancellationToken).ConfigureAwait(false);

var pagedResponse = TraktPagedResponse<TResponseContentType>.Create(response.ResponseMessage.StatusCode, responseContent,
response.TraktHeaders, response.ResponseMessage.Headers, response.ResponseMessage.Content.Headers);

pagedResponse.Context = context;
pagedResponse.RequestBuilder = requestBuilder;

return pagedResponse;
}

private static async Task<RequestResponse> ExecuteRequestAsync(TraktContext context, RequestBase request,
CancellationToken cancellationToken = default)
{
request.Validate();
request.BuildUri();
AddRequestMessageHeaders(context, request);

HttpClient httpClient = context.GetHttpClient();
using HttpResponseMessage responseMessage =
await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);

HttpResponseMessage responseMessage = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead,
cancellationToken).ConfigureAwait(false);

TraktResponseHeaders traktHeaders = ParseTraktResponseHeaders(responseMessage.Headers);

if (!responseMessage.IsSuccessStatusCode)
{
await HandleErrorAsync(request, responseMessage, traktHeaders, false, cancellationToken);
await HandleErrorAsync(request, responseMessage, traktHeaders, false, cancellationToken).ConfigureAwait(false);
}

#if NET5_0_OR_GREATER
using Stream responseContentStream = await responseMessage.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#else
using Stream responseContentStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
#endif

TResponseContentType? responseContent =
await responseContentStream.ReadAsJsonAsync<TResponseContentType>(cancellationToken).ConfigureAwait(false);
Stream responseContentStream = await GetResponseContentStreamAsync(responseMessage, cancellationToken).ConfigureAwait(false);

return TraktResponse<TResponseContentType>.Create(responseMessage.StatusCode, responseContent,
traktHeaders, responseMessage.Headers, responseMessage.Content.Headers);
return new RequestResponse
{
ResponseMessage = responseMessage,
ResponseContentStream = responseContentStream,
TraktHeaders = traktHeaders
};
}

private static void AddRequestMessageHeaders<TRequest>(TraktContext context, TRequest request) where TRequest : RequestBase
private static void AddRequestMessageHeaders(TraktContext context, RequestBase request)
{
const string AuthenticationScheme = "Bearer";

Expand All @@ -58,5 +86,27 @@ private static void AddRequestMessageHeaders<TRequest>(TraktContext context, TRe

request.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationScheme, context.Authorization!.AccessToken ?? string.Empty);
}

private static Task<Stream> GetResponseContentStreamAsync(HttpResponseMessage responseMessage, CancellationToken cancellationToken = default)
#if NET5_0_OR_GREATER
=> responseMessage.Content.ReadAsStreamAsync(cancellationToken);
#else
=> responseMessage.Content.ReadAsStreamAsync();
#endif
}

internal readonly struct RequestResponse : IDisposable
{
internal HttpResponseMessage ResponseMessage { get; init; }

internal Stream ResponseContentStream { get; init; }

internal TraktResponseHeaders TraktHeaders { get; init; }

public readonly void Dispose()
{
ResponseMessage.Dispose();
ResponseContentStream.Dispose();
}
}
}
Loading

0 comments on commit c296f39

Please sign in to comment.