henrikfroehling / Trakt.NET

A .NET wrapper library with which developers can build .NET applications that integrate with the Trakt.tv API and access its features and data.
https://henrikfroehling.github.io/Trakt.NET/
MIT License
65 stars 12 forks source link

[Bug]: ValidateHistoryPost for RemoveWatchedHistoryItemsAsync ignores WithHistoryIds #316

Closed meilon closed 1 year ago

meilon commented 1 year ago

Failure description?

I'm trying to write an app to clean up the mess that is my watched history. Some show and movie tracking apps have created a lot of duplicate plays and I'd like to clean that up programmatically.

I started with movies, so here's the code I came up with so far:

using TraktNet;
using TraktNet.Objects.Authentication;
using TraktNet.Objects.Post;
using Spectre.Console;
using TraktNet.Objects.Post.Syncs.History;

// Prod
//var client = new TraktClient("...", "...") { Authorization = TraktAuthorization.CreateWith("...")};
// Staging
var client = new TraktClient("...", "...") { Authorization = TraktAuthorization.CreateWith("...") };
client.Configuration.UseSandboxEnvironment = true;

TimeSpan MaxDiff = TimeSpan.FromHours(24);

Console.WriteLine("Getting movies...");
var movies = await client.Sync.GetWatchedMoviesAsync();
foreach (var movie in movies)
{
    if (movie.Plays > 1)
    {
        Console.WriteLine("{0} has {1} plays, getting history...", movie.Title, movie.Plays);
        var history = await client.Sync.GetWatchedHistoryAsync(historyItemType: TraktNet.Enums.TraktSyncItemType.Movie, itemId: movie.Ids.Trakt);

        DateTime? lastPlay = null;
        List<ulong> historyIds = new();
        Table table = new();
        table.AddColumn(new TableColumn("Id"));
        table.AddColumn(new TableColumn("Played at"));
        table.AddColumn(new TableColumn("Action"));
        table.AddColumn(new TableColumn("Will be removed"));
        foreach (var item in history)
        {
            bool willBeRemoved = false;
            if (lastPlay.HasValue && (lastPlay.Value - item.WatchedAt) < MaxDiff)
            {
                historyIds.Add(item.Id);
                willBeRemoved = true;
            }
            lastPlay = item.WatchedAt;
            table.AddRow(new string[] { item.Id.ToString(), item.WatchedAt.ToString(), item.Action.ToString(), willBeRemoved ? "x" : "" });
        }
        AnsiConsole.Write(table);

        if (historyIds.Count > 0)
        {
            ITraktSyncHistoryRemovePost syncHistoryRemovePost = TraktPost.NewSyncHistoryRemovePost()
                    .WithHistoryIds(historyIds: historyIds.ToArray())
                    .Build();
            var response = await client.Sync.RemoveWatchedHistoryItemsAsync(syncHistoryRemovePost);
            if (!response.IsSuccess)
            {
                Console.WriteLine("  Error removing from history");
            }
            else
            {
                Console.WriteLine("  Removed {0} items from history", response.Value.Deleted.Movies);
            }
        }
    }    
}

But when I try to run it I get an System.ArgumentException: "no watched history items set" for the call client.Sync.RemoveWatchedHistoryItemsAsync(syncHistoryRemovePost) The exception hails from ValidateHistoryPost. There only the movies, shows and episodes get checked for items, never the HistoryIds.

From how I understand the API it is okay to just use the ids, therefore ValidateHistoryPost should be okay with the built historyRemovePost only containing historyIds as well. I know that the same function gets used for adding watched history items, therefore maybe check if it is being used for removing from the history, only then being okay with only historyIds?

Version

1.2.0 (Latest)

Relevant Stacktrace

No response

Code of Conduct

henrikfroehling commented 1 year ago

@meilon The bug should be fixed now. The fix will be released in version 1.3.0. But you can already try it in this release preview package: Trakt.NET.1.3.0-release.preview.135.nupkg.zip

meilon commented 1 year ago

Great, thank you for the fix and this great library! This version did the trick. Finally my watched history reflects what actually happened and is now over 7000 plays lighter