public async Task Test_TraktSyncModule_AddCollectionItems() { string postJson = await TestUtility.SerializeObject(AddCollectionItemsPost); postJson.Should().NotBeNullOrEmpty(); TraktClient client = TestUtility.GetOAuthMockClient(ADD_COLLECTION_ITEMS_URI, postJson, COLLECTION_POST_RESPONSE_JSON); TraktResponse <ITraktSyncCollectionPostResponse> response = await client.Sync.AddCollectionItemsAsync(AddCollectionItemsPost); response.Should().NotBeNull(); response.IsSuccess.Should().BeTrue(); response.HasValue.Should().BeTrue(); response.Value.Should().NotBeNull(); ITraktSyncCollectionPostResponse responseValue = response.Value; responseValue.Added.Should().NotBeNull(); responseValue.Added.Movies.Should().Be(1); responseValue.Added.Episodes.Should().Be(12); responseValue.Added.Shows.Should().NotHaveValue(); responseValue.Added.Seasons.Should().NotHaveValue(); responseValue.Updated.Should().NotBeNull(); responseValue.Updated.Movies.Should().Be(3); responseValue.Updated.Episodes.Should().Be(1); responseValue.Updated.Shows.Should().NotHaveValue(); responseValue.Updated.Seasons.Should().NotHaveValue(); responseValue.Existing.Should().NotBeNull(); responseValue.Existing.Movies.Should().Be(2); responseValue.Existing.Episodes.Should().Be(0); responseValue.Existing.Shows.Should().NotHaveValue(); responseValue.Existing.Seasons.Should().NotHaveValue(); responseValue.NotFound.Should().NotBeNull(); responseValue.NotFound.Movies.Should().NotBeNull().And.HaveCount(1); ITraktPostResponseNotFoundMovie[] movies = responseValue.NotFound.Movies.ToArray(); movies[0].Ids.Should().NotBeNull(); movies[0].Ids.Trakt.Should().Be(0); movies[0].Ids.Slug.Should().BeNullOrEmpty(); movies[0].Ids.Imdb.Should().Be("tt0000111"); movies[0].Ids.Tmdb.Should().BeNull(); responseValue.NotFound.Shows.Should().NotBeNull().And.BeEmpty(); responseValue.NotFound.Seasons.Should().NotBeNull().And.BeEmpty(); responseValue.NotFound.Episodes.Should().NotBeNull().And.BeEmpty(); }
public TraktSyncMoviesResult SyncMovies() { _mediaPortalServices.GetLogger().Info("Trakt: start sync movies"); ValidateAuthorization(); TraktSyncMoviesResult syncMoviesResult = new TraktSyncMoviesResult(); TraktMovies traktMovies = _traktCache.RefreshMoviesCache(); IList <Movie> traktUnWatchedMovies = traktMovies.UnWatched; IList <MovieWatched> traktWatchedMovies = traktMovies.Watched; IList <MovieCollected> traktCollectedMovies = traktMovies.Collected; Guid[] types = { MediaAspect.ASPECT_ID, MovieAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID, ExternalIdentifierAspect.ASPECT_ID, ProviderResourceAspect.ASPECT_ID, VideoStreamAspect.ASPECT_ID, VideoAudioStreamAspect.ASPECT_ID }; IContentDirectory contentDirectory = _mediaPortalServices.GetServerConnectionManager().ContentDirectory; if (contentDirectory == null) { throw new MediaLibraryNotConnectedException("ML not connected"); } Guid? userProfile = null; IUserManagement userProfileDataManagement = _mediaPortalServices.GetUserManagement(); if (userProfileDataManagement != null && userProfileDataManagement.IsValidUser) { userProfile = userProfileDataManagement.CurrentUser.ProfileId; } #region Get local database info IList <MediaItem> collectedMovies = contentDirectory.SearchAsync(new MediaItemQuery(types, null, null), true, userProfile, false).Result; if (collectedMovies.Any()) { syncMoviesResult.CollectedInLibrary = collectedMovies.Count; _mediaPortalServices.GetLogger().Info("Trakt: found {0} collected movies available to sync in media library", collectedMovies.Count); } List <MediaItem> watchedMovies = collectedMovies.Where(MediaItemAspectsUtl.IsWatched).ToList(); if (watchedMovies.Any()) { syncMoviesResult.WatchedInLibrary = watchedMovies.Count; _mediaPortalServices.GetLogger().Info("Trakt: found {0} watched movies available to sync in media library", watchedMovies.Count); } #endregion #region Mark movies as unwatched in local database _mediaPortalServices.GetLogger().Info("Trakt: start marking movies as unwatched in media library"); if (traktUnWatchedMovies.Any()) { foreach (var movie in traktUnWatchedMovies) { var localMovie = watchedMovies.FirstOrDefault(m => MovieMatch(m, movie)); if (localMovie == null) { continue; } _mediaPortalServices.GetLogger().Info( "Marking movie as unwatched in library, movie is not watched on trakt. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}'", movie.Title, movie.Year.HasValue ? movie.Year.ToString() : "<empty>", movie.Imdb ?? "<empty>", movie.Tmdb.HasValue ? movie.Tmdb.ToString() : "<empty>"); if (_mediaPortalServices.MarkAsUnWatched(localMovie).Result) { syncMoviesResult.MarkedAsUnWatchedInLibrary++; } } // update watched set watchedMovies = collectedMovies.Where(MediaItemAspectsUtl.IsWatched).ToList(); } #endregion #region Mark movies as watched in local database _mediaPortalServices.GetLogger().Info("Trakt: start marking movies as watched in media library"); if (traktWatchedMovies.Any()) { foreach (var twm in traktWatchedMovies) { var localMovie = collectedMovies.FirstOrDefault(m => MovieMatch(m, twm)); if (localMovie == null) { continue; } _mediaPortalServices.GetLogger().Info( "Marking movie as watched in library, movie is watched on trakt. Plays = '{0}', Title = '{1}', Year = '{2}', IMDb ID = '{3}', TMDb ID = '{4}'", twm.Plays, twm.Title, twm.Year.HasValue ? twm.Year.ToString() : "<empty>", twm.Imdb ?? "<empty>", twm.Tmdb.HasValue ? twm.Tmdb.ToString() : "<empty>"); if (_mediaPortalServices.MarkAsWatched(localMovie).Result) { syncMoviesResult.MarkedAsWatchedInLibrary++; } } } #endregion #region Add movies to watched history at trakt.tv _mediaPortalServices.GetLogger().Info("Trakt: finding movies to add to watched history"); List <TraktSyncHistoryPostMovie> syncWatchedMovies = (from movie in watchedMovies where !traktWatchedMovies.ToList().Exists(c => MovieMatch(movie, c)) select new TraktSyncHistoryPostMovie { Ids = new TraktMovieIds { Imdb = MediaItemAspectsUtl.GetMovieImdbId(movie), Tmdb = MediaItemAspectsUtl.GetMovieTmdbId(movie) }, Title = MediaItemAspectsUtl.GetMovieTitle(movie), Year = MediaItemAspectsUtl.GetMovieYear(movie), WatchedAt = MediaItemAspectsUtl.GetLastPlayedDate(movie), }).ToList(); if (syncWatchedMovies.Any()) { _mediaPortalServices.GetLogger().Info("Trakt: trying to add {0} watched movies to trakt watched history", syncWatchedMovies.Count); ITraktSyncHistoryPostResponse watchedResponse = _traktClient.AddWatchedHistoryItems(new TraktSyncHistoryPost { Movies = syncWatchedMovies }); syncMoviesResult.AddedToTraktWatchedHistory = watchedResponse.Added?.Movies; _traktCache.ClearLastActivity(FileName.WatchedMovies.Value); if (watchedResponse.Added?.Movies != null) { _mediaPortalServices.GetLogger().Info("Trakt: successfully added {0} watched movies to trakt watched history", watchedResponse.Added.Movies.Value); } } #endregion #region Add movies to collection at trakt.tv _mediaPortalServices.GetLogger().Info("Trakt: finding movies to add to collection"); List <TraktSyncCollectionPostMovie> syncCollectedMovies = (from movie in collectedMovies where !traktCollectedMovies.ToList().Exists(c => MovieMatch(movie, c)) select new TraktSyncCollectionPostMovie { MediaType = MediaItemAspectsUtl.GetVideoMediaType(movie), MediaResolution = MediaItemAspectsUtl.GetVideoResolution(movie), Audio = MediaItemAspectsUtl.GetVideoAudioCodec(movie), AudioChannels = MediaItemAspectsUtl.GetVideoAudioChannel(movie), ThreeDimensional = false, Ids = new TraktMovieIds { Imdb = MediaItemAspectsUtl.GetMovieImdbId(movie), Tmdb = MediaItemAspectsUtl.GetMovieTmdbId(movie) }, Title = MediaItemAspectsUtl.GetMovieTitle(movie), Year = MediaItemAspectsUtl.GetMovieYear(movie), CollectedAt = MediaItemAspectsUtl.GetDateAddedToDb(movie) }).ToList(); if (syncCollectedMovies.Any()) { _mediaPortalServices.GetLogger().Info("Trakt: trying to add {0} collected movies to trakt collection", syncCollectedMovies.Count); foreach (var traktSyncCollectionPostMovie in syncCollectedMovies) { string audio = traktSyncCollectionPostMovie.Audio?.DisplayName; string channel = traktSyncCollectionPostMovie.AudioChannels?.DisplayName; string res = traktSyncCollectionPostMovie.MediaResolution?.DisplayName; string mediatype = traktSyncCollectionPostMovie.MediaType?.DisplayName; string name = traktSyncCollectionPostMovie.Title; _mediaPortalServices.GetLogger().Info("Trakt: {0}, {1}, {2}, {3}, {4}", audio, channel, res, mediatype, name); } ITraktSyncCollectionPostResponse collectionResponse = _traktClient.AddCollectionItems(new TraktSyncCollectionPost { Movies = syncCollectedMovies }); syncMoviesResult.AddedToTraktCollection = collectionResponse.Added?.Movies; _traktCache.ClearLastActivity(FileName.CollectedMovies.Value); if (collectionResponse.Added?.Movies != null) { _mediaPortalServices.GetLogger().Info("Trakt: successfully added {0} collected movies to trakt collection", collectionResponse.Added.Movies.Value); } } #endregion return(syncMoviesResult); }
public TraktSyncEpisodesResult SyncSeries() { _mediaPortalServices.GetLogger().Info("Trakt: start sync series"); ValidateAuthorization(); TraktSyncEpisodesResult syncEpisodesResult = new TraktSyncEpisodesResult(); TraktEpisodes traktEpisodes = _traktCache.RefreshSeriesCache(); IList <Episode> traktUnWatchedEpisodes = traktEpisodes.UnWatched; IList <EpisodeWatched> traktWatchedEpisodes = traktEpisodes.Watched; IList <EpisodeCollected> traktCollectedEpisodes = traktEpisodes.Collected; Guid[] types = { MediaAspect.ASPECT_ID, EpisodeAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID, ProviderResourceAspect.ASPECT_ID, ExternalIdentifierAspect.ASPECT_ID }; var contentDirectory = _mediaPortalServices.GetServerConnectionManager().ContentDirectory; if (contentDirectory == null) { throw new MediaLibraryNotConnectedException("ML not connected"); } Guid? userProfile = null; IUserManagement userProfileDataManagement = _mediaPortalServices.GetUserManagement(); if (userProfileDataManagement != null && userProfileDataManagement.IsValidUser) { userProfile = userProfileDataManagement.CurrentUser.ProfileId; } #region Get data from local database IList <MediaItem> localEpisodes = contentDirectory.SearchAsync(new MediaItemQuery(types, null, null), true, userProfile, false).Result; if (localEpisodes.Any()) { syncEpisodesResult.CollectedInLibrary = localEpisodes.Count; _mediaPortalServices.GetLogger().Info("Trakt: found {0} total episodes in library", localEpisodes.Count); } List <MediaItem> localWatchedEpisodes = localEpisodes.Where(MediaItemAspectsUtl.IsWatched).ToList(); if (localWatchedEpisodes.Any()) { syncEpisodesResult.WatchedInLibrary = localWatchedEpisodes.Count; _mediaPortalServices.GetLogger().Info("Trakt: found {0} episodes watched in library", localWatchedEpisodes.Count); } #endregion #region Mark episodes as unwatched in local database _mediaPortalServices.GetLogger().Info("Trakt: start marking series episodes as unwatched in media library"); if (traktUnWatchedEpisodes.Any()) { // create a unique key to lookup and search for faster ILookup <string, MediaItem> localLookupEpisodes = localWatchedEpisodes.ToLookup(twe => CreateLookupKey(twe), twe => twe); foreach (var episode in traktUnWatchedEpisodes) { string tvdbKey = CreateLookupKey(episode); var watchedEpisode = localLookupEpisodes[tvdbKey].FirstOrDefault(); if (watchedEpisode != null) { _mediaPortalServices.GetLogger().Info( "Marking episode as unwatched in library, episode is not watched on trakt. Title = '{0}', Year = '{1}', Season = '{2}', Episode = '{3}', Show TVDb ID = '{4}', Show IMDb ID = '{5}'", episode.ShowTitle, episode.ShowYear.HasValue ? episode.ShowYear.ToString() : "<empty>", episode.Season, episode.Number, episode.ShowTvdbId.HasValue ? episode.ShowTvdbId.ToString() : "<empty>", episode.ShowImdbId ?? "<empty>"); if (_mediaPortalServices.MarkAsUnWatched(watchedEpisode).Result) { syncEpisodesResult.MarkedAsUnWatchedInLibrary++; } // update watched episodes localWatchedEpisodes.Remove(watchedEpisode); } } } #endregion #region Mark episodes as watched in local database _mediaPortalServices.GetLogger().Info("Trakt: start marking series episodes as watched in media library"); if (traktWatchedEpisodes.Any()) { // create a unique key to lookup and search for faster ILookup <string, EpisodeWatched> onlineEpisodes = traktWatchedEpisodes.ToLookup(twe => CreateLookupKey(twe), twe => twe); List <MediaItem> localUnWatchedEpisodes = localEpisodes.Except(localWatchedEpisodes).ToList(); foreach (var episode in localUnWatchedEpisodes) { string tvdbKey = CreateLookupKey(episode); var traktEpisode = onlineEpisodes[tvdbKey].FirstOrDefault(); if (traktEpisode != null) { _mediaPortalServices.GetLogger().Info( "Marking episode as watched in library, episode is watched on trakt. Plays = '{0}', Title = '{1}', Year = '{2}', Season = '{3}', Episode = '{4}', Show TVDb ID = '{5}', Show IMDb ID = '{6}', Last Watched = '{7}'", traktEpisode.Plays, traktEpisode.ShowTitle, traktEpisode.ShowYear.HasValue ? traktEpisode.ShowYear.ToString() : "<empty>", traktEpisode.Season, traktEpisode.Number, traktEpisode.ShowTvdbId.HasValue ? traktEpisode.ShowTvdbId.ToString() : "<empty>", traktEpisode.ShowImdbId ?? "<empty>", traktEpisode.WatchedAt); if (_mediaPortalServices.MarkAsWatched(episode).Result) { syncEpisodesResult.MarkedAsWatchedInLibrary++; } } } } #endregion #region Add episodes to watched history at trakt.tv ITraktSyncHistoryPost syncHistoryPost = GetWatchedShowsForSync(localWatchedEpisodes, traktWatchedEpisodes); if (syncHistoryPost.Shows != null && syncHistoryPost.Shows.Any()) { _mediaPortalServices.GetLogger().Info("Trakt: trying to add {0} watched episodes to trakt watched history", syncHistoryPost.Shows.Count()); ITraktSyncHistoryPostResponse response = _traktClient.AddWatchedHistoryItems(syncHistoryPost); syncEpisodesResult.AddedToTraktWatchedHistory = response.Added?.Episodes; _traktCache.ClearLastActivity(FileName.WatchedEpisodes.Value); if (response.Added?.Episodes != null) { _mediaPortalServices.GetLogger().Info("Trakt: successfully added {0} watched episodes to trakt watched history", response.Added.Episodes.Value); } } #endregion #region Add episodes to collection at trakt.tv ITraktSyncCollectionPost syncCollectionPost = GetCollectedShowsForSync(localEpisodes, traktCollectedEpisodes); if (syncCollectionPost.Shows != null && syncCollectionPost.Shows.Any()) { _mediaPortalServices.GetLogger().Info("Trakt: trying to add {0} collected episodes to trakt collection", syncCollectionPost.Shows.Count()); ITraktSyncCollectionPostResponse response = _traktClient.AddCollectionItems(syncCollectionPost); syncEpisodesResult.AddedToTraktCollection = response.Added?.Episodes; _traktCache.ClearLastActivity(FileName.CollectedEpisodes.Value); if (response.Added?.Episodes != null) { _mediaPortalServices.GetLogger().Info("Trakt: successfully added {0} collected episodes to trakt collection", response.Added.Episodes.Value); } } #endregion return(syncEpisodesResult); }