Cleaned up scrobble logic and refined API calls

This commit is contained in:
Alexander Rufenach
2021-06-03 08:40:34 -04:00
parent f63ea288df
commit e103be43a9
2 changed files with 81 additions and 31 deletions
+27 -8
View File
@@ -24,14 +24,14 @@ namespace Jellyfin.Plugin.AnilistSync.API
private readonly IHttpClientFactory _httpClientFactory;
private readonly JsonSerializerOptions _jsonSerializerOptions;
private const string listIdQuery = @"mutation ($mediaId: Int) {SaveMediaListEntry(mediaId: $mediaId) {id, status, repeat}}&variables={""mediaId"": ""{0}""}";
private const string listIdQuery = @"mutation ($mediaId: Int) {SaveMediaListEntry(mediaId: $mediaId) {id, status, repeat, progress}}&variables={""mediaId"": ""{0}""}";
private const string listUpdateQuery = @"mutation ($id: Int, $progress: Int, $status: MediaListStatus, $repeat: Int) {SaveMediaListEntry(id: $id, progress: $progress, status: $status, repeat: $repeat) {id, progress, status, repeat}}";
private const string listStatusUpdateQuery = @"mutation ($id: Int, $status: MediaListStatus) {SaveMediaListEntry(id: $id, status: $status) {id, status}}";
private const string episodeQuery = @"query ($id: Int) {Media (id: $id) {episodes}}";
private const string currentUserQuery = @"query {Viewer {id, name}}";
private const string listUpdateVars1 = @"&variables={""id"":""{0}"", ""progress"":""{1}""}";
private const string listUpdateVars2 = @"&variables={""id"":""{0}"", ""progress"":""{1}"", ""status"":""{2}""}";
private const string listUpdateVars3 = @"&variables={""id"":""{0}"", ""progress"":""{1}"", ""status"":""{2}"", ""repeat"":""{3}""}";
private const string listUpdateVars2 = @"&variables={""id"":""{0}"", ""status"":""{1}""}";
public const string BaseOauthUrl = @"https://anilist.co/api/v2";
public const string BaseGraphQLUrl = @"https://graphql.anilist.co/api/v2?query=";
@@ -115,17 +115,36 @@ namespace Jellyfin.Plugin.AnilistSync.API
return data;
}
public async Task<RootObject?> PostListUpdate(string? anilistMediaId, string? userToken, int? progress, MediaListStatus? status, int? timesRewatched)
public async Task<RootObject?> PostListStatusUpdate(string? anilistMediaId, string? userToken, MediaListStatus? status)
{
var requestMessage = new HttpRequestMessage();
requestMessage.RequestUri = new Uri(
BaseGraphQLUrl +
listStatusUpdateQuery +
listUpdateVars2
.Replace("{0}", anilistMediaId)
.Replace("{1}", status.ToString()));
requestMessage.Method = HttpMethod.Post;
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", userToken);
requestMessage.Content = new StringContent("", Encoding.UTF8, "application/json");
var responseMessage = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(requestMessage);
var data = await responseMessage.Content.ReadFromJsonAsync<RootObject>(_jsonSerializerOptions);
if (data?.Errors != null)
{
throw new AnilistAPIException(data.Errors);
}
return data;
}
public async Task<RootObject?> PostListProgressUpdate(string? anilistMediaId, string? userToken, int? progress)
{
var requestMessage = new HttpRequestMessage();
requestMessage.RequestUri = new Uri(
BaseGraphQLUrl +
listUpdateQuery +
listUpdateVars3
listUpdateVars1
.Replace("{0}", anilistMediaId)
.Replace("{1}", progress.ToString())
.Replace("{2}", status.ToString())
.Replace("{3}", timesRewatched.ToString()));
.Replace("{1}", progress.ToString()));
requestMessage.Method = HttpMethod.Post;
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", userToken);
requestMessage.Content = new StringContent("", Encoding.UTF8, "application/json");
@@ -173,30 +173,63 @@ namespace Jellyfin.Plugin.AnilistSync.Services
var listEntry = _anilistApi.GetListEntry(anilistId, userConfig.UserToken).Result?.Data?.ListEntry;
int? currentIndex = eventArgs.Item.IndexNumber;
int? currentRemoteIndex = listEntry?.Progress;
int? timesRewatched = listEntry?.TimesRewatched;
MediaListStatus? status = listEntry?.Status;
// Check if STARTING a rewatch
if (status == MediaListStatus.COMPLETED)
switch (status)
{
if (userConfig.ScrobbleRewatches)
{
if (currentIndex == 1) // Check rewatching first episode
case MediaListStatus.COMPLETED: // Check if STARTING a rewatch
if (userConfig.ScrobbleRewatches)
{
status = MediaListStatus.REPEATING;
if (currentIndex == 1) // Only initialize a rewatch if watching first episode
{
status = MediaListStatus.REPEATING;
await _anilistApi.PostListStatusUpdate(listEntry?.Id.ToString(), userConfig.UserToken, status);
_logger.LogInformation("Rewatch started");
}
else
{
_logger.LogInformation("Attempting to start rewatch from middle episode, discarding scrobble");
return;
}
}
else
{
_logger.LogDebug("Attempting to start rewatch from middle episode, discarding scrobble");
_logger.LogInformation("User has chosen not to scrobble rewatches");
return;
}
}
else
{
_logger.LogDebug("User has chosen not to scrobble rewatches");
return;
}
}
break;
case MediaListStatus.REPEATING:
if (userConfig.ScrobbleRewatches)
{
if (currentIndex <= currentRemoteIndex)
{
_logger.LogInformation("Episode number <= Anilist episode watch count, discarding scrobble");
return;
}
}
else
{
_logger.LogInformation("User has chosen not to scrobble rewatches");
return;
}
break;
case MediaListStatus.PLANNING:
case MediaListStatus.DROPPED:
case MediaListStatus.PAUSED:
status = MediaListStatus.CURRENT;
await _anilistApi.PostListStatusUpdate(listEntry?.Id.ToString(), userConfig.UserToken, status);
break;
case MediaListStatus.CURRENT:
if (currentIndex <= currentRemoteIndex)
{
_logger.LogInformation("Episode number <= Anilist episode watch count, discarding scrobble");
return;
}
break;
default:
break;
}
// Get total number of episodes of current item from Anilist
@@ -207,17 +240,15 @@ namespace Jellyfin.Plugin.AnilistSync.Services
// If watching LAST episode change status to completed
if (currentIndex == episodes)
{
if (status == MediaListStatus.REPEATING)
{
timesRewatched += 1;
}
status = MediaListStatus.COMPLETED;
var statusResponse = await _anilistApi.PostListStatusUpdate(listEntry?.Id.ToString(), userConfig.UserToken, status);
}
else
{
var response = await _anilistApi.PostListProgressUpdate(listEntry?.Id.ToString(), userConfig.UserToken, currentIndex);
}
_logger.LogInformation("Current watch status: {status}", status);
// Send post request to API to update list
var response = await _anilistApi.PostListUpdate(listEntry?.Id.ToString(), userConfig.UserToken, currentIndex, status, timesRewatched);
_logger.LogDebug("Scrobbled without errors");
_logger.LogInformation("Scrobbled without errors");
_lastScrobbled[eventArgs.Session.Id] = eventArgs.MediaInfo.Id;
}