public void SyncCollectedMoviesToTrakt()
        {
            // Arrange
            IMediaPortalServices mediaPortalServices = Substitute.For <IMediaPortalServices>();

            mediaPortalServices.MarkAsWatched(Arg.Any <MediaItem>()).Returns(true);
            mediaPortalServices.MarkAsUnWatched(Arg.Any <MediaItem>()).Returns(true);
            mediaPortalServices.GetTraktUserHomePath()
            .Returns(HomeUserPath);

            IList <MediaItem>         collectedMovies = new List <MediaItem>();
            IList <MediaLibraryMovie> savedMovies     = new List <MediaLibraryMovie>();
            string collectedMoviesPath = Path.Combine(mediaPortalServices.GetTraktUserHomePath(), FileName.MediaLibraryMovies.Value);

            if (File.Exists(collectedMoviesPath))
            {
                string collectedMoviesJson = File.ReadAllText(collectedMoviesPath);
                savedMovies = JsonConvert.DeserializeObject <List <MediaLibraryMovie> >(collectedMoviesJson);
            }

            foreach (MediaLibraryMovie movie in savedMovies)
            {
                collectedMovies.Add(new MockedDatabaseMovie(new MediaLibraryMovie
                {
                    Title      = movie.Title,
                    Imdb       = movie.Imdb,
                    Year       = movie.Year,
                    AddedToDb  = movie.AddedToDb,
                    LastPlayed = movie.LastPlayed,
                    PlayCount  = movie.PlayCount
                }).Movie);
            }

            IContentDirectory contentDirectory = Substitute.For <IContentDirectory>();

            contentDirectory.SearchAsync(Arg.Any <MediaItemQuery>(), true, null, false).Returns(collectedMovies);
            mediaPortalServices.GetServerConnectionManager().ContentDirectory.Returns(contentDirectory);

            ILogger      logger      = Substitute.For <ILogger>();
            ITraktClient traktClient = new TraktClientProxy(ApplicationId, SecretId, logger);


            ValidateAuthorization(traktClient, new FileOperations());

            IFileOperations         fileOperations         = new FileOperations();
            ITraktCache             traktCache             = new TraktCache(mediaPortalServices, traktClient, fileOperations);
            ILibrarySynchronization librarySynchronization = new LibrarySynchronization(mediaPortalServices, traktClient, traktCache, fileOperations);

            // Act
            TraktSyncMoviesResult result = librarySynchronization.SyncMovies();

            // Assert
            Assert.NotNull(result);
        }
Exemple #2
0
        /// <inheritdoc />
        public RestoreResult RestoreWatchedMovies(string path)
        {
            RestoreResult result = new RestoreResult {
                SavedWatchedCount = 0, MarkedWatchedCount = 0
            };
            IList <MediaLibraryMovie> watchedMovies = ReadSavedWatchedMovies(path);

            result.SavedWatchedCount = watchedMovies.Count;

            Guid[] types =
            {
                MediaAspect.ASPECT_ID,              MovieAspect.ASPECT_ID,            VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID,
                ExternalIdentifierAspect.ASPECT_ID, ProviderResourceAspect.ASPECT_ID, VideoStreamAspect.ASPECT_ID
            };

            IContentDirectory contentDirectory = GetContentDirectory();
            Guid?userProfile = GetUserProfileId();

            IList <MediaItem> collectedMovies = contentDirectory.SearchAsync(new MediaItemQuery(types, null, null), true, userProfile, false).Result;

            foreach (MediaLibraryMovie watchedMovie in watchedMovies)
            {
                MediaItem movie = collectedMovies.FirstOrDefault(m => MovieMatch(m, watchedMovie));
                if (movie == null)
                {
                    continue;
                }

                if (_mediaPortalServices.MarkAsWatched(movie).Result)
                {
                    _mediaPortalServices.GetLogger().Info(
                        "FlagMover: Marking movie as watched in library. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}'",
                        watchedMovie.Title, watchedMovie.Year.HasValue ? watchedMovie.Year.ToString() : "<empty>",
                        watchedMovie.Imdb ?? "<empty>", watchedMovie.Tmdb.HasValue ? watchedMovie.Tmdb.ToString() : "<empty>");

                    result.MarkedWatchedCount++;
                }
            }
            return(result);
        }
        private IMediaPortalServices GetMockMediaPortalServices(IList <MediaItem> databaseMediaItems)
        {
            IMediaPortalServices mediaPortalServices = Substitute.For <IMediaPortalServices>();

            mediaPortalServices.MarkAsWatched(Arg.Any <MediaItem>()).Returns(true);
            mediaPortalServices.MarkAsUnWatched(Arg.Any <MediaItem>()).Returns(true);

            IContentDirectory contentDirectory = Substitute.For <IContentDirectory>();

            contentDirectory.SearchAsync(Arg.Any <MediaItemQuery>(), true, null, false).Returns(databaseMediaItems);
            mediaPortalServices.GetServerConnectionManager().ContentDirectory.Returns(contentDirectory);

            return(mediaPortalServices);
        }
        public void Should_MarkFourEpisodesAsWatched_When_FourEpisodesRestored()
        {
            // Arrange
            IMediaPortalServices mediaPortalServices = Substitute.For <IMediaPortalServices>();
            IContentDirectory    contentDirectory    = Substitute.For <IContentDirectory>();
            IList <MediaItem>    databaseMediaItems  = new List <MediaItem>
            {
                new MockedDatabaseEpisode("272127", 1, new List <int> {
                    7, 8
                }, 0).Episode,
                new MockedDatabaseEpisode("317653", 1, new List <int> {
                    1
                }, 0).Episode,
                new MockedDatabaseEpisode("317653", 1, new List <int> {
                    2
                }, 0).Episode,
                new MockedDatabaseEpisode("275271", 2, new List <int> {
                    11, 12
                }, 0).Episode
            };

            contentDirectory.SearchAsync(Arg.Any <MediaItemQuery>(), true, null, false).Returns(databaseMediaItems);
            mediaPortalServices.GetServerConnectionManager().ContentDirectory.Returns(contentDirectory);
            mediaPortalServices.MarkAsWatched(Arg.Any <MediaItem>()).Returns(true);

            string          savedEpisodesPath = Path.Combine(FakePath, FileName.WatchedEpisodes.Value);
            IFileOperations fileOperations    = Substitute.For <IFileOperations>();

            fileOperations.FileExists(savedEpisodesPath).Returns(true);
            string watchedEpisodesJson =
                "[{\"show_imdb\":\"tt6682754\",\"show_tvdb\":317653,\"show_title\":\"Je-an-Claude Van Johnson\",\"season\":1,\"number\":1}," +
                "{\"show_imdb\":\"tt3155320\",\"show_tvdb\":272127,\"show_title\":\"Extant\",\"season\":1,\"number\":7}," +
                "{\"show_imdb\":\"tt3155320\",\"show_tvdb\":272127,\"show_title\":\"Extant\",\"season\":1,\"number\":8}," +
                "{\"show_imdb\":\"tt6682754\",\"show_tvdb\":317653,\"show_title\":\"Jean-Claude Van Johnson\",\"season\":1,\"number\":2}]";

            fileOperations.FileReadAllText(savedEpisodesPath).Returns(watchedEpisodesJson);

            IMoverOperations operations = new MoverOperations(mediaPortalServices, fileOperations);

            // Act
            RestoreResult result = operations.RestoreWatchedSeries(FakePath);

            // Assert
            Assert.Equal(4, result.MarkedWatchedCount);
            Assert.Equal(4, result.SavedWatchedCount);
        }
        public void Should_MarkOneMovieAsWatched_When_OneMovieRestored()
        {
            // Arrange
            IMediaPortalServices mediaPortalServices = Substitute.For <IMediaPortalServices>();
            IContentDirectory    contentDirectory    = Substitute.For <IContentDirectory>();
            IList <MediaItem>    databaseMediaItems  = new List <MediaItem>
            {
                new MockedDatabaseMovie(new MediaLibraryMovie {
                    Imdb = "tt0268380", Title = "Ice Age", Tmdb = null, Year = 2002
                }, 0).Movie,
                new MockedDatabaseMovie(new MediaLibraryMovie {
                    Imdb = "tt0457939", Title = "Title_2", Tmdb = null, Year = 2016
                }, 0).Movie,
                new MockedDatabaseMovie(new MediaLibraryMovie {
                    Imdb = "tt1355630", Title = "Title_3", Tmdb = null, Year = 2013
                }, 0).Movie
            };

            contentDirectory.SearchAsync(Arg.Any <MediaItemQuery>(), true, null, false).Returns(databaseMediaItems);
            mediaPortalServices.GetServerConnectionManager().ContentDirectory.Returns(contentDirectory);
            mediaPortalServices.MarkAsWatched(Arg.Any <MediaItem>()).Returns(true);

            string          savedMoviesPath = Path.Combine(FakePath, FileName.WatchedMovies.Value);
            IFileOperations fileOperations  = Substitute.For <IFileOperations>();

            fileOperations.FileExists(savedMoviesPath).Returns(true);
            string watchedMoviesJson =
                "[{\"imdb\":\"tt0268380\",\"tmdb\":null,\"title\":\"Ice Age\",\"year\":2002}]";

            fileOperations.FileReadAllText(savedMoviesPath).Returns(watchedMoviesJson);

            IMoverOperations operations = new MoverOperations(mediaPortalServices, fileOperations);

            // Act
            RestoreResult result = operations.RestoreWatchedMovies(FakePath);

            // Assert
            Assert.Equal(1, result.MarkedWatchedCount);
            Assert.Equal(1, result.SavedWatchedCount);
        }
        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);
        }