Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media Reviews #11

Merged
merged 7 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/AniListNet.Tests/MediaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public async Task GetMediaRecommendationTest()
Console.WriteLine(ObjectDumper.Dump(data));
Assert.Pass();
}

[Test]
public async Task GetMediaReviewTest()
{
var data = await TestObjects.AniClient.GetMediaReviewsAsync(1);
Console.WriteLine(ObjectDumper.Dump(data));
Assert.Pass();
}

[Test]
public async Task GetMediaEntryTest() // TODO: needs improvement
Expand Down
30 changes: 30 additions & 0 deletions src/AniListNet/AniClient.Media.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AniListNet.Helpers;
using AniListNet.Objects;
using AniListNet.Parameters;

namespace AniListNet;

Expand Down Expand Up @@ -115,6 +116,35 @@ public async Task<AniPagination<MediaRecommendationEdge>> GetMediaRecommendation
response["Media"]["recommendations"]["edges"].ToObject<MediaRecommendationEdge[]>()
);
}

/// <summary>
/// Gets Reviews associated with a given Media.
/// </summary>
/// <param name="mediaId"></param>
/// <param name="filter"></param>
/// <param name="paginationOptions"></param>
/// <returns></returns>
public async Task<AniPagination<MediaReviewEdge>> GetMediaReviewsAsync(int mediaId, MediaReviewFilter? filter = null, AniPaginationOptions? paginationOptions = null)
{
filter ??= new MediaReviewFilter();
paginationOptions ??= new AniPaginationOptions();
var selections = new GqlSelection("Media", new GqlSelection[]
{
new("reviews", new GqlSelection[]
{
new("pageInfo", typeof(PageInfo).ToSelections()),
new("edges", typeof(MediaReviewEdge).ToSelections(), filter.ToParameters().ToArray())
}, paginationOptions.ToParameters())
}, new GqlParameter[]
{
new("id", mediaId)
});
var response = await PostRequestAsync(selections);
return new AniPagination<MediaReviewEdge>(
response["Media"]["reviews"]["pageInfo"].ToObject<PageInfo>(),
response["Media"]["reviews"]["edges"].ToObject<MediaReviewEdge[]>()
);
}

/* below is properties specific for the authenticated user */

Expand Down
6 changes: 3 additions & 3 deletions src/AniListNet/Objects/Media/MediaCover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ public class MediaCover : Image
[JsonProperty("color")] private readonly string? _color;

/// <summary>
/// The cover image url of the media at medium size.
/// The cover image URL of the media at medium size.
/// </summary>
[JsonProperty("medium")] public Uri MediumImageUrl { get; private set; }
/// <summary>
/// The cover image url of the media at large size.
/// The cover image URL of the media at large size.
/// </summary>
[JsonProperty("large")] public Uri LargeImageUrl { get; private set; }
/// <summary>
/// The cover image url of the media at its largest size. If this size isn't available, large will be provided instead.
/// The cover image URL of the media at its largest size. If this size isn't available, large will be provided instead.
/// </summary>
[JsonProperty("extraLarge")] public Uri ExtraLargeImageUrl { get; private set; }
/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/AniListNet/Objects/Media/MediaSort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public enum MediaSort
[EnumMember(Value = "FAVOURITES")] Favorites,
[EnumMember(Value = "TYPE")] Type,
[EnumMember(Value = "FORMAT")] Format,
[EnumMember(Value = "STATUS")] Status,
// TODO: Update with more sort options: https://anilist.github.io/ApiV2-GraphQL-Docs/
[EnumMember(Value = "STATUS")] Status
// TODO: update with more sort options: https://anilist.github.io/ApiV2-GraphQL-Docs/
}
70 changes: 70 additions & 0 deletions src/AniListNet/Objects/Media/Review/MediaReview.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using AniListNet.Helpers;
using Newtonsoft.Json;

namespace AniListNet.Objects;

/// <summary>
/// A Review that features in an anime or manga.
/// </summary>
public class MediaReview
{
[JsonProperty("createdAt")] private readonly int _createdAt;
[JsonProperty("updatedAt")] private readonly int _updatedAt;

/// <summary>
/// The ID of the review.
/// </summary>
[JsonProperty("id")] public int Id { get; private set; }
/// <summary>
/// The creator of the review.
/// </summary>
[JsonProperty("user")] public User User { get; private set; }
/// <summary>
/// The media the review is of.
/// </summary>
[JsonProperty("media")] public Media Media { get; private set; }
/// <summary>
/// A short summary of the review.
/// </summary>
[JsonProperty("summary")] public string Summary { get; private set; }
/// <summary>
/// For which type of media the review is for.
/// </summary>
[JsonProperty("mediaType")] public MediaType MediaType { get; private set; }
/// <summary>
/// The main review body text.
/// </summary>
[JsonProperty("body")] [GqlParameter("asHtml", false)] public string Body { get; private set; }
/// <summary>
/// The total user rating of the review.
/// </summary>
[JsonProperty("rating")] public int Rating { get; private set; }
/// <summary>
/// The amount of user ratings of the review.
/// </summary>
[JsonProperty("ratingAmount")] public int RatingAmount { get; private set; }
/// <summary>
/// The review score of the media.
/// </summary>
[JsonProperty("score")] public int Score { get; private set; }
/// <summary>
/// The url for the review page on the AniList website.
/// </summary>
[JsonProperty("siteUrl")] public Uri Url { get; private set; }
/// <summary>
/// The time of the thread creation.
/// </summary>
public DateTime CreatedAt => DateTimeOffset.FromUnixTimeSeconds(_createdAt).DateTime;
/// <summary>
/// The time of the thread last update.
/// </summary>
public DateTime UpdatedAt => DateTimeOffset.FromUnixTimeSeconds(_updatedAt).DateTime;

/* below are properties only for the authenticated user */

/// <summary>
/// The rating of the review by currently authenticated user.
/// </summary>
[JsonProperty("userRating")] public MediaReviewRating UserRating { get; private set; }

}
10 changes: 10 additions & 0 deletions src/AniListNet/Objects/Media/Review/MediaReviewConnection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace AniListNet.Objects;


public class MediaReviewConnection
{
[JsonProperty("edges")] public MediaReviewEdge[] Edges { get; private set; }
[JsonProperty("nodes")] public MediaReview[] Nodes { get; private set; }
}
8 changes: 8 additions & 0 deletions src/AniListNet/Objects/Media/Review/MediaReviewEdge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Newtonsoft.Json;

namespace AniListNet.Objects;

public class MediaReviewEdge
{
[JsonProperty("node")] public MediaReview Review { get; private set; }
}
10 changes: 10 additions & 0 deletions src/AniListNet/Objects/Media/Review/MediaReviewRating.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Runtime.Serialization;

namespace AniListNet.Objects;

public enum MediaReviewRating
{
[EnumMember(Value = "NO_VOTE")] NoVote,
[EnumMember(Value = "UP_VOTE")] UpVote,
[EnumMember(Value = "DOWN_VOTE")] DownVote
}
12 changes: 12 additions & 0 deletions src/AniListNet/Objects/Media/Review/MediaReviewSort.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Runtime.Serialization;

namespace AniListNet.Objects;

public enum MediaReviewSort
{
[EnumMember(Value = "ID")] Id,
[EnumMember(Value = "SCORE")] Score,
[EnumMember(Value = "RATING")] Rating,
[EnumMember(Value = "CREATED_AT")] CreatedAt,
[EnumMember(Value = "UPDATED_AT")] UpdatedAt,
}
42 changes: 42 additions & 0 deletions src/AniListNet/Parameters/MediaReviewFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using AniListNet.Helpers;
using AniListNet.Objects;

namespace AniListNet.Parameters;

public class MediaReviewFilter
{
/// <summary>
/// Filter by Review ID.
/// </summary>
public int? Id { get; set; }
/// <summary>
/// Filter by Media ID.
/// </summary>
public int? MediaId { get; set; }
/// <summary>
/// Filter by User ID.
/// </summary>
public int? UserId { get; set; }
/// <summary>
/// Filter by Media Type.
/// </summary>
public MediaType? MediaType { get; set; }
public MediaReviewSort Sort { get; set; } = MediaReviewSort.Rating;
public bool SortDescending { get; set; } = true;

internal IEnumerable<GqlParameter> ToParameters()
{
var parameters = new List<GqlParameter>();
if (Id.HasValue)
parameters.Add(new GqlParameter("id", Id));
if (MediaId.HasValue)
parameters.Add(new GqlParameter("mediaId", MediaId));
if (UserId.HasValue)
parameters.Add(new GqlParameter("userId", UserId));
if (MediaType.HasValue)
parameters.Add(new GqlParameter("mediaType", MediaType));

parameters.Add(new GqlParameter("sort", $"${HelperUtilities.GetEnumMemberValue(Sort)}" + (SortDescending ? "_DESC" : string.Empty)));
return parameters;
}
}