Example #1
0
        public static void RateSeries(DBSeries series)
        {
            if (string.IsNullOrEmpty(TraktAPI.Username) || string.IsNullOrEmpty(TraktAPI.Password))
            {
                return;
            }

            new Thread(delegate()
            {
                TraktRateValue loveorhate = series[DBOnlineSeries.cMyRating] >= 7.0 ? TraktRateValue.love : TraktRateValue.hate;

                TraktRateSeries seriesData = new TraktRateSeries()
                {
                    Rating   = loveorhate.ToString(),
                    SeriesID = series[DBOnlineSeries.cID],
                    Year     = series.Year,
                    Title    = series[DBOnlineSeries.cOriginalName],
                    UserName = TraktAPI.Username,
                    Password = TraktAPI.Password,
                };

                TraktRateResponse response = TraktAPI.RateSeries(seriesData);

                // check for any error and notify
                CheckTraktErrorAndNotify(response, false);
            })
            {
                IsBackground = true,
                Name         = "Trakt Rate Series"
            }.Start();
        }
Example #2
0
        public static void RateEpisode(DBEpisode episode)
        {
            if (string.IsNullOrEmpty(TraktAPI.Username) || string.IsNullOrEmpty(TraktAPI.Password))
            {
                return;
            }

            new Thread(delegate()
            {
                DBSeries series = Helper.getCorrespondingSeries(episode[DBOnlineEpisode.cSeriesID]);

                TraktRateValue loveorhate = episode[DBOnlineEpisode.cMyRating] >= 7.0 ? TraktRateValue.love : TraktRateValue.hate;

                TraktRateEpisode episodeData = new TraktRateEpisode()
                {
                    Episode  = episode[DBOnlineEpisode.cEpisodeIndex],
                    Rating   = loveorhate.ToString(),
                    Season   = episode[DBOnlineEpisode.cSeasonIndex],
                    SeriesID = episode[DBOnlineEpisode.cSeriesID],
                    Year     = series.Year,
                    Title    = series[DBOnlineSeries.cOriginalName],
                    UserName = TraktAPI.Username,
                    Password = TraktAPI.Password
                };

                TraktRateResponse response = TraktAPI.RateEpisode(episodeData);

                // check for any error and notify
                CheckTraktErrorAndNotify(response, false);
            })
            {
                IsBackground = true,
                Name         = "Trakt Rate Episode"
            }.Start();
        }
Example #3
0
 /// <summary>
 /// Uses the current accound information and tries to validate them at trakt.
 /// </summary>
 public void TestAccount()
 {
     try
     {
         TraktResponse result = TraktAPI.TestAccount(new TraktAccount {
             Username = Username, Password = Password
         });
         if (!string.IsNullOrWhiteSpace(result.Error))
         {
             TestStatus = result.Error;
         }
         else if (!string.IsNullOrWhiteSpace(result.Message))
         {
             TestStatus = result.Message;
         }
         else
         {
             TestStatus = string.Empty;
         }
         BuildBannerUrls();
     }
     catch (Exception ex)
     {
         TestStatus = "Error";
         ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while testing account.", ex);
     }
 }
Example #4
0
        /// <summary>
        /// syncs the watched state locally from trakt.tv
        /// </summary>
        public static void SyncTraktWatchedState()
        {
            if (string.IsNullOrEmpty(TraktAPI.Username) || string.IsNullOrEmpty(TraktAPI.Password))
            {
                return;
            }

            // Get all local unwatched episodes
            SQLCondition     conditions = new SQLCondition(new DBOnlineEpisode(), DBOnlineEpisode.cWatched, false, SQLConditionType.Equal);
            List <DBEpisode> episodes   = DBEpisode.Get(conditions, false);

            var watchedItems = TraktAPI.GetUserWatched(TraktAPI.Username);

            MPTVSeriesLog.Write("Trakt: Syncronizing Watched/Seen from trakt.tv");

            // go through all unwatched episodes and check if watched online
            foreach (DBEpisode episode in episodes)
            {
                // if the episode exists on server response
                // then we mark as watched locally
                if (HasEpisode(watchedItems, episode))
                {
                    MPTVSeriesLog.Write("Trakt: Marking '{0}' as watched", episode.ToString());
                    episode[DBOnlineEpisode.cWatched]   = true;
                    episode[DBOnlineEpisode.cTraktSeen] = true;
                    episode.Commit();
                }
            }

            MPTVSeriesLog.Write("Finished Syncronizing Watched/Seen state from trakt.tv");
        }
Example #5
0
        private void StartScrobble()
        {
            ISettingsManager settingsManager = ServiceRegistration.Get <ISettingsManager>();
            TraktSettings    settings        = settingsManager.Load <TraktSettings>();

            if (string.IsNullOrEmpty(settings.TraktOAuthToken))
            {
                TraktLogger.Info("0Auth Token not available");
                return;
            }

            if (!Login(settings.TraktOAuthToken))
            {
                return;
            }

            if (_dataMovie.Movie != null && IsMovie(currentPlayingMediaItem))
            {
                _dataMovie.Progress = 0;
                var response = TraktAPI.StartMovieScrobble(_dataMovie);
                TraktLogger.LogTraktResponse(response);
                return;
            }
            if (_dataEpisode != null && IsSeries(currentPlayingMediaItem))
            {
                _dataEpisode.Progress = 0;
                var response = TraktAPI.StartEpisodeScrobble(_dataEpisode);
                TraktLogger.LogTraktResponse(response);
                return;
            }
            TraktLogger.Info("Can't start scrobble, scrobbledata not available");
        }
Example #6
0
        private bool CallShowAPI(WebTVEpisodeBasic episode, TraktWatchStatus state, int?progress)
        {
            WebTVShowDetailed   show   = MediaService.GetTVShowDetailedById(episode.PID, episode.ShowId);
            WebTVSeasonDetailed season = MediaService.GetTVSeasonDetailedById(episode.PID, episode.SeasonId);

            var data = new TraktEpisodeScrobbleData()
            {
                MediaCenter          = TraktConfig.MediaCenter,
                MediaCenterBuildDate = TraktConfig.MediaCenterDate,
                MediaCenterVersion   = TraktConfig.MediaCenterVersion,
                PluginVersion        = TraktConfig.PluginVersion,
                Password             = Configuration["passwordHash"],
                UserName             = Configuration["username"],

                Duration = show.Runtime.ToString(),
                Episode  = episode.EpisodeNumber.ToString(),
                Season   = season.SeasonNumber.ToString(),
                Title    = show.Title,
                Year     = show.Year.ToString(),
            };

            if (progress != null)
            {
                data.Progress = progress.Value.ToString();
            }

            if (show.ExternalId.Count(x => x.Site == "IMDB") > 0)
            {
                data.IMDBID = show.ExternalId.First(x => x.Site == "IMDB").Id;
            }
            if (show.ExternalId.Count(x => x.Site == "TVDB") > 0)
            {
                data.TVDBID = show.ExternalId.First(x => x.Site == "TVDB").Id;
            }
            if (data.IMDBID == null && data.TVDBID == null)
            {
                Log.Info("Trakt: IMDB and TVDB unknown of episode {0}, not sending", episode.Title);
                return(false);
            }

            try
            {
                Log.Debug("Trakt: calling service for show {0} (episode {1}) with progress {2} and state {3}", data.Title, episode.Title, data.Progress, state.ToString());
                TraktResponse response = TraktAPI.ScrobbleEpisode(data, state);
                if (response.Status != "success")
                {
                    Log.Warn("Trakt: failed to update watch status of episode '{0}' ({1}): {2}", episode.Title, episode.Id, response.Error);
                    return(false);
                }
                Log.Trace("Trakt: finished service call");
                return(true);
            }
            catch (Exception ex)
            {
                Log.Warn("Trakt: failed to call service", ex);
                return(false);
            }
        }
Example #7
0
        void OnSearchResultSelected(GUIListItem item, GUIControl parent)
        {
            TorrentMatch selectedmatch = item.AlbumInfoTag as TorrentMatch;

            Thread backdrop = new Thread(delegate()
            {
                if (!string.IsNullOrEmpty(selectedmatch.tvdb))
                {
                    TraktShow show = TraktAPI.SeriesOverview(selectedmatch.tvdb);
                    if (!string.IsNullOrEmpty(show.Title))
                    {
                        GUIPropertyManager.SetProperty("#MyTorrents.Backdrop", show.Images.Fanart);
                        GUIPropertyManager.SetProperty("#MyTorrents.Poster", show.Images.Poster);
                        GUIPropertyManager.SetProperty("#MyTorrents.Title", show.Title);
                        GUIPropertyManager.SetProperty("#MyTorrents.Year", show.Year.ToString());
                        GUIPropertyManager.SetProperty("#MyTorrents.Summary", show.Overview);
                        GUIPropertyManager.SetProperty("#MyTorrents.Runtime", show.Runtime.ToString());
                        GUIPropertyManager.SetProperty("#MyTorrents.Certification", show.Certification);
                        GUIPropertyManager.SetProperty("#MyTorrents.Rating", show.Rating);
                    }
                }
                else if (!string.IsNullOrEmpty(selectedmatch.imdb))
                {
                    TraktMovie movie = TraktAPI.MovieOverview("tt" + Convert.ToInt32(selectedmatch.imdb).ToString("0000000"));
                    if (!string.IsNullOrEmpty(movie.Title))
                    {
                        GUIPropertyManager.SetProperty("#MyTorrents.Backdrop", movie.Images.Fanart);
                        GUIPropertyManager.SetProperty("#MyTorrents.Poster", movie.Images.Poster);
                        GUIPropertyManager.SetProperty("#MyTorrents.Title", movie.Title);
                        GUIPropertyManager.SetProperty("#MyTorrents.Year", movie.Year);
                        GUIPropertyManager.SetProperty("#MyTorrents.Summary", movie.Overview);
                        GUIPropertyManager.SetProperty("#MyTorrents.Runtime", movie.Runtime.ToString());
                        GUIPropertyManager.SetProperty("#MyTorrents.Certification", movie.Certification);
                        GUIPropertyManager.SetProperty("#MyTorrents.Rating", movie.Rating);
                        GUIPropertyManager.SetProperty("#MyTorrents.Trailer", movie.Trailer);
                    }
                }
                else
                {
                    GUIPropertyManager.SetProperty("#MyTorrents.Backdrop", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Poster", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Title", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Year", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Summary", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Runtime", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Certification", "");
                    GUIPropertyManager.SetProperty("#MyTorrents.Rating", "");
                }
            })
            {
                IsBackground = true,
                Name         = "MyTorrent Backdrop Lookup"
            };

            backdrop.Start();
        }
Example #8
0
 public void GetMovies()
 {
     IEnumerable <TraktSearchEpisode> myep        = TraktAPI.SearchEpisodes("Scars");
     IEnumerable <TraktMovie>         searchmovie = TraktAPI.SearchMovies("Tron");
     IEnumerable <TraktShow>          searchshow  = TraktAPI.SearchShows("eureka");
     //MovieSearch mymovie = TheMovieDbAPI.SearchMovies("tron");
     IEnumerable <TraktMovie>       recmovies   = TraktAPI.GetRecommendedMovies();
     IEnumerable <TraktMovie>       tronrelated = TraktAPI.GetRelatedMovies("tt0084827");
     IEnumerable <TraktUserProfile> newfriend   = TraktAPI.SearchForFriends("ltfearme");
 }
Example #9
0
        public bool TestCredentials(string username, string password)
        {
            var data = new TraktAccountTestData()
            {
                UserName = username,
                Password = HashPassword(password)
            };
            var resp = TraktAPI.TestAccount(data);

            return(resp.Status == "success");
        }
Example #10
0
        private bool CallMovieAPI(WebMovieBasic movie, TraktWatchStatus state, int?progress)
        {
            var data = new TraktMovieScrobbleData()
            {
                MediaCenter          = TraktConfig.MediaCenter,
                MediaCenterBuildDate = TraktConfig.MediaCenterDate,
                MediaCenterVersion   = TraktConfig.MediaCenterVersion,
                PluginVersion        = TraktConfig.PluginVersion,
                Password             = Configuration["passwordHash"],
                UserName             = Configuration["username"],

                Duration = movie.Runtime.ToString(),
                Title    = movie.Title,
                Year     = movie.Year.ToString()
            };

            if (progress != null)
            {
                data.Progress = progress.Value.ToString();
            }

            if (movie.ExternalId.Count(x => x.Site == "IMDB") > 0)
            {
                data.IMDBID = movie.ExternalId.First(x => x.Site == "IMDB").Id;
            }
            if (movie.ExternalId.Count(x => x.Site == "TMDB") > 0)
            {
                data.TMDBID = movie.ExternalId.First(x => x.Site == "TMDB").Id;
            }
            if (data.IMDBID == null && data.TMDBID == null)
            {
                Log.Info("Trakt: IMDB and TMDB unknown of movie {0}, not sending", movie.Title);
                return(false);
            }

            try
            {
                Log.Debug("Trakt: calling service for movie {0} with progress {1} and state {2}", data.Title, data.Progress, state);
                TraktResponse response = TraktAPI.ScrobbleMovie(data, state);
                if (response.Status != "success")
                {
                    Log.Warn("Trakt: failed to update watch status of movie '{0}' ({1}): {2}", movie.Title, movie.Id, response.Error);
                    return(false);
                }
                Log.Trace("Trakt: finished service call");
                return(true);
            }
            catch (Exception ex)
            {
                Log.Warn("Trakt: failed to call service", ex);
                return(false);
            }
        }
        public void SearchSeries()
        {
            VirtualKeyboard keyboard = (VirtualKeyboard)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_VIRTUAL_KEYBOARD);

            keyboard.Reset();
            keyboard.Text = "";
            keyboard.DoModal(GUIWindowManager.ActiveWindow);

            if (!keyboard.IsConfirmed)
            {
                return;
            }

            IList <TraktShow> searchshow = TraktAPI.SearchShows(keyboard.Text).ToList();
            GUIDialogMenu     dialog     = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);

            if (dialog == null)
            {
                return;
            }

            dialog.Reset();
            dialog.SetHeading("Choose TV Series to add");
            foreach (TraktShow ts in searchshow)
            {
                dialog.Add(string.Format("{0} - ({1})", ts.Title, ts.Year));
            }
            dialog.DoModal(GUIWindowManager.ActiveWindow);

            if (dialog.SelectedId != -1)
            {
                TraktShow  t    = searchshow[dialog.SelectedId - 1];
                SeriesItem item = new SeriesItem();
                item.quality           = "720p";
                item.show              = new Series();
                item.show.Name         = t.Title;
                item.show.OriginalName = t.Title;
                item.show.Description  = t.Overview;
                foreach (string genre in t.Genres)
                {
                    item.show.Genres += "|" + genre;
                }
                item.show.Rating = ((double)t.Ratings.Percentage / 10.0).ToString();
                item.show.Poster = t.Images.Banner;
                item.show.ID     = t.Tvdb;
                item.tracker     = "BTN";
                MyTorrents.Instance()._torrentWatchlist._watchItemList.Add(item);
            }
        }
Example #12
0
        private void HandleScrobble(IPlayerSlotController psc, bool starting)
        {
            try
            {
                IPlayerContext pc = PlayerContext.GetPlayerContext(psc);
                if (pc == null)
                {
                    return;
                }

                bool removePsc = HandleTasks(psc, starting);

                AbstractScrobble    scrobbleData;
                TraktScrobbleStates state;
                if (TryCreateScrobbleData(psc, pc, starting, out scrobbleData, out state))
                {
                    ServiceRegistration.Get <ILogger>().Debug("Trakt.tv: [{5}] {0}, Duration {1}, Percent {2}, PSC.Duration {3}, PSC.ResumePosition {4}",
                                                              scrobbleData.Title, scrobbleData.Duration, scrobbleData.Progress, _progressUpdateWorks[psc].Duration, _progressUpdateWorks[psc].ResumePosition, state);

                    TraktMovieScrobble movie = scrobbleData as TraktMovieScrobble;
                    if (movie != null)
                    {
                        TraktAPI.ScrobbleMovieState(movie, state);
                    }

                    TraktEpisodeScrobble episode = scrobbleData as TraktEpisodeScrobble;
                    if (episode != null)
                    {
                        TraktAPI.ScrobbleEpisodeState(episode, state);
                    }
                }

                if (removePsc)
                {
                    lock (_syncObj)
                        _progressUpdateWorks.Remove(psc);
                }
            }
            catch (ThreadAbortException)
            { }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while scrobbling", ex);
            }
        }
Example #13
0
 private void StopScrobble()
 {
     if (_dataMovie.Movie != null && IsMovie(currentPlayingMediaItem))
     {
         _dataMovie.Progress = _progress;
         var response = TraktAPI.StopMovieScrobble(_dataMovie);
         TraktLogger.LogTraktResponse(response);
         return;
     }
     if (_dataEpisode != null && IsSeries(currentPlayingMediaItem))
     {
         _dataEpisode.Progress = _progress;
         var response = TraktAPI.StopEpisodeScrobble(_dataEpisode);
         TraktLogger.LogTraktResponse(response);
         return;
     }
     TraktLogger.Info("Can't post stop scrobble, scrobbledata lost");
 }
Example #14
0
        public bool SyncMovies()
        {
            try
            {
                TestStatus = "[Trakt.SyncMovies]";
                Guid[] types            = { MediaAspect.ASPECT_ID, MovieAspect.ASPECT_ID };
                var    contentDirectory = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
                if (contentDirectory == null)
                {
                    TestStatus = "[Trakt.MediaLibraryNotConnected]";
                    return(false);
                }
                var            movies   = contentDirectory.Search(new MediaItemQuery(types, null, null), true);
                TraktMovieSync syncData = new TraktMovieSync {
                    UserName = Username, Password = Password, MovieList = new List <TraktMovieSync.Movie>()
                };
                // First send all movies to Trakt that we have so they appear in library
                foreach (var movie in movies)
                {
                    syncData.MovieList.Add(ToMovie(movie));
                }

                TraktSyncModes traktSyncMode = TraktSyncModes.library;
                var            response      = TraktAPI.SyncMovieLibrary(syncData, traktSyncMode);
                ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Movies '{0}': {1} inserted, {2} existing, {3} skipped movies.", traktSyncMode, response.Inserted, SafeCount(response.AlreadyExistMovies), SafeCount(response.SkippedMovies));

                syncData.MovieList.Clear();
                // Then send only the watched movies as "seen"
                foreach (var movie in movies.Where(IsWatched))
                {
                    syncData.MovieList.Add(ToMovie(movie));
                }

                traktSyncMode = TraktSyncModes.seen;
                response      = TraktAPI.SyncMovieLibrary(syncData, traktSyncMode);
                ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Movies '{0}': {1} inserted, {2} existing, {3} skipped movies.", traktSyncMode, response.Inserted, SafeCount(response.AlreadyExistMovies), SafeCount(response.SkippedMovies));
                return(true);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex);
            }
            return(false);
        }
Example #15
0
        private void ImportMovieData()
        {
            if (!importMovies)
            {
                return;
            }

            var listal = ListalAPI.ReadListalExportFile(listalMovieFile);

            // check if everything we need was read okay
            if (listal == null || listal.Channel == null || listal.Channel.Items == null)
            {
                UIUtils.UpdateStatus("Error reading Listal movie XML file", true);
                return;
            }

            UIUtils.UpdateStatus("Found {0} movies in Listal export file", listal.Channel.Items.Count);
            if (importCancelled)
            {
                return;
            }

            #region Ratings

            var listalMovieRatings = listal.Channel.Items.Where(m => m.Rating > 0).ToList();
            UIUtils.UpdateStatus("Found {0} movies with ratings", listalMovieRatings.Count);

            if (listalMovieRatings.Count > 0)
            {
                // get current trakt ratings
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();
                if (importCancelled)
                {
                    return;
                }

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count());

                    // filter out movies to rate from existing ratings online
                    listalMovieRatings.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.ImdbId == "tt" + m.IMDbId.ToString()));
                }

                UIUtils.UpdateStatus("Importing {0} new Listal movie ratings...", listalMovieRatings.Count);
                if (listalMovieRatings.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)listalMovieRatings.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Listal rated movies...", i + 1, pages);

                        var response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(listalMovieRatings.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send ratings for Listal movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Watched

            if (AppSettings.MarkAsWatched)
            {
                if (importCancelled)
                {
                    return;
                }

                // mark all movies as watched if rated
                listalMovieRatings = listal.Channel.Items.Where(m => m.Rating > 0).ToList();

                // get watched movies from trakt.tv
                UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                watchedTraktMovies = TraktAPI.GetWatchedMovies();
                if (watchedTraktMovies == null)
                {
                    UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                    Thread.Sleep(2000);
                }
                else
                {
                    if (importCancelled)
                    {
                        return;
                    }

                    UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                    UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");
                    listalMovieRatings.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == "tt" + w.IMDbId) != null);

                    UIUtils.UpdateStatus("Importing {0} Listal movies as watched...", listalMovieRatings.Count);

                    if (listalMovieRatings.Count > 0)
                    {
                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)listalMovieRatings.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} Listal movies as watched...", i + 1, pages);

                            var watchedResponse = TraktAPI.AddMoviesToWatchedHistory(GetWatchedMoviesData(listalMovieRatings.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (watchedResponse == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watched status for Listal movies", true);
                                Thread.Sleep(2000);
                            }
                            else if (watchedResponse.NotFound.Movies.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watched for {0} movies as they're not found on trakt.tv!", watchedResponse.NotFound.Movies.Count);
                                Thread.Sleep(1000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
            }
            #endregion

            #region Watchlist

            // Convert Listal Wantlist to a Trakt Watchlist
            if (importWantlist)
            {
                if (importCancelled)
                {
                    return;
                }

                var wantList = listal.Channel.Items.Where(m => m.ListType == ListType.wanted.ToString()).ToList();

                if (wantList.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                    var watchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                    if (watchlistTraktMovies != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", watchlistTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                        wantList.RemoveAll(w => watchlistTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == "tt" + w.IMDbId) != null);
                    }
                    if (importCancelled)
                    {
                        return;
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist)
                    {
                        UIUtils.UpdateStatus("Requesting watched movies from trakt...");

                        // get watched movies from trakt so we don't import movies into watchlist that are already watched
                        if (watchedTraktMovies == null)
                        {
                            watchedTraktMovies = TraktAPI.GetWatchedMovies();
                            if (watchedTraktMovies != null)
                            {
                                UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());

                                // remove movies from sync list which are watched already
                                wantList.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == "tt" + w.IMDbId) != null);
                            }
                        }
                        if (importCancelled)
                        {
                            return;
                        }
                    }

                    // add all movies to watchlist
                    UIUtils.UpdateStatus("Importing {0} Listal Wantlist movies to trakt.tv Watchlist...", wantList.Count());

                    if (wantList.Count > 0)
                    {
                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)wantList.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} Listal wantlist movies to trakt.tv watchlist...", i + 1, pages);

                            var watchlistMoviesResponse = TraktAPI.AddMoviesToWatchlist(GetMoviesData(wantList.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (watchlistMoviesResponse == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watchlist for Listal movies", true);
                                Thread.Sleep(2000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
            }

            #endregion
        }
Example #16
0
        private void ImportShowData()
        {
            if (!importShows)
            {
                return;
            }

            var listal = ListalAPI.ReadListalExportFile(listalShowFile);

            // check if everything we need was read okay
            if (listal == null || listal.Channel == null || listal.Channel.Items == null)
            {
                UIUtils.UpdateStatus("Error reading Listal tv show XML file", true);
                return;
            }

            UIUtils.UpdateStatus("Found {0} tv shows in Listal export file", listal.Channel.Items.Count);
            if (importCancelled)
            {
                return;
            }

            #region Ratings

            var listalShowRatings = listal.Channel.Items.Where(m => m.Rating > 0).ToList();
            UIUtils.UpdateStatus(string.Format("Found {0} tv shows with ratings", listalShowRatings.Count), true);

            if (listalShowRatings.Count > 0)
            {
                // get current trakt ratings
                UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
                var currentUserShowRatings = TraktAPI.GetRatedShows();
                if (importCancelled)
                {
                    return;
                }

                if (currentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv show ratings on trakt.tv", currentUserShowRatings.Count());

                    // filter out shows to rate from existing ratings online
                    listalShowRatings.RemoveAll(m => currentUserShowRatings.Any(c => c.Show.Ids.ImdbId == "tt" + m.IMDbId.ToString()));
                }

                UIUtils.UpdateStatus("Importing {0} Listal tv show ratings...", listalShowRatings.Count);
                if (listalShowRatings.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)listalShowRatings.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Listal show ratings...", i + 1, pages);

                        var response = TraktAPI.AddShowsToRatings(GetRateShowsData(listalShowRatings.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send ratings for Listal tv shows", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Watchlist
            // Convert Listal Wantlist to a Trakt Watchlist
            if (importWantlist)
            {
                if (importCancelled)
                {
                    return;
                }

                var wantList = listal.Channel.Items.Where(m => m.ListType == ListType.wanted.ToString()).ToList();

                if (wantList.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist shows from trakt...");
                    var watchlistTraktShows = TraktAPI.GetWatchlistShows();
                    if (watchlistTraktShows != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", watchlistTraktShows.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                        wantList.RemoveAll(w => watchlistTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == "tt" + w.IMDbId) != null);
                    }
                    if (importCancelled)
                    {
                        return;
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist)
                    {
                        UIUtils.UpdateStatus("Requesting watched shows from trakt...");

                        // get watched movies from trakt so we don't import shows into watchlist that are already watched
                        var watchedTraktShows = TraktAPI.GetWatchedShows();
                        if (watchedTraktShows != null)
                        {
                            UIUtils.UpdateStatus("Found {0} watched shows on trakt", watchedTraktShows.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist shows containing watched episodes on trakt.tv.");

                            // remove shows from sync list which are watched already
                            wantList.RemoveAll(w => watchedTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == "tt" + w.IMDbId) != null);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }

                    // add movies to watchlist
                    UIUtils.UpdateStatus("Importing {0} Listal Wantlist tv shows to trakt.tv Watchlist...", wantList.Count());

                    if (wantList.Count > 0)
                    {
                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)wantList.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} Listal wantlist tv shows to trakt.tv watchlist...", i + 1, pages);

                            var watchlistShowsResponse = TraktAPI.AddShowsToWatchlist(GetSyncShowsData(wantList.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (watchlistShowsResponse == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watchlist for Listal tv shows", true);
                                Thread.Sleep(2000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
            }

            #endregion
        }
Example #17
0
        public void ImportRatings()
        {
            importCancelled = false;

            // get show userratings from theTVDb.com first
            UIUtils.UpdateStatus("Getting show ratings from theTVDb.com");

            TVDbShowRatings showRatings = TVDbAPI.GetShowRatings(accountId);

            // if there are no show ratings quit
            if (showRatings == null || showRatings.Shows.Count == 0)
            {
                UIUtils.UpdateStatus("Unable to get list of shows from thetvdb.com, NOTE: episode ratings can not be retreived from theTVDb.com unless the Show has also been rated!", true);
                return;
            }

            #region Import Show Ratings
            if (importCancelled)
            {
                return;
            }
            UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
            var currentUserShowRatings = TraktAPI.GetRatedShows();

            var filteredShows = new TVDbShowRatings();
            filteredShows.Shows.AddRange(showRatings.Shows);

            if (currentUserShowRatings != null)
            {
                UIUtils.UpdateStatus("Found {0} user tv show ratings on trakt.tv", currentUserShowRatings.Count());
                UIUtils.UpdateStatus("Filtering out tvdb show ratings that already exist at trakt.tv");

                // Filter out shows to rate from existing ratings online
                filteredShows.Shows.RemoveAll(s => currentUserShowRatings.Any(c => c.Show.Ids.TvdbId == s.Id));
            }

            UIUtils.UpdateStatus("Importing {0} show ratings to trakt.tv", filteredShows.Shows.Count);

            if (filteredShows.Shows.Count > 0)
            {
                int pageSize = AppSettings.BatchSize;
                int pages    = (int)Math.Ceiling((double)filteredShows.Shows.Count / pageSize);
                for (int i = 0; i < pages; i++)
                {
                    UIUtils.UpdateStatus("Importing page {0}/{1} TVDb rated shows...", i + 1, pages);

                    TraktSyncResponse response = TraktAPI.AddShowsToRatings(GetRateShowsData(filteredShows.Shows.Skip(i * pageSize).Take(pageSize).ToList()));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Error importing show ratings to trakt.tv", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Shows.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync ratings of {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                        Thread.Sleep(1000);
                    }
                    if (importCancelled)
                    {
                        return;
                    }
                }
            }
            #endregion

            #region Import Episode Ratings
            int iCounter      = 0;
            var episodesRated = new Dictionary <string, List <TraktEpisodeRating> >();

            // get all existing user ratings from trakt.tv
            UIUtils.UpdateStatus("Retrieving existing episode ratings from trakt.tv");
            var currentUserEpisodeRatings = TraktAPI.GetRatedEpisodes();

            if (currentUserEpisodeRatings != null)
            {
                UIUtils.UpdateStatus("Found {0} user tv episode ratings on trakt.tv", currentUserEpisodeRatings.Count());
            }

            foreach (var show in showRatings.Shows)
            {
                if (importCancelled)
                {
                    return;
                }
                iCounter++;

                UIUtils.UpdateStatus("[{0}/{1}] Getting show info for tvdb series id {2}", iCounter, showRatings.Shows.Count, show.Id);

                // we need to get the episode/season numbers as trakt api requires this
                // tvdb only returns episode ids, so user series info call to this info
                TVDbShow showInfo = TVDbAPI.GetShowInfo(show.Id.ToString());
                if (showInfo == null)
                {
                    UIUtils.UpdateStatus(string.Format("Unable to get show info for tvdb series id: {0}", show.Id), true);
                    Thread.Sleep(2000);
                    continue;
                }
                if (importCancelled)
                {
                    return;
                }
                UIUtils.UpdateStatus("[{0}/{1}] Requesting episode ratings for {2} from theTVDb.com", iCounter, showRatings.Shows.Count, showInfo.Show.Name);

                // get episode ratings for each show in showratings
                TVDbEpisodeRatings episodeRatings = TVDbAPI.GetEpisodeRatings(accountId, show.Id.ToString());
                if (episodeRatings == null)
                {
                    UIUtils.UpdateStatus(string.Format("Unable to get episode ratings for {0} [{1}] from theTVDb.com", showInfo.Show.Name, show.Id), true);
                    Thread.Sleep(2000);
                    continue;
                }
                if (importCancelled)
                {
                    return;
                }

                UIUtils.UpdateStatus("Found {0} episode ratings for {1} on theTVDb.com", episodeRatings.Episodes.Count, showInfo.Show.Name);

                if (currentUserEpisodeRatings != null)
                {
                    UIUtils.UpdateStatus("Filtering out {0} tvdb episode ratings that already exist at trakt.tv", showInfo.Show.Name);

                    // Filter out episodes to rate from existing ratings online, using tvdb episode id's
                    episodeRatings.Episodes.RemoveAll(e => currentUserEpisodeRatings.Any(c => ((c.Episode.Ids.TvdbId == e.Id))));
                }

                UIUtils.UpdateStatus("[{0}/{1}] Importing {2} episode ratings for {3}", iCounter, showRatings.Shows.Count, episodeRatings.Episodes.Count, showInfo.Show.Name);
                if (episodeRatings.Episodes.Count == 0)
                {
                    continue;
                }

                // submit one series at a time
                var episodesToRate = GetRateEpisodeData(episodeRatings);
                var response       = TraktAPI.AddsEpisodesToRatings(episodesToRate);
                if (response == null)
                {
                    UIUtils.UpdateStatus(string.Format("Error importing {0} episode ratings to trakt.tv", showInfo.Show.Name), true);
                    Thread.Sleep(2000);
                    continue;
                }
                else if (response.NotFound.Episodes.Count > 0)
                {
                    UIUtils.UpdateStatus("[{0}/{1}] Unable to sync ratings for {2} episodes of {3} as they're not found on trakt.tv!", iCounter, showRatings.Shows.Count, response.NotFound.Episodes.Count, showInfo.Show.Name);
                    Thread.Sleep(1000);
                }
                episodesRated.Add(showInfo.Show.Name, episodesToRate.Episodes);
            }
            #endregion

            #region Mark As Watched

            if (AppSettings.MarkAsWatched && episodesRated.Any())
            {
                int i = 0;
                foreach (var show in episodesRated)
                {
                    if (importCancelled)
                    {
                        return;
                    }

                    // mark all episodes as watched if rated
                    UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TVDb episodes of {3} as watched to trakt.tv...", ++i, episodesRated.Count, show.Value.Count, show.Key);
                    var watchedEpisodes = GetWatchedEpisodeData(show.Value);
                    var response        = TraktAPI.AddEpisodesToWatchedHistory(watchedEpisodes);
                    if (response == null)
                    {
                        UIUtils.UpdateStatus(string.Format("Failed to send watched status for TVDb '{0}' episodes", show.Key), true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Episodes.Count > 0)
                    {
                        UIUtils.UpdateStatus("[{0}/{1}] Unable to sync {2} TVDb episodes of {3} as watched as they're not found on trakt.tv!", i, episodesRated.Count, response.NotFound.Episodes.Count, show.Key);
                        Thread.Sleep(1000);
                    }
                }
            }

            #endregion
        }
Example #18
0
        public void ImportRatings()
        {
            var lRateItems    = new List <Dictionary <string, string> >();
            var lWatchedItems = new List <Dictionary <string, string> >();
            var lDiaryItems   = new List <Dictionary <string, string> >();

            mImportCancelled = false;

            #region Parse Ratings CSV
            UIUtils.UpdateStatus("Reading Letterboxd ratings export...");
            if (mImportRatings && !ParseCSVFile(mLetterboxdRatingsFile, out lRateItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd ratings file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Watched CSV
            UIUtils.UpdateStatus("Reading Letterboxd watched export...");
            if (mImportWatched && !ParseCSVFile(mLetterboxdWatchedFile, out lWatchedItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd watched file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Diary CSV
            UIUtils.UpdateStatus("Reading Letterboxd diary export...");
            if (mImportDiary && !ParseCSVFile(mLetterboxdDiaryFile, out lDiaryItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd diary file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Movies
            FileLog.Info("Found {0} movie ratings in CSV file", lRateItems.Count);
            if (lRateItems.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count());
                    // Filter out movies to rate from existing ratings online
                    lRateItems.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Title == m[LetterboxdFieldMapping.cTitle] && c.Movie.Year.ToString() == m[LetterboxdFieldMapping.cYear]));
                }

                UIUtils.UpdateStatus("Importing {0} new movie ratings to trakt.tv", lRateItems.Count());

                if (lRateItems.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lRateItems.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Letterboxd rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(lRateItems.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing Letterboxd movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync Letterboxd ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watched Movies

            // The Dairy can can include rated and watched items, it also has a watched date
            // if the watched movie exists in the diary use that as a watched date otherwise use date from watched file

            // add to diary any watched films that have been back filled
            foreach (var movie in lWatchedItems)
            {
                if (!lDiaryItems.Exists(d => d[LetterboxdFieldMapping.cTitle] == movie[LetterboxdFieldMapping.cTitle] && d[LetterboxdFieldMapping.cYear] == movie[LetterboxdFieldMapping.cYear]))
                {
                    lDiaryItems.Add(movie);
                }
            }

            if (lDiaryItems.Count > 0)
            {
                // get watched movies from trakt.tv
                UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                var watchedTraktMovies = TraktAPI.GetWatchedMovies();
                if (watchedTraktMovies == null)
                {
                    UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                    Thread.Sleep(2000);
                }
                else
                {
                    if (mImportCancelled)
                    {
                        return;
                    }

                    UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                    UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                    lDiaryItems.RemoveAll(d => watchedTraktMovies.FirstOrDefault(t => t.Movie.Title == d[LetterboxdFieldMapping.cTitle] && t.Movie.Year.ToString() == d[LetterboxdFieldMapping.cYear]) != null);

                    UIUtils.UpdateStatus("Importing {0} Letterboxd movies as watched...", lDiaryItems.Count);

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lDiaryItems.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Letterboxd movies as watched...", i + 1, pages);

                        var response = TraktAPI.AddMoviesToWatchedHistory(GetSyncWatchedMoviesData(lDiaryItems.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watched status for Letterboxd movies to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync Letterboxd watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }
                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion

            return;
        }
Example #19
0
        public void ImportRatings()
        {
            importCancelled = false;
            List <TMDbMovie> watchedMovies = new List <TMDbMovie>();

            #region Session Id
            // check if we have a session id
            // note: request token if new is only valid for 60mins
            if (string.IsNullOrEmpty(AppSettings.TMDbSessionId))
            {
                UIUtils.UpdateStatus("Getting TMDb Authentication Session Id...");
                var sessionResponse = TMDbAPI.RequestSessionId(AppSettings.TMDbRequestToken);
                if (sessionResponse == null || !sessionResponse.Success)
                {
                    UIUtils.UpdateStatus("Unable to get TMDb Authentication Session Id.", true);
                    Thread.Sleep(2000);
                    return;
                }
                AppSettings.TMDbSessionId = sessionResponse.SessionId;
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Account Information
            UIUtils.UpdateStatus("Getting TMDb Account Id...");
            var accountInfo = TMDbAPI.GetAccountId(AppSettings.TMDbSessionId);
            if (accountInfo == null)
            {
                UIUtils.UpdateStatus("Unable to get TMDb Account Id.", true);
                Thread.Sleep(2000);
                return;
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Get Rated Movies
            UIUtils.UpdateStatus("Getting first batch of TMDb rated movies...");
            var movieRatings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1);
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Import Movie Ratings

            if (movieRatings != null && movieRatings.TotalResults > 0)
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count());
                    UIUtils.UpdateStatus("Filtering out movies already rated on trakt.tv");
                    movieRatings.Movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.TmdbId == m.Id));
                }

                UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Movie Ratings...", movieRatings.Page, movieRatings.TotalPages, movieRatings.Movies.Count);

                if (movieRatings.Movies.Count > 0)
                {
                    var response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(movieRatings.Movies));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Failed to send ratings for TMDb movies", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Movies.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                        Thread.Sleep(1000);
                    }
                    if (importCancelled)
                    {
                        return;
                    }

                    // add to list of movies to mark as watched
                    watchedMovies.AddRange(movieRatings.Movies);
                }

                // get each page of movies
                for (int i = 2; i <= movieRatings.TotalPages; i++)
                {
                    UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb Rated Movies...", movieRatings.Page, movieRatings.TotalPages);
                    movieRatings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i);
                    if (movieRatings == null || movieRatings.TotalResults == 0 || importCancelled)
                    {
                        return;
                    }

                    if (currentUserMovieRatings != null)
                    {
                        UIUtils.UpdateStatus("Filtering out movies already rated on trakt.tv");
                        movieRatings.Movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.TmdbId == m.Id));
                    }

                    UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Movie Ratings...", movieRatings.Page, movieRatings.TotalPages, movieRatings.Movies.Count);

                    if (movieRatings.Movies.Count > 0)
                    {
                        var response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(movieRatings.Movies));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send ratings for TMDb movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }
                        if (importCancelled)
                        {
                            return;
                        }

                        // add to list of movies to mark as watched
                        watchedMovies.AddRange(movieRatings.Movies);
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }

            #endregion

            #region Mark As Watched
            if (AppSettings.MarkAsWatched && watchedMovies.Count > 0)
            {
                // mark all rated movies as watched
                UIUtils.UpdateStatus("Importing {0} TMDb movies as watched...", watchedMovies.Count);

                int pageSize = AppSettings.BatchSize;
                int pages    = (int)Math.Ceiling((double)watchedMovies.Count / pageSize);
                for (int i = 0; i < pages; i++)
                {
                    UIUtils.UpdateStatus("Importing page {0}/{1} TMDb movies as watched...", i + 1, pages);

                    var response = TraktAPI.AddMoviesToWatchedHistory(GetSyncWatchedMoviesData(watchedMovies.Skip(i * pageSize).Take(pageSize).ToList()));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Failed to send watched status for TMDb movies to trakt.tv", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Movies.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                        Thread.Sleep(1000);
                    }
                    if (importCancelled)
                    {
                        return;
                    }
                }
            }
            #endregion

            #region Get Rated Shows
            UIUtils.UpdateStatus("Getting first batch of TMDb rated shows...");
            var showRatings = TMDbAPI.GetRatedShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1);
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Import Show Ratings
            if (showRatings != null && showRatings.TotalResults > 0)
            {
                return;
            }
            {
                UIUtils.UpdateStatus("Retrieving existing show ratings from trakt.tv");
                var currentUserShowRatings = TraktAPI.GetRatedShows();

                if (currentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user show ratings on trakt.tv", currentUserShowRatings.Count());
                    UIUtils.UpdateStatus("Filtering out shows already rated on trakt.tv");
                    showRatings.Shows.RemoveAll(s => currentUserShowRatings.Any(c => c.Show.Ids.TmdbId == s.Id));
                }

                UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Show Ratings...", showRatings.Page, showRatings.TotalPages, showRatings.Shows.Count);

                if (showRatings == null || showRatings.Shows.Count > 0)
                {
                    var response = TraktAPI.AddShowsToRatings(GetRateShowsData(showRatings.Shows));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Failed to send ratings for TMDb shows", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Shows.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                        Thread.Sleep(1000);
                    }

                    if (importCancelled)
                    {
                        return;
                    }
                }

                // get each page of movies
                for (int i = 2; i <= showRatings.TotalPages; i++)
                {
                    UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb rated shows...", showRatings.Page, showRatings.TotalPages);
                    showRatings = TMDbAPI.GetRatedShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i);
                    if (importCancelled)
                    {
                        return;
                    }

                    if (currentUserShowRatings != null)
                    {
                        UIUtils.UpdateStatus("Filtering out shows already rated on trakt.tv");
                        showRatings.Shows.RemoveAll(s => currentUserShowRatings.Any(c => c.Show.Ids.TmdbId == s.Id));
                    }

                    UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb show ratings...", showRatings.Page, showRatings.TotalPages, showRatings.Shows.Count);

                    if (showRatings == null || showRatings.Shows.Count > 0)
                    {
                        var response = TraktAPI.AddShowsToRatings(GetRateShowsData(showRatings.Shows));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send ratings for TMDb shows.", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Import Watchlist

            if (AppSettings.TMDbSyncWatchlist)
            {
                #region Movies
                IEnumerable <TraktMoviePlays> traktWatchedMovies = null;

                UIUtils.UpdateStatus("Getting first batch of TMDb watchlist movies...");
                var moviesInWatchlist = TMDbAPI.GetWatchlistMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1);
                if (importCancelled)
                {
                    return;
                }

                if (moviesInWatchlist != null && moviesInWatchlist.TotalResults > 0)
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                    var traktWatchlistMovies = TraktAPI.GetWatchlistMovies();
                    if (traktWatchlistMovies != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", traktWatchlistMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                        moviesInWatchlist.Movies.RemoveAll(w => traktWatchlistMovies.FirstOrDefault(t => t.Movie.Ids.TmdbId == w.Id) != null);
                    }
                    if (importCancelled)
                    {
                        return;
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist)
                    {
                        UIUtils.UpdateStatus("Retrieving existing watched movies from trakt.tv");
                        traktWatchedMovies = TraktAPI.GetWatchedMovies();

                        if (traktWatchedMovies != null)
                        {
                            UIUtils.UpdateStatus("Found {0} watched movies on trakt.tv", traktWatchedMovies.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watched on trakt.tv");
                            moviesInWatchlist.Movies.RemoveAll(m => traktWatchedMovies.Any(c => c.Movie.Ids.TmdbId == m.Id));
                        }
                    }
                    if (importCancelled)
                    {
                        return;
                    }

                    UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages, moviesInWatchlist.Movies.Count);

                    if (moviesInWatchlist.Movies.Count > 0)
                    {
                        var response = TraktAPI.AddMoviesToWatchlist(GetSyncMoviesData(moviesInWatchlist.Movies));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for TMDb movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus(string.Format("Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count));
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }

                    // get each page of movies
                    for (int i = 2; i <= moviesInWatchlist.TotalPages; i++)
                    {
                        UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages);
                        moviesInWatchlist = TMDbAPI.GetWatchlistMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i);
                        if (importCancelled)
                        {
                            return;
                        }

                        if (moviesInWatchlist != null && moviesInWatchlist.TotalResults > 0)
                        {
                            if (traktWatchlistMovies != null)
                            {
                                UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                                moviesInWatchlist.Movies.RemoveAll(w => traktWatchlistMovies.FirstOrDefault(t => t.Movie.Ids.TmdbId == w.Id) != null);
                            }

                            if (traktWatchedMovies != null)
                            {
                                UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watched on trakt.tv");
                                moviesInWatchlist.Movies.RemoveAll(m => traktWatchedMovies.Any(c => c.Movie.Ids.TmdbId == m.Id));
                            }

                            UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages, moviesInWatchlist.Movies.Count);

                            if (moviesInWatchlist.Movies.Count > 0)
                            {
                                var response = TraktAPI.AddMoviesToWatchlist(GetSyncMoviesData(moviesInWatchlist.Movies));
                                if (response == null)
                                {
                                    UIUtils.UpdateStatus("Failed to send watchlist for TMDb movies", true);
                                    Thread.Sleep(2000);
                                }
                                else if (response.NotFound.Movies.Count > 0)
                                {
                                    UIUtils.UpdateStatus("Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                                    Thread.Sleep(1000);
                                }
                                if (importCancelled)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
                if (importCancelled)
                {
                    return;
                }
                #endregion

                #region Shows
                IEnumerable <TraktShowPlays> traktWatchedShows = null;

                UIUtils.UpdateStatus("Getting first batch of TMDb watchlist shows...");
                var showsInWatchlist = TMDbAPI.GetWatchlistShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1);
                if (importCancelled)
                {
                    return;
                }

                if (showsInWatchlist != null || showsInWatchlist.TotalResults > 0)
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist shows from trakt...");
                    var traktWatchlistShows = TraktAPI.GetWatchlistShows();
                    if (traktWatchlistShows != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", traktWatchlistShows.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                        showsInWatchlist.Shows.RemoveAll(w => traktWatchlistShows.FirstOrDefault(t => t.Show.Ids.TmdbId == w.Id) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist)
                    {
                        UIUtils.UpdateStatus("Retrieving existing watched shows from trakt.tv.");
                        traktWatchedShows = TraktAPI.GetWatchedShows();

                        if (traktWatchedShows != null)
                        {
                            UIUtils.UpdateStatus("Found {0} watched shows on trakt.tv", traktWatchedShows.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watched on trakt.tv");
                            showsInWatchlist.Shows.RemoveAll(s => traktWatchedShows.Any(c => c.Show.Ids.TmdbId == s.Id));
                        }
                    }

                    UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages, showsInWatchlist.Shows.Count);

                    if (showsInWatchlist.Shows.Count > 0)
                    {
                        var response = TraktAPI.AddShowsToWatchlist(GetSyncShowsData(showsInWatchlist.Shows));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for TMDb shows.", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }
                        if (importCancelled)
                        {
                            return;
                        }
                    }

                    // get each page of movies
                    for (int i = 2; i <= showsInWatchlist.TotalPages; i++)
                    {
                        UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages);
                        showsInWatchlist = TMDbAPI.GetWatchlistShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i);
                        if (importCancelled)
                        {
                            return;
                        }

                        if (showsInWatchlist != null || showsInWatchlist.TotalResults > 0)
                        {
                            if (traktWatchlistShows != null)
                            {
                                UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", traktWatchlistShows.Count());
                                UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                                showsInWatchlist.Shows.RemoveAll(w => traktWatchlistShows.FirstOrDefault(t => t.Show.Ids.TmdbId == w.Id) != null);
                            }

                            if (traktWatchedShows != null)
                            {
                                UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watched on trakt.tv");
                                showsInWatchlist.Shows.RemoveAll(s => traktWatchedShows.Any(c => c.Show.Ids.TmdbId == s.Id));
                            }

                            UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages, showsInWatchlist.Shows.Count);

                            if (showsInWatchlist.Shows.Count > 0)
                            {
                                var response = TraktAPI.AddShowsToWatchlist(GetSyncShowsData(showsInWatchlist.Shows));
                                if (response == null)
                                {
                                    UIUtils.UpdateStatus("Failed to send watchlist for TMDb shows", true);
                                    Thread.Sleep(2000);
                                }
                                else if (response.NotFound.Shows.Count > 0)
                                {
                                    UIUtils.UpdateStatus("Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                                    Thread.Sleep(1000);
                                }
                                if (importCancelled)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
                if (importCancelled)
                {
                    return;
                }
                #endregion
            }

            #endregion
        }
Example #20
0
        public void ImportRatings()
        {
            importCancelled = false;

            List <Dictionary <string, string> > watchlistMovies = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > watchlistShows  = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > ratedItems      = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > watchlistItems  = new List <Dictionary <string, string> >();

            #region Download Data
            UIUtils.UpdateStatus("Requesting ratings from IMDb.com...");

            int count;
            int movieIndex     = 1;
            int movieIncrement = 250;

            #region Ratings
            do
            {
                count = ratedItems.Count;
                UIUtils.UpdateStatus("Requesting ratings {0} - {1}, Total Results: {2}", movieIndex, (movieIncrement + movieIndex - 1), count);
                string url      = "http://www.imdb.com/user/" + username + "/ratings?start=" + movieIndex + "&view=compact";
                string response = TraktWeb.Transmit(url, null, false);
                if (response == null)
                {
                    break;
                }
                int begin = 0;

                // only log response when set to trace as it's very verbose in this case
                if (AppSettings.LogSeverityLevel >= AppSettings.LoggingSeverity.Trace)
                {
                    FileLog.Trace("Response: {0}", response);
                }

                while ((begin = response.IndexOf("<tr data-item-id", begin)) > 0)
                {
                    var    rateItem = new Dictionary <string, string>();
                    string sub      = response.Substring(begin, response.IndexOf("</tr>", begin) - begin);

                    Regex reg = new Regex("<td class=\"title[^\"]*\"><a href=\"/title/(?<cIMDbID>tt\\d+)/[^\"]*\">(?<cTitle>[^<]+)</a>(?:\\s*<br>\\s*Episode:\\s*<a href=\"/title/(?<cEpisodeID>tt\\d+)/[^\"]*\">(?<cEpisodeTitle>[^<]+)</a>)?</td>");

                    // Get IMDb ID
                    var find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cIMDbID, find.Groups["cIMDbID"].ToString());

                    // Get Title
                    // If it's a TV Episode then include both show and episode title
                    if (!string.IsNullOrEmpty(find.Groups["cEpisodeTitle"].ToString()))
                    {
                        rateItem.Add(IMDbFieldMapping.cTitle, string.Format("{0}: {1}", find.Groups["cTitle"], find.Groups["cEpisodeTitle"]));
                    }
                    else
                    {
                        rateItem.Add(IMDbFieldMapping.cTitle, find.Groups["cTitle"].ToString());
                    }

                    // Get User Rating
                    reg  = new Regex("<td class=\"your_ratings\">\\n    <a>([1-9][0-9]{0,1})</a>\\n</td>");
                    find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cRating, find.Groups[1].ToString());

                    // Get Year
                    reg  = new Regex("<td class=\"year\">([1-2][0-9]{3})</td>");
                    find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cYear, find.Groups[1].ToString());

                    // Get Type
                    reg  = new Regex("<td class=\"title_type\"> (.*)</td>");
                    find = reg.Match(sub);
                    if (find.Groups[1].ToString() == string.Empty)
                    {
                        rateItem.Add(IMDbFieldMapping.cType, "Feature Film");
                    }
                    else
                    {
                        rateItem.Add(IMDbFieldMapping.cType, find.Groups[1].ToString());
                    }

                    // Set provider to web or csv
                    rateItem.Add(IMDbFieldMapping.cProvider, "web");

                    ratedItems.Add(rateItem);

                    begin += 10;
                }
                // fetch next page
                movieIndex += movieIncrement;
            }while (count < ratedItems.Count);
            #endregion

            #region Watchlist
            if (AppSettings.IMDbSyncWatchlist)
            {
                UIUtils.UpdateStatus("Reading IMDb watchlist from web...");
                movieIndex     = 1;
                movieIncrement = 100;

                do
                {
                    count = watchlistItems.Count;
                    UIUtils.UpdateStatus("Requesting watchlist items {0} - {1}, Total Results: {2}", movieIndex, (movieIncrement + movieIndex - 1), count);
                    string url      = "http://www.imdb.com/user/" + username + "/watchlist?start=" + movieIndex + "&view=compact";
                    string response = TraktWeb.Transmit(url, null, false);
                    if (response == null)
                    {
                        break;
                    }
                    int begin = 0;

                    // only log response when set to trace as it's very verbose in this case
                    if (AppSettings.LogSeverityLevel >= AppSettings.LoggingSeverity.Trace)
                    {
                        FileLog.Trace("Response: {0}", response);
                    }

                    if (response == null)
                    {
                        continue;
                    }

                    while ((begin = response.IndexOf("<tr data-item-id", begin)) > 0)
                    {
                        var watchListItem = new Dictionary <string, string>();
                        var sub           = response.Substring(begin, response.IndexOf("</tr>", begin) - begin);

                        Regex reg = new Regex("<td class=\"title[^\"]*\"><a href=\"/title/(?<cIMDbID>tt\\d+)/[^\"]*\">(?<cTitle>[^<]+)</a>(?:\\s*<br>\\s*Episode:\\s*<a href=\"/title/(?<cEpisodeID>tt\\d+)/[^\"]*\">(?<cEpisodeTitle>[^<]+)</a>)?</td>");

                        // Get IMDb ID
                        var find = reg.Match(sub);
                        watchListItem.Add(IMDbFieldMapping.cIMDbID, find.Groups["cIMDbID"].ToString());

                        // Get Title
                        // If it's a TV Episode then include both show and episode title
                        if (!string.IsNullOrEmpty(find.Groups["cEpisodeTitle"].ToString()))
                        {
                            watchListItem.Add(IMDbFieldMapping.cTitle, string.Format("{0}: {1}", find.Groups["cTitle"], find.Groups["cEpisodeTitle"]));
                        }
                        else
                        {
                            watchListItem.Add(IMDbFieldMapping.cTitle, find.Groups["cTitle"].ToString());
                        }

                        // Get Year
                        reg  = new Regex("<td class=\"year\">([1-2][0-9]{3})</td>");
                        find = reg.Match(sub);
                        watchListItem.Add(IMDbFieldMapping.cYear, find.Groups[1].ToString());

                        // Get Type
                        reg  = new Regex("<td class=\"title_type\"> (.*)</td>");
                        find = reg.Match(sub);
                        if (find.Groups[1].ToString() == string.Empty)
                        {
                            watchListItem.Add(IMDbFieldMapping.cType, "Feature Film");
                        }
                        else
                        {
                            watchListItem.Add(IMDbFieldMapping.cType, find.Groups[1].ToString());
                        }

                        // Set provider to web or csv
                        watchListItem.Add(IMDbFieldMapping.cProvider, "web");

                        watchlistItems.Add(watchListItem);

                        begin += 10;
                    }
                    // fetch next page
                    movieIndex += movieIncrement;
                }while (count < watchlistItems.Count);
            }
            #endregion
            #endregion

            if (importCancelled)
            {
                return;
            }

            #region Sync Ratings
            #region Movies
            var movies = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            if (movies.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus(string.Format("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count()));
                    // Filter out movies to rate from existing ratings online
                    movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.ImdbId == m[IMDbFieldMapping.cIMDbID]));
                }

                UIUtils.UpdateStatus("Importing {0} new IMDb movie ratings to trakt.tv", movies.Count());

                if (movies.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)movies.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(Helper.GetRateMoviesData(movies.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region TV Shows
            var shows = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Show && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            if (shows.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
                var currentUserShowRatings = TraktAPI.GetRatedShows();

                if (currentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv show ratings on trakt.tv", currentUserShowRatings.Count());
                    // Filter out shows to rate from existing ratings online
                    shows.RemoveAll(s => currentUserShowRatings.Any(c => (c.Show.Ids.ImdbId == s[IMDbFieldMapping.cIMDbID]) || (c.Show.Title == s[IMDbFieldMapping.cTitle] && c.Show.Year.ToString() == s[IMDbFieldMapping.cYear])));
                }

                if (shows.Count > 0)
                {
                    UIUtils.UpdateStatus("Importing {0} new IMDb tv show ratings to trakt.tv", shows.Count());

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)shows.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated shows...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddShowsToRatings(Helper.GetRateShowsData(shows.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb show ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Episodes
            var imdbEpisodes = new List <IMDbEpisode>();
            var episodes     = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Episode).ToList();
            if (episodes.Any())
            {
                // we can't rely on the imdb id as trakt most likely wont have the info for episodes

                // search and cache all series info needed for syncing
                // use the tvdb API to first search for each unique series name
                // then GetSeries by TVDb ID to get a list of all episodes
                // each episode will have TVDb ID which we can use for syncing.

                imdbEpisodes.AddRange(episodes.Select(Helper.GetIMDbEpisodeFromTVDb).Where(imdbEpisode => imdbEpisode != null));

                UIUtils.UpdateStatus("Retrieving existing tv episode ratings from trakt.tv");
                var currentUserEpisodeRatings = TraktAPI.GetRatedEpisodes();

                if (currentUserEpisodeRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv episode ratings on trakt.tv", currentUserEpisodeRatings.Count());

                    // Filter out episodes to rate from existing ratings online
                    imdbEpisodes.RemoveAll(e => currentUserEpisodeRatings.Any(c => c.Episode.Ids.TvdbId == e.TvdbId));
                }

                UIUtils.UpdateStatus("Importing {0} episode ratings to trakt.tv", imdbEpisodes.Count());

                if (imdbEpisodes.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)imdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesRated = Helper.GetTraktEpisodeRateData(imdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated episodes...", i + 1, pages);

                        var response = TraktAPI.AddsEpisodesToRatings(episodesRated);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb episodes as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion
            #endregion

            #region Mark as Watched
            IEnumerable <TraktMoviePlays> watchedTraktMovies = null;

            if (AppSettings.MarkAsWatched)
            {
                #region Movies
                // compare all movies rated against what's not watched on trakt
                movies = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
                if (movies.Count > 0)
                {
                    // get watched movies from trakt.tv
                    UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                    watchedTraktMovies = TraktAPI.GetWatchedMovies();
                    if (watchedTraktMovies == null)
                    {
                        UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                        Thread.Sleep(2000);
                    }
                    else
                    {
                        if (importCancelled)
                        {
                            return;
                        }

                        UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                        movies.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);

                        // mark all rated movies as watched
                        UIUtils.UpdateStatus("Importing {0} IMDb movies as watched...", movies.Count);

                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)movies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} IMDb movies as watched...", i + 1, pages);

                            var response = TraktAPI.AddMoviesToWatchedHistory(Helper.GetSyncWatchedMoviesData(movies.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (response == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watched status for IMDb movies", true);
                                Thread.Sleep(2000);
                            }
                            else if (response.NotFound.Movies.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watched state for {0} IMDb movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                                Thread.Sleep(1000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion

                #region Episodes

                if (imdbEpisodes != null && imdbEpisodes.Any())
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)imdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesWatched = Helper.GetTraktEpisodeWatchedData(imdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watched episodes...", i + 1, pages);

                        var response = TraktAPI.AddEpisodesToWatchedHistory(episodesWatched);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes as watched to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync {0} IMDb episodes as watched, as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion
            }
            #endregion

            #region Sync Watchlist
            if (AppSettings.IMDbSyncWatchlist)
            {
                #region Movies
                watchlistMovies.AddRange(watchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie));
                if (watchlistMovies.Any())
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                    var watchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                    if (watchlistTraktMovies != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", watchlistTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                        watchlistMovies.RemoveAll(w => watchlistTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && movies.Count > 0)
                    {
                        UIUtils.UpdateStatus("Requesting watched movies from trakt...");

                        // get watched movies from trakt so we don't import movies into watchlist that are already watched
                        if (watchedTraktMovies != null)
                        {
                            watchedTraktMovies = TraktAPI.GetWatchedMovies();
                            if (watchedTraktMovies == null)
                            {
                                UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                                UIUtils.UpdateStatus("Filtering out watchlist movies that are watched on trakt.tv");

                                // remove movies from sync list which are watched already
                                watchlistMovies.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                            }
                        }
                    }

                    // add all movies to watchlist
                    UIUtils.UpdateStatus("Importing {0} IMDb watchlist movies to trakt.tv ...", watchlistMovies.Count());

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)watchlistMovies.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb movies into watchlist...", i + 1, pages);

                        var response = TraktAPI.AddMoviesToWatchlist(Helper.GetSyncMoviesData(watchlistMovies.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for IMDb movies.", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion

                #region TV Shows
                IEnumerable <TraktShowPlays> watchedTraktShows = null;
                watchlistShows.AddRange(watchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Show));
                if (watchlistShows.Any())
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist shows from trakt...");
                    var watchlistTraktShows = TraktAPI.GetWatchlistShows();
                    if (watchlistTraktShows != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", watchlistTraktShows.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                        watchlistShows.RemoveAll(w => watchlistTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Show.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle].ToLowerInvariant() && t.Show.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && shows.Count > 0)
                    {
                        UIUtils.UpdateStatus("Requesting watched shows from trakt...");

                        // get watched movies from trakt so we don't import shows into watchlist that are already watched
                        watchedTraktShows = TraktAPI.GetWatchedShows();
                        if (watchedTraktShows != null)
                        {
                            UIUtils.UpdateStatus("Found {0} watched shows on trakt", watchedTraktShows.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist shows containing watched episodes on trakt.tv");

                            // remove shows from sync list which are watched already
                            watchlistShows.RemoveAll(w => watchedTraktShows.Count(t => (t.Show.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID]) || (t.Show.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle].ToLowerInvariant() && t.Show.Year.ToString() == w[IMDbFieldMapping.cYear])) != 0);
                        }
                    }

                    //add all shows to watchlist
                    UIUtils.UpdateStatus("Importing {0} IMDb watchlist shows to trakt.tv...", watchlistShows.Count());

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)watchlistShows.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb shows into watchlist...", i + 1, pages);

                        var response = TraktAPI.AddShowsToWatchlist(Helper.GetSyncShowsData(watchlistShows.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for IMDb tv shows", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion

                #region Episodes
                imdbEpisodes.Clear();
                episodes = watchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Episode).ToList();
                if (episodes.Any())
                {
                    UIUtils.UpdateStatus("Found {0} IMDb watchlist episodes", episodes.Count());

                    imdbEpisodes.AddRange(episodes.Select(Helper.GetIMDbEpisodeFromTVDb).Where(imdbEpisode => imdbEpisode != null));

                    // filter out existing watchlist episodes
                    UIUtils.UpdateStatus("Requesting existing watchlist episodes from trakt...");
                    var watchlistTraktEpisodes = TraktAPI.GetWatchlistEpisodes();
                    if (watchlistTraktEpisodes != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist episodes on trakt", watchlistTraktEpisodes.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist episodes that are already in watchlist on trakt.tv");
                        imdbEpisodes.RemoveAll(e => watchlistTraktEpisodes.FirstOrDefault(w => w.Episode.Ids.ImdbId == e.ImdbId || w.Episode.Ids.TvdbId == e.TvdbId) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && episodes.Count > 0)
                    {
                        // we already might have it from the shows sync
                        if (watchedTraktShows == null)
                        {
                            UIUtils.UpdateStatus("Requesting watched episodes from trakt...");

                            // get watched episodes from trakt so we don't import episodes into watchlist that are already watched
                            watchedTraktShows = TraktAPI.GetWatchedShows();
                        }

                        if (watchedTraktShows != null)
                        {
                            UIUtils.UpdateStatus("Filtering out watchlist episodes containing watched episodes on trakt.tv.");

                            imdbEpisodes.RemoveAll(e => watchedTraktShows.Where(s => s.Show.Ids.ImdbId == e.ImdbId)
                                                   .Any(s => s.Seasons.Exists(se => se.Number == e.SeasonNumber && se.Episodes.Exists(ep => ep.Number == e.EpisodeNumber))));
                        }
                    }

                    UIUtils.UpdateStatus("Importing {0} episodes in watchlist to trakt.tv", imdbEpisodes.Count());

                    if (imdbEpisodes.Count > 0)
                    {
                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)imdbEpisodes.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus(string.Format("Importing page {0}/{1} IMDb watchlist episodes...", i + 1, pages));

                            var response = TraktAPI.AddEpisodesToWatchlist(Helper.GetTraktEpisodeData(imdbEpisodes.Skip(i * pageSize).Take(pageSize)));
                            if (response == null)
                            {
                                UIUtils.UpdateStatus("Error importing IMDb episode watchlist to trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                            else if (response.NotFound.Episodes.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb episodes as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                                Thread.Sleep(1000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion
            }
            #endregion
        }
Example #21
0
        public bool SyncSeries()
        {
            TraktLogger.Info("Series Library Starting Sync");

            // store list of series ids so we can update the episode counts
            // of any series that syncback watched flags
            var seriesToUpdateEpisodeCounts = new HashSet <int>();

            #region Get online data from cache

            #region UnWatched / Watched

            List <TraktCache.EpisodeWatched> traktWatchedEpisodes = null;

            // get all episodes on trakt that are marked as 'unseen'
            var traktUnWatchedEpisodes = TraktCache.GetUnWatchedEpisodesFromTrakt().ToNullableList();
            if (traktUnWatchedEpisodes == null)
            {
                TraktLogger.Error("Error getting tv shows unwatched from trakt.tv server, unwatched and watched sync will be skipped");
            }
            else
            {
                TraktLogger.Info("Found {0} unwatched tv episodes in trakt.tv library", traktUnWatchedEpisodes.Count());

                // now get all episodes on trakt that are marked as 'seen' or 'watched' (this will be cached already when working out unwatched)
                traktWatchedEpisodes = TraktCache.GetWatchedEpisodesFromTrakt().ToNullableList();
                if (traktWatchedEpisodes == null)
                {
                    TraktLogger.Error("Error getting tv shows watched from trakt.tv server, watched sync will be skipped");
                }
                else
                {
                    TraktLogger.Info("Found {0} watched tv episodes in trakt.tv library", traktWatchedEpisodes.Count());
                }
            }

            #endregion

            #region Collection

            // get all episodes on trakt that are marked as in 'collection'
            var traktCollectedEpisodes = TraktCache.GetCollectedEpisodesFromTrakt().ToNullableList();
            if (traktCollectedEpisodes == null)
            {
                TraktLogger.Error("Error getting tv episode collection from trakt.tv server");
            }
            else
            {
                TraktLogger.Info("Found {0} tv episodes in trakt.tv collection", traktCollectedEpisodes.Count());
            }

            #endregion

            #region Ratings

            #region Episodes

            //var traktRatedEpisodes = TraktCache.GetRatedEpisodesFromTrakt().ToNullableList();
            //if (traktRatedEpisodes == null)
            //{
            //  TraktLogger.Error("Error getting rated episodes from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} rated tv episodes in trakt.tv library", traktRatedEpisodes.Count());
            //}

            #endregion

            #region Shows

            //var traktRatedShows = TraktCache.GetRatedShowsFromTrakt().ToNullableList();
            //if (traktRatedShows == null)
            //{
            //  TraktLogger.Error("Error getting rated shows from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} rated tv shows in trakt.tv library", traktRatedShows.Count());
            //}

            #endregion

            #region Seasons

            //var traktRatedSeasons = TraktCache.GetRatedSeasonsFromTrakt().ToNullableList();
            //if (traktRatedSeasons == null)
            //{
            //  TraktLogger.Error("Error getting rated seasons from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} rated tv seasons in trakt.tv library", traktRatedSeasons.Count());
            //}

            #endregion

            #endregion

            #region Watchlist

            #region Shows

            //var traktWatchlistedShows = TraktCache.GetWatchlistedShowsFromTrakt();
            //if (traktWatchlistedShows == null)
            //{
            //  TraktLogger.Error("Error getting watchlisted shows from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} watchlisted tv shows in trakt.tv library", traktWatchlistedShows.Count());
            //}

            #endregion

            #region Seasons

            //var traktWatchlistedSeasons = TraktCache.GetWatchlistedSeasonsFromTrakt();
            //if (traktWatchlistedSeasons == null)
            //{
            //  TraktLogger.Error("Error getting watchlisted seasons from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} watchlisted tv seasons in trakt.tv library", traktWatchlistedSeasons.Count());
            //}

            #endregion

            #region Episodes

            //var traktWatchlistedEpisodes = TraktCache.GetWatchlistedEpisodesFromTrakt();
            //if (traktWatchlistedEpisodes == null)
            //{
            //  TraktLogger.Error("Error getting watchlisted episodes from trakt.tv server");
            //}
            //else
            //{
            //  TraktLogger.Info("Found {0} watchlisted tv episodes in trakt.tv library", traktWatchlistedEpisodes.Count());
            //}

            #endregion

            #endregion

            #endregion

            if (traktCollectedEpisodes != null)
            {
                try
                {
                    TestStatus = "[Trakt.SyncSeries]";
                    Guid[]         types            = { MediaAspect.ASPECT_ID, SeriesAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID };
                    MediaItemQuery mediaItemQuery   = new MediaItemQuery(types, null, null);
                    var            contentDirectory = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
                    if (contentDirectory == null)
                    {
                        TestStatus = "[Trakt.MediaLibraryNotConnected]";
                        return(false);
                    }

                    #region Get data from local database

                    var localEpisodes = contentDirectory.Search(mediaItemQuery, true);
                    int episodeCount  = localEpisodes.Count;

                    TraktLogger.Info("Found {0} total episodes in local database", episodeCount);

                    // get the episodes that we have watched
                    var localWatchedEpisodes = localEpisodes.Where(IsWatched).ToList();

                    TraktLogger.Info("Found {0} episodes watched in tvseries database", localWatchedEpisodes.Count);

                    #endregion

                    #region Add episodes to watched history at trakt.tv
                    int showCount    = 0;
                    int iSyncCounter = 0;
                    if (traktWatchedEpisodes != null)
                    {
                        var syncWatchedShows = GetWatchedShowsForSyncEx(localWatchedEpisodes, traktWatchedEpisodes);

                        TraktLogger.Info("Found {0} local tv show(s) with {1} watched episode(s) to add to trakt.tv watched history", syncWatchedShows.Shows.Count, syncWatchedShows.Shows.Sum(sh => sh.Seasons.Sum(se => se.Episodes.Count())));

                        showCount = syncWatchedShows.Shows.Count;
                        foreach (var show in syncWatchedShows.Shows)
                        {
                            int showEpisodeCount = show.Seasons.Sum(s => s.Episodes.Count());
                            TraktLogger.Info("Adding tv show [{0}/{1}] to trakt.tv episode watched history, Episode Count = '{2}', Show Title = '{3}', Show Year = '{4}', Show TVDb ID = '{5}', Show IMDb ID = '{6}'",
                                             ++iSyncCounter, showCount, showEpisodeCount, show.Title, show.Year.HasValue ? show.Year.ToString() : "<empty>", show.Ids.Tvdb, show.Ids.Imdb ?? "<empty>");

                            show.Seasons.ForEach(s => s.Episodes.ForEach(e =>
                            {
                                TraktLogger.Info("Adding episode to trakt.tv watched history, Title = '{0} - {1}x{2}', Watched At = '{3}'", show.Title, s.Number, e.Number, e.WatchedAt.ToLogString());
                            }));

                            // only sync one show at a time regardless of batch size in settings
                            var pagedShows = new List <TraktSyncShowWatchedEx>();
                            pagedShows.Add(show);

                            var response = TraktAPI.AddShowsToWatchedHistoryEx(new TraktSyncShowsWatchedEx {
                                Shows = pagedShows
                            });
                            TraktLogger.LogTraktResponse <TraktSyncResponse>(response);

                            // only add to cache if it was a success
                            // note: we don't get back the same object type so makes it hard to figure out what failed
                            if (response != null && response.Added != null && response.Added.Episodes == showEpisodeCount)
                            {
                                // update local cache
                                TraktCache.AddEpisodesToWatchHistory(show);
                            }
                        }
                    }
                    #endregion

                    #region Add episodes to collection at trakt.tv

                    if (traktCollectedEpisodes != null)
                    {
                        var syncCollectedShows = GetCollectedShowsForSyncEx(localEpisodes, traktCollectedEpisodes);

                        TraktLogger.Info("Found {0} local tv show(s) with {1} collected episode(s) to add to trakt.tv collection", syncCollectedShows.Shows.Count, syncCollectedShows.Shows.Sum(sh => sh.Seasons.Sum(se => se.Episodes.Count())));

                        iSyncCounter = 0;
                        showCount    = syncCollectedShows.Shows.Count;
                        foreach (var show in syncCollectedShows.Shows)
                        {
                            int showEpisodeCount = show.Seasons.Sum(s => s.Episodes.Count());
                            TraktLogger.Info("Adding tv show [{0}/{1}] to trakt.tv episode collection, Episode Count = '{2}', Show Title = '{3}', Show Year = '{4}', Show TVDb ID = '{5}', Show IMDb ID = '{6}'",
                                             ++iSyncCounter, showCount, showEpisodeCount, show.Title, show.Year.HasValue ? show.Year.ToString() : "<empty>", show.Ids.Tvdb, show.Ids.Imdb ?? "<empty>");

                            show.Seasons.ForEach(s => s.Episodes.ForEach(e =>
                            {
                                TraktLogger.Info("Adding episode to trakt.tv collection, Title = '{0} - {1}x{2}', Collected At = '{3}', Audio Channels = '{4}', Audio Codec = '{5}', Resolution = '{6}', Media Type = '{7}', Is 3D = '{8}'", show.Title, s.Number, e.Number, e.CollectedAt.ToLogString(), e.AudioChannels.ToLogString(), e.AudioCodec.ToLogString(), e.Resolution.ToLogString(), e.MediaType.ToLogString(), e.Is3D);
                            }));

                            // only sync one show at a time regardless of batch size in settings
                            var pagedShows = new List <TraktSyncShowCollectedEx>();
                            pagedShows.Add(show);

                            var response = TraktAPI.AddShowsToCollectonEx(new TraktSyncShowsCollectedEx {
                                Shows = pagedShows
                            });
                            TraktLogger.LogTraktResponse <TraktSyncResponse>(response);

                            // only add to cache if it was a success
                            if (response != null && response.Added != null && response.Added.Episodes == showEpisodeCount)
                            {
                                // update local cache
                                TraktCache.AddEpisodesToCollection(show);
                            }
                        }
                    }
                    #endregion
                    return(true);
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex);
                }
            }
            return(false);
        }
Example #22
0
        public void ImportRatings()
        {
            mImportCancelled = false;

            var lRateItems      = new List <Dictionary <string, string> >();
            var lWatchlistItems = new List <Dictionary <string, string> >();
            var lCustomLists    = new Dictionary <string, List <Dictionary <string, string> > >();

            #region Parse Ratings CSV
            UIUtils.UpdateStatus("Reading IMDb ratings export...");
            if (mImportCsvRatings && !ParseCSVFile(mRatingsFileCsv, out lRateItems))
            {
                UIUtils.UpdateStatus("Failed to parse IMDb ratings file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Watchlist CSV
            UIUtils.UpdateStatus("Reading IMDb watchlist export...");
            if (mImportCsvWatchlist && !ParseCSVFile(mWatchlistFileCsv, out lWatchlistItems))
            {
                UIUtils.UpdateStatus("Failed to parse IMDb watchlist file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Custom List CSVs
            UIUtils.UpdateStatus("Reading IMDb custom lists export...");
            if (mImportCsvCustomLists)
            {
                foreach (var list in mCustomListsCsvs)
                {
                    UIUtils.UpdateStatus("Reading IMDb custom list '{0}' export...", list);
                    var lCustomList = new List <Dictionary <string, string> >();

                    if (!ParseCSVFile(list, out lCustomList))
                    {
                        UIUtils.UpdateStatus("Failed to parse IMDb custom list file!", true);
                        Thread.Sleep(2000);
                        return;
                    }

                    lCustomLists.Add(list, lCustomList);
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Movies
            var lMovies = lRateItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            FileLog.Info("Found {0} movie ratings in CSV file", lMovies.Count);
            if (lMovies.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var lCurrentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (lCurrentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", lCurrentUserMovieRatings.Count());
                    // Filter out movies to rate from existing ratings online
                    lMovies.RemoveAll(m => lCurrentUserMovieRatings.Any(c => c.Movie.Ids.ImdbId == m[IMDbFieldMapping.cIMDbID]));
                }

                UIUtils.UpdateStatus("Importing {0} new movie ratings to trakt.tv", lMovies.Count());

                if (lMovies.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lMovies.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(Helper.GetRateMoviesData(lMovies.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated TV Shows
            var lShows = lRateItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Show && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            FileLog.Info("Found {0} tv show ratings in CSV file", lShows.Count);
            if (lShows.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
                var currentUserShowRatings = TraktAPI.GetRatedShows();

                if (currentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv show ratings on trakt.tv", currentUserShowRatings.Count());
                    // Filter out shows to rate from existing ratings online
                    lShows.RemoveAll(s => currentUserShowRatings.Any(c => (c.Show.Ids.ImdbId == s[IMDbFieldMapping.cIMDbID]) || (c.Show.Title == s[IMDbFieldMapping.cTitle] && c.Show.Year.ToString() == s[IMDbFieldMapping.cYear])));
                }

                UIUtils.UpdateStatus("Importing {0} tv show ratings to trakt.tv", lShows.Count());

                if (lShows.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lShows.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated shows...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddShowsToRatings(Helper.GetRateShowsData(lShows.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb tv show ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Episodes
            var lImdbEpisodes    = new List <IMDbEpisode>();
            var lImdbCsvEpisodes = lRateItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Episode).ToList();
            FileLog.Info("Found {0} tv episode ratings in CSV file", lImdbCsvEpisodes.Count);
            if (lImdbCsvEpisodes.Any())
            {
                // we can't rely on the imdb id as trakt most likely wont have the info for episodes

                // search and cache all series info needed for syncing
                // use the tvdb API to first search for each unique series name
                // then GetSeries by TVDb ID to get a list of all episodes
                // each episode will have TVDb ID which we can use for syncing.

                lImdbEpisodes.AddRange(lImdbCsvEpisodes.Select(Helper.GetIMDbEpisodeFromTVDb).Where(imdbEpisode => imdbEpisode != null));

                UIUtils.UpdateStatus("Retrieving existing tv episode ratings from trakt.tv");
                var currentUserEpisodeRatings = TraktAPI.GetRatedEpisodes();

                if (currentUserEpisodeRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv episode ratings on trakt.tv", currentUserEpisodeRatings.Count());

                    // Filter out episodes to rate from existing ratings online
                    lImdbEpisodes.RemoveAll(e => currentUserEpisodeRatings.Any(c => c.Episode.Ids.TvdbId == e.TvdbId || c.Episode.Ids.ImdbId == e.ImdbId));
                }

                UIUtils.UpdateStatus("Importing {0} episode ratings to trakt.tv", lImdbEpisodes.Count());

                if (lImdbEpisodes.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lImdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesRated = Helper.GetTraktEpisodeRateData(lImdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated episodes...", i + 1, pages);

                        var response = TraktAPI.AddsEpisodesToRatings(episodesRated);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb episodes as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Mark Rated Items as Watched
            IEnumerable <TraktMoviePlays> lWatchedTraktMovies = null;

            if (AppSettings.MarkAsWatched)
            {
                #region Movies
                // compare all movies rated against what's not watched on trakt
                lMovies = lRateItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie).ToList();
                FileLog.Info("Found {0} movies in CSV file", lMovies.Count);
                if (lMovies.Count > 0)
                {
                    // get watched movies from trakt.tv
                    UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                    lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                    if (lWatchedTraktMovies == null)
                    {
                        UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                        Thread.Sleep(2000);
                    }
                    else
                    {
                        if (mImportCancelled)
                        {
                            return;
                        }

                        UIUtils.UpdateStatus("Found {0} watched movies on trakt", lWatchedTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                        lMovies.RemoveAll(w => lWatchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);

                        // mark all rated movies as watched
                        UIUtils.UpdateStatus("Importing {0} IMDb movies as watched...", lMovies.Count);

                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)lMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} IMDb movies as watched...", i + 1, pages);

                            var response = TraktAPI.AddMoviesToWatchedHistory(Helper.GetSyncWatchedMoviesData(lMovies.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (response == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watched status for IMDb movies to trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                            else if (response.NotFound.Movies.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                                Thread.Sleep(1000);
                            }
                            if (mImportCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion

                #region Episodes
                if (lImdbEpisodes != null && lImdbEpisodes.Any())
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lImdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesWatched = Helper.GetTraktEpisodeWatchedData(lImdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watched episodes...", i + 1, pages);

                        var response = TraktAPI.AddEpisodesToWatchedHistory(episodesWatched);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes as watched to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync {0} IMDb episodes as watched, as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion
            }
            #endregion

            #region Import Watchlist Movies
            lMovies = lWatchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie).ToList();
            FileLog.Info("Found {0} movies watchlisted in CSV file", lMovies.Count);
            if (lMovies.Any())
            {
                UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                var watchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                if (watchlistTraktMovies != null)
                {
                    UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", watchlistTraktMovies.Count());
                    UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                    lMovies.RemoveAll(w => watchlistTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lMovies.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting watched movies from trakt...");

                    // get watched movies from trakt so we don't import movies into watchlist that are already watched
                    if (lWatchedTraktMovies != null)
                    {
                        lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                        if (lWatchedTraktMovies == null)
                        {
                            UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                    }

                    if (lWatchedTraktMovies != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watched movies on trakt", lWatchedTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are watched on trakt.tv");

                        // remove movies from sync list which are watched already
                        lMovies.RemoveAll(w => lWatchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                    }
                }

                // add movies to watchlist
                UIUtils.UpdateStatus("Importing {0} IMDb watchlist movies to trakt.tv...", lMovies.Count());

                int pageSize = AppSettings.BatchSize;
                int pages    = (int)Math.Ceiling((double)lMovies.Count / pageSize);
                for (int i = 0; i < pages; i++)
                {
                    UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watchlist movies...", i + 1, pages);

                    var response = TraktAPI.AddMoviesToWatchlist(Helper.GetSyncMoviesData(lMovies.Skip(i * pageSize).Take(pageSize).ToList()));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Failed to send watchlist for IMDb movies", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Movies.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                        Thread.Sleep(1000);
                    }

                    if (mImportCancelled)
                    {
                        return;
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watchlist TV Shows
            IEnumerable <TraktShowPlays> watchedTraktShows = null;
            lShows = lWatchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Show).ToList();
            FileLog.Info("Found {0} tv shows watchlisted in CSV file", lShows.Count);
            if (lShows.Any())
            {
                UIUtils.UpdateStatus("Requesting existing watchlist shows from trakt...");
                var watchlistTraktShows = TraktAPI.GetWatchlistShows();
                if (watchlistTraktShows != null)
                {
                    UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", watchlistTraktShows.Count());
                    UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                    lShows.RemoveAll(w => watchlistTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Show.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle].ToLowerInvariant() && t.Show.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lShows.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting watched shows from trakt...");

                    // get watched movies from trakt so we don't import shows into watchlist that are already watched
                    watchedTraktShows = TraktAPI.GetWatchedShows();
                    if (watchedTraktShows != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watched shows on trakt", watchedTraktShows.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist shows containing watched episodes on trakt.tv.");

                        // remove shows from sync list which are watched already
                        lShows.RemoveAll(w => watchedTraktShows.FirstOrDefault(t => (t.Show.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID]) || (t.Show.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle].ToLowerInvariant() && t.Show.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);
                    }
                }

                // add shows to watchlist
                UIUtils.UpdateStatus("Importing {0} IMDb watchlist shows to trakt.tv...", lShows.Count());

                int pageSize = AppSettings.BatchSize;
                int pages    = (int)Math.Ceiling((double)lShows.Count / pageSize);
                for (int i = 0; i < pages; i++)
                {
                    UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watchlist shows...", i + 1, pages);

                    var response = TraktAPI.AddShowsToWatchlist(Helper.GetSyncShowsData(lShows.Skip(i * pageSize).Take(pageSize)));
                    if (response == null)
                    {
                        UIUtils.UpdateStatus("Failed to send watchlist for IMDb tv shows", true);
                        Thread.Sleep(2000);
                    }
                    else if (response.NotFound.Shows.Count > 0)
                    {
                        UIUtils.UpdateStatus("Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                        Thread.Sleep(1000);
                    }

                    if (mImportCancelled)
                    {
                        return;
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watchlist Episodes
            lImdbEpisodes.Clear();
            lImdbCsvEpisodes = lWatchlistItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Episode).ToList();
            FileLog.Info("Found {0} tv episodes watchlisted in CSV file", lImdbCsvEpisodes.Count);
            if (lImdbCsvEpisodes.Any())
            {
                UIUtils.UpdateStatus("Found {0} IMDb watchlist episodes", lImdbCsvEpisodes.Count());

                lImdbEpisodes.AddRange(lImdbCsvEpisodes.Select(Helper.GetIMDbEpisodeFromTVDb).Where(imdbEpisode => imdbEpisode != null));

                // filter out existing watchlist episodes
                UIUtils.UpdateStatus("Requesting existing watchlist episodes from trakt...");
                var watchlistTraktEpisodes = TraktAPI.GetWatchlistEpisodes();
                if (watchlistTraktEpisodes != null)
                {
                    UIUtils.UpdateStatus("Found {0} watchlist episodes on trakt", watchlistTraktEpisodes.Count());
                    UIUtils.UpdateStatus("Filtering out watchlist episodes that are already in watchlist on trakt.tv");
                    lImdbEpisodes.RemoveAll(e => watchlistTraktEpisodes.FirstOrDefault(w => w.Episode.Ids.ImdbId == e.ImdbId || w.Episode.Ids.TvdbId == e.TvdbId) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lImdbEpisodes.Count > 0)
                {
                    // we already might have it from the shows sync
                    if (watchedTraktShows == null)
                    {
                        UIUtils.UpdateStatus("Requesting watched episodes from trakt...");

                        // get watched episodes from trakt so we don't import episodes into watchlist that are already watched
                        watchedTraktShows = TraktAPI.GetWatchedShows();
                    }

                    if (watchedTraktShows != null)
                    {
                        UIUtils.UpdateStatus("Filtering out watchlist episodes containing watched episodes on trakt.tv");

                        lImdbEpisodes.RemoveAll(e => watchedTraktShows.Where(s => s.Show.Ids.ImdbId == e.ImdbId)
                                                .Any(s => s.Seasons.Exists(se => se.Number == e.SeasonNumber && se.Episodes.Exists(ep => ep.Number == e.EpisodeNumber))));
                    }
                }

                UIUtils.UpdateStatus("Importing {0} episodes in watchlist to trakt.tv", lImdbEpisodes.Count());

                if (lImdbEpisodes.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lImdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watchlist episodes...", i + 1, pages);

                        var response = TraktAPI.AddEpisodesToWatchlist(Helper.GetTraktEpisodeData(lImdbEpisodes.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episode watchlist to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb episodes as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion

            #region Import Custom Lists
            if (lCustomLists.Count > 0)
            {
                UIUtils.UpdateStatus("Requesting custom lists from trakt...");
                var lTraktCustomLists = TraktAPI.GetCustomLists();
                if (lTraktCustomLists == null)
                {
                    UIUtils.UpdateStatus("Error requesting custom lists from trakt.tv", true);
                    Thread.Sleep(2000);
                    return;
                }

                UIUtils.UpdateStatus("Found {0} custom lists on trakt.tv", lTraktCustomLists.Count());

                foreach (var list in lCustomLists)
                {
                    bool   lListCreated = false;
                    string lListName    = Path.GetFileNameWithoutExtension(list.Key);

                    // create the list if we don't have it
                    TraktListDetail lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                    if (lTraktCustomList == null)
                    {
                        UIUtils.UpdateStatus("Creating new custom list '{0}' on trakt.tv", lListName);
                        var lTraktList = new TraktList
                        {
                            Name           = lListName,
                            DisplayNumbers = true,
                        };

                        lTraktCustomList = TraktAPI.CreateCustomList(lTraktList);
                        if (lTraktCustomList == null)
                        {
                            UIUtils.UpdateStatus("Error creating custom list on trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        lListCreated = true;
                    }

                    // get the CSV list items parsed
                    var lIMDbListItems = list.Value;

                    var lImdbListMovies = lIMDbListItems.Where(l => l.ItemType() == IMDbType.Movie).ToList();
                    var lImdbListShows  = lIMDbListItems.Where(l => l.ItemType() == IMDbType.Show).ToList();

                    // if the list already exists, get current items for list
                    if (!lListCreated)
                    {
                        lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                        UIUtils.UpdateStatus("Requesting existing custom list '{0}' items from trakt...", lListName);
                        var lTraktListItems = TraktAPI.GetCustomListItems(lTraktCustomList.Ids.Trakt.ToString());
                        if (lTraktListItems == null)
                        {
                            UIUtils.UpdateStatus("Error requesting custom list items on trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        // filter out existing items from CSV so we don't send again
                        FileLog.Info("Filtering out existing items from IMDb list '{0}' so we don't send again to trakt.tv", lListName);
                        lImdbListMovies.RemoveAll(d => d.ItemType() == IMDbType.Movie && lTraktListItems.FirstOrDefault(l => l.Movie.Ids.ImdbId == d[IMDbFieldMapping.cIMDbID]) != null);
                        lImdbListShows.RemoveAll(d => d.ItemType() == IMDbType.Show && lTraktListItems.FirstOrDefault(l => l.Show.Ids.ImdbId == d[IMDbFieldMapping.cIMDbID]) != null);
                    }

                    #region Movies

                    UIUtils.UpdateStatus("Importing {0} movies into {1} custom list...", lImdbListMovies.Count(), lListName);

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lImdbListMovies.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb custom list movies...", i + 1, pages);

                        // create list sync object to hold list items
                        var lTraktMovieSync = new TraktSyncAll
                        {
                            Movies = Helper.GetSyncMoviesData(lImdbListMovies.Skip(i * pageSize).Take(pageSize).ToList()).Movies
                        };

                        var response = TraktAPI.AddItemsToList(lTraktCustomList.Ids.Trakt.ToString(), lTraktMovieSync);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send custom list items for IMDb movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync custom list items for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                    #endregion

                    #region Shows

                    UIUtils.UpdateStatus("Importing {0} shows into {1} custom list...", lImdbListShows.Count(), lListName);

                    pageSize = AppSettings.BatchSize;
                    pages    = (int)Math.Ceiling((double)lImdbListShows.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb custom list shows...", i + 1, pages);

                        // create list sync object to hold list items
                        var lTraktShowSync = new TraktSyncAll
                        {
                            Shows = Helper.GetSyncShowsData(lImdbListShows.Skip(i * pageSize).Take(pageSize).ToList()).Shows
                        };

                        var response = TraktAPI.AddItemsToList(lTraktCustomList.Ids.Trakt.ToString(), lTraktShowSync);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send custom list items for IMDb shows", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync custom list items for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }

                    #endregion
                }
            }
            #endregion
        }
Example #23
0
        public bool SyncSeries()
        {
            try
            {
                TestStatus = "[Trakt.SyncSeries]";
                Guid[] types = { MediaAspect.ASPECT_ID, SeriesAspect.ASPECT_ID };

                MediaItemQuery mediaItemQuery   = new MediaItemQuery(types, null, null);
                var            contentDirectory = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
                if (contentDirectory == null)
                {
                    TestStatus = "[Trakt.MediaLibraryNotConnected]";
                    return(false);
                }
                var episodes = contentDirectory.Search(mediaItemQuery, true);

                var series = episodes.ToLookup(GetSeriesKey);
                foreach (var serie in series)
                {
                    var imdbId = serie.Select(episode =>
                    {
                        string value;
                        return(MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) ? value : null);
                    }).FirstOrDefault(value => !string.IsNullOrWhiteSpace(value));

                    var tvdbId = serie.Select(episode =>
                    {
                        int value;
                        return(MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_TVDB_ID, out value) ? value : 0);
                    }).FirstOrDefault(value => value != 0);

                    TraktEpisodeSync syncData = new TraktEpisodeSync
                    {
                        UserName    = Username,
                        Password    = Password,
                        EpisodeList = new List <TraktEpisodeSync.Episode>(),
                        Title       = serie.Key,
                        Year        = serie.Min(e =>
                        {
                            int year;
                            string seriesTitle;
                            GetSeriesTitleAndYear(e, out seriesTitle, out year);
                            return(year);
                        }).ToString()
                    };

                    if (!string.IsNullOrWhiteSpace(imdbId))
                    {
                        syncData.IMDBID = imdbId;
                    }

                    if (tvdbId > 0)
                    {
                        syncData.SeriesID = tvdbId.ToString();
                    }

                    HashSet <TraktEpisodeSync.Episode> uniqueEpisodes = new HashSet <TraktEpisodeSync.Episode>();
                    foreach (var episode in serie)
                    {
                        string seriesTitle;
                        int    year = 0;
                        if (!GetSeriesTitle/*AndYear*/ (episode, out seriesTitle /*, out year*/))
                        {
                            continue;
                        }

                        // First send all movies to Trakt that we have so they appear in library
                        CollectionUtils.AddAll(uniqueEpisodes, ToSeries(episode));
                    }
                    syncData.EpisodeList = uniqueEpisodes.ToList();

                    TraktSyncModes traktSyncMode = TraktSyncModes.library;
                    var            response      = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode);
                    ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error);

                    // Then send only the watched movies as "seen"
                    uniqueEpisodes.Clear();
                    foreach (var seenEpisode in episodes.Where(IsWatched))
                    {
                        CollectionUtils.AddAll(uniqueEpisodes, ToSeries(seenEpisode));
                    }
                    syncData.EpisodeList = uniqueEpisodes.ToList();

                    traktSyncMode = TraktSyncModes.seen;
                    response      = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode);
                    ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex);
            }
            return(false);
        }
Example #24
0
        public void ImportRatings()
        {
            var lRateItems    = new List <Dictionary <string, string> >();
            var lWatchedItems = new List <Dictionary <string, string> >();
            var lDiaryItems   = new List <Dictionary <string, string> >();
            var lCustomLists  = new Dictionary <string, List <LetterboxdListItem> >();

            mImportCancelled = false;

            #region Parse Ratings CSV
            UIUtils.UpdateStatus("Reading Letterboxd ratings export...");
            if (mImportRatings && !ParseCSVFile(mLetterboxdRatingsFile, out lRateItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd ratings file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Watched CSV
            UIUtils.UpdateStatus("Reading Letterboxd watched export...");
            if (mImportWatched && !ParseCSVFile(mLetterboxdWatchedFile, out lWatchedItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd watched file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Diary CSV
            UIUtils.UpdateStatus("Reading Letterboxd diary export...");
            if (mImportDiary && !ParseCSVFile(mLetterboxdDiaryFile, out lDiaryItems))
            {
                UIUtils.UpdateStatus("Failed to parse Letterboxd diary file!", true);
                Thread.Sleep(2000);
                return;
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Custom List CSVs
            UIUtils.UpdateStatus("Reading Letterboxd custom lists export...");
            if (mImportCustomLists)
            {
                mCsvConfiguration.RegisterClassMap <LetterboxdListCsvMap>();

                foreach (var list in mCustomListsCsvs)
                {
                    UIUtils.UpdateStatus($"Reading Letterboxd custom list '{list}'");

                    var lListCsvItems = ParseCsvFile <LetterboxdListItem>(list);
                    if (lListCsvItems == null)
                    {
                        UIUtils.UpdateStatus("Failed to parse Letterboxd custom list file!", true);
                        Thread.Sleep(2000);
                        continue;
                    }
                    lCustomLists.Add(list, lListCsvItems);
                }
                mCsvConfiguration.UnregisterClassMap <LetterboxdListCsvMap>();
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Movies
            FileLog.Info("Found {0} movie ratings in CSV file", lRateItems.Count);
            if (lRateItems.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count());
                    // Filter out movies to rate from existing ratings online
                    lRateItems.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Title == m[LetterboxdFieldMapping.cTitle] && c.Movie.Year.ToString() == m[LetterboxdFieldMapping.cYear]));
                }

                UIUtils.UpdateStatus("Importing {0} new movie ratings to trakt.tv", lRateItems.Count());

                if (lRateItems.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lRateItems.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Letterboxd rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(lRateItems.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing Letterboxd movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync Letterboxd ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watched Movies

            // The Dairy can can include rated and watched items, it also has a watched date
            // if the watched movie exists in the diary use that as a watched date otherwise use date from watched file

            // add to diary any watched films that have been back filled
            foreach (var movie in lWatchedItems)
            {
                if (!lDiaryItems.Exists(d => d[LetterboxdFieldMapping.cTitle] == movie[LetterboxdFieldMapping.cTitle] && d[LetterboxdFieldMapping.cYear] == movie[LetterboxdFieldMapping.cYear]))
                {
                    lDiaryItems.Add(movie);
                }
            }

            if (lDiaryItems.Count > 0)
            {
                // get watched movies from trakt.tv
                UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                var watchedTraktMovies = TraktAPI.GetWatchedMovies();
                if (watchedTraktMovies == null)
                {
                    UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                    Thread.Sleep(2000);
                }
                else
                {
                    if (mImportCancelled)
                    {
                        return;
                    }

                    UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                    UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                    lDiaryItems.RemoveAll(d => watchedTraktMovies.FirstOrDefault(t => t.Movie.Title == d[LetterboxdFieldMapping.cTitle] && t.Movie.Year.ToString() == d[LetterboxdFieldMapping.cYear]) != null);

                    UIUtils.UpdateStatus("Importing {0} Letterboxd movies as watched...", lDiaryItems.Count);

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lDiaryItems.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Letterboxd movies as watched...", i + 1, pages);

                        var response = TraktAPI.AddMoviesToWatchedHistory(GetSyncWatchedMoviesData(lDiaryItems.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watched status for Letterboxd movies to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync Letterboxd watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }
                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion

            #region Import Custom Lists
            if (lCustomLists.Count > 0)
            {
                UIUtils.UpdateStatus("Requesting custom lists from trakt...");
                var lTraktCustomLists = TraktAPI.GetCustomLists();
                if (lTraktCustomLists == null)
                {
                    UIUtils.UpdateStatus("Error requesting custom lists from trakt.tv", true);
                    Thread.Sleep(2000);
                    return;
                }

                UIUtils.UpdateStatus($"Found {lTraktCustomLists.Count()} custom lists on trakt.tv");

                foreach (var list in lCustomLists)
                {
                    bool   lListCreated = false;
                    string lListName    = Path.GetFileNameWithoutExtension(list.Key);

                    // create the list if we don't have it
                    TraktListDetail lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                    if (lTraktCustomList == null)
                    {
                        UIUtils.UpdateStatus($"Creating new custom list '{lListName}' on trakt.tv");
                        var lTraktList = new TraktList
                        {
                            Name           = lListName,
                            DisplayNumbers = true,
                        };

                        lTraktCustomList = TraktAPI.CreateCustomList(lTraktList);
                        if (lTraktCustomList == null)
                        {
                            UIUtils.UpdateStatus("Error creating custom list on trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        lListCreated = true;
                    }

                    FileLog.Info($"Found {list.Value.Count} movies in Letterboxd {lListName} list");

                    // if the list already exists, get current items for list
                    if (!lListCreated)
                    {
                        lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                        UIUtils.UpdateStatus($"Requesting existing custom list '{lListName}' items from trakt...");
                        var lTraktListItems = TraktAPI.GetCustomListItems(lTraktCustomList.Ids.Trakt.ToString());
                        if (lTraktListItems == null)
                        {
                            UIUtils.UpdateStatus("Error requesting custom list items from trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        // filter out existing items from CSV so we don't send again
                        FileLog.Info($"Filtering out existing items from Letterboxd list '{lListName}' so we don't send again to trakt.tv");
                        list.Value.RemoveAll(i => lTraktListItems.FirstOrDefault(l => l.Movie.Title.ToLowerInvariant() == i.Title.ToLowerInvariant() && l.Movie.Year == i.Year) != null);
                    }

                    UIUtils.UpdateStatus($"Importing {list.Value.Count} new movies into {lListName} custom list...");

                    var lLetterboxdCsvListMovies = list.Value.Select(m => m.ToTraktMovie());

                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = ( int )Math.Ceiling(( double )list.Value.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} Letterboxd custom list movies...");

                        // create list sync object to hold list items
                        var lTraktMovieSync = new TraktSyncAll
                        {
                            Movies = lLetterboxdCsvListMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        var lResponse = TraktAPI.AddItemsToList(lTraktCustomList.Ids.Trakt.ToString(), lTraktMovieSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send custom list items for Letterboxd movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync custom list items for {lResponse.NotFound.Movies.Count} movies as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion
        }
Example #25
0
        public void ImportRatings()
        {
            var criticker = CritickerAPI.ReadCritickerMovieExportFile(critickerMovieFile);

            // check if everything we need was read okay
            if (criticker == null || criticker.Films == null)
            {
                UIUtils.UpdateStatus("Error reading Criticker movie XML file", true);
                return;
            }

            UIUtils.UpdateStatus("Found {0} movies with ratings", criticker.Films.Count);
            if (importCancelled)
            {
                return;
            }

            #region Import Ratings

            if (criticker.Films.Count > 0)
            {
                // get current trakt ratings
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();
                if (importCancelled)
                {
                    return;
                }

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count());

                    // filter out movies to rate from existing ratings online
                    UIUtils.UpdateStatus("Filtering out movies which are already rated");
                    criticker.Films.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Title.ToLowerInvariant() == m.Title.ToLowerInvariant() && c.Movie.Year == m.Year));
                }

                UIUtils.UpdateStatus(string.Format("Importing {0} Criticker movie ratings...", criticker.Films.Count));
                if (criticker.Films.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)criticker.Films.Count() / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Criticker movie ratings...", i + 1, pages);

                        var movies   = GetRateMoviesData(criticker.Films.Skip(i * pageSize).Take(pageSize).ToList());
                        var response = TraktAPI.AddMoviesToRatings(movies);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send ratings for Criticker movies.", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Mark As Watched

            if (AppSettings.MarkAsWatched)
            {
                if (importCancelled)
                {
                    return;
                }

                // mark all movies as watched if rated
                UIUtils.UpdateStatus("Importing {0} Criticker movies as watched...", criticker.Films.Count);
                if (criticker.Films.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)criticker.Films.Count() / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Criticker movies as watched...", i + 1, pages);

                        var watchedResponse = TraktAPI.AddMoviesToWatchedHistory(GetSyncMoviesData(criticker.Films.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (watchedResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watched status for Criticker movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (watchedResponse.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watched for {0} movies as they're not found on trakt.tv!", watchedResponse.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }

            #endregion
        }
Example #26
0
        public static void SynchronizeLibrary(List <DBEpisode> episodes, TraktSyncModes mode)
        {
            if (episodes.Count == 0)
            {
                return;
            }

            // get unique series ids
            var uniqueSeriesIDs = (from seriesIDs in episodes
                                   select seriesIDs[DBEpisode.cSeriesID].ToString()).Distinct().ToList();

            // go over each series, can only send one series at a time
            foreach (string seriesID in uniqueSeriesIDs)
            {
                DBSeries series = Helper.getCorrespondingSeries(int.Parse(seriesID));
                if (series == null || series[DBOnlineSeries.cTraktIgnore])
                {
                    continue;
                }

                MPTVSeriesLog.Write("Trakt: Synchronizing '{0}' episodes for series '{1}'.", mode.ToString(), series.ToString());

                TraktSync traktSync = GetTraktSyncObject(series, episodes);

                // upload to trakt
                TraktResponse response = TraktAPI.SyncEpisodeLibrary(traktSync, mode);
                if (response == null)
                {
                    MPTVSeriesLog.Write("Trakt Error: Response from server was unexpected.");
                    continue;
                }

                // check for any error and log result
                CheckTraktErrorAndNotify(response, false);

                if (response.Status == "success")
                {
                    SQLCondition conditions = new SQLCondition();

                    // flag episodes and commit to database
                    switch (mode)
                    {
                    case TraktSyncModes.seen:
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, seriesID, SQLConditionType.Equal);
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cWatched, 1, SQLConditionType.Equal);
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cHidden, 0, SQLConditionType.Equal);
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 0, SQLConditionType.Equal);

                        // we always flag traktLibrary field as the 'traktSeen' field counts as part of library
                        DBOnlineEpisode.GlobalSet(new DBOnlineEpisode(), DBOnlineEpisode.cTraktLibrary, 1, conditions);
                        DBOnlineEpisode.GlobalSet(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 1, conditions);
                        break;

                    case TraktSyncModes.library:
                        // we can't do a global set as our conditions are from two different tables
                        // where filename is not empty and traktLibrary = 0
                        foreach (DBEpisode ep in episodes.Where(e => e[DBEpisode.cSeriesID] == seriesID))
                        {
                            ep[DBOnlineEpisode.cTraktLibrary] = 1;
                            ep.Commit();
                        }
                        break;

                    case TraktSyncModes.unseen:
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, seriesID, SQLConditionType.Equal);
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cHidden, 0, SQLConditionType.Equal);
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 2, SQLConditionType.Equal);
                        DBOnlineEpisode.GlobalSet(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 0, conditions);
                        break;

                    case TraktSyncModes.unlibrary:
                        break;
                    }
                }

                // wait a short period before uploading another series
                Thread.Sleep(2000);
            }
        }
Example #27
0
        public void ImportRatings()
        {
            importCancelled = false;

            List <Dictionary <string, string> > watchlistMovies = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > watchlistShows  = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > ratedItems      = new List <Dictionary <string, string> >();
            List <Dictionary <string, string> > watchlistItems  = new List <Dictionary <string, string> >();
            List <IMDbListItem> lWatchlistItems = new List <IMDbListItem>();

            #region Download Data
            UIUtils.UpdateStatus("Requesting ratings from IMDb.com...");

            int    movieIndex     = 0;
            int    movieIncrement = 100;
            string paginationKey  = string.Empty;
            Regex  reg;
            Match  find;

            #region Ratings
            do
            {
                UIUtils.UpdateStatus("Requesting ratings {0} - {1}, Total Results: {2}", movieIndex + 1, (movieIncrement + movieIndex), ratedItems.Count);
                string url = "http://www.imdb.com/user/" + username + "/ratings?sort=date_added%2Cdesc&mode=detail&lastPosition=" + movieIndex
                             + (string.IsNullOrEmpty(paginationKey) ? string.Empty : "&paginationKey=" + paginationKey);

                string response = TraktWeb.Transmit(url, null, false);
                if (response == null)
                {
                    break;
                }

                int begin = 0;

                // only log response when set to trace as it's very verbose in this case
                if (AppSettings.LogSeverityLevel >= AppSettings.LoggingSeverity.Trace)
                {
                    FileLog.Trace("Response: {0}", response);
                }

                while ((begin = response.IndexOf("lister-item-content", begin)) > 0)
                {
                    var    rateItem = new Dictionary <string, string>();
                    string sub      = response.Substring(begin, response.IndexOf("class=\"clear\"", begin) - begin);

                    reg = new Regex("<a href=\"/title/(?<cIMDbID>tt\\d+)/[^\"]*\"\n>(?<cTitle>[^<]*)</a>(?:[.\\s\\S]*Episode:</small>\\s*<a href=\"/title/(?<cEpisodeID>tt\\d+)/[^\"]*\"\n*>(?<cEpisodeTitle>[^<]+)</a>){0,1}");

                    // Get IMDb ID
                    find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cIMDbID, find.Groups["cIMDbID"].ToString());

                    // Get Title
                    // If it's a TV Episode then include both show and episode title
                    if (!string.IsNullOrEmpty(find.Groups["cEpisodeTitle"].ToString()))
                    {
                        rateItem.Add(IMDbFieldMapping.cTitle, string.Format("{0}: {1}", find.Groups["cTitle"], find.Groups["cEpisodeTitle"]));
                    }
                    else
                    {
                        rateItem.Add(IMDbFieldMapping.cTitle, find.Groups["cTitle"].ToString());
                    }

                    // Get User Rating
                    reg  = new Regex("<span class=\"ipl-rating-star__rating\">([1-9][0-9]{0,1})</span>");
                    find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cRating, find.Groups[1].ToString());

                    // Get Year
                    reg  = new Regex("<span class=\"lister-item-year text-muted unbold\">\\(([1-2][0-9]{3}).*\\)</span>");
                    find = reg.Match(sub);
                    rateItem.Add(IMDbFieldMapping.cYear, find.Groups[1].ToString());

                    // Get Type
                    reg  = new Regex("<span class=\"lister-item-year text-muted unbold\">\\(([1-2][0-9]{3}–).*\\)</span>");
                    find = reg.Match(sub);
                    if (find.Groups[1].ToString() == string.Empty)
                    {
                        rateItem.Add(IMDbFieldMapping.cType, "Feature Film");
                    }
                    else
                    {
                        rateItem.Add(IMDbFieldMapping.cType, "tvseries");
                    }

                    // Set provider to web or csv
                    rateItem.Add(IMDbFieldMapping.cProvider, "web");

                    ratedItems.Add(rateItem);

                    begin += 10;
                }
                // fetch next page
                movieIndex += movieIncrement;

                reg           = new Regex("<a class=\"flat-button lister-page-next next-page\" href=.*&paginationKey=(?<cPaginationKey>.*)&");
                find          = reg.Match(response);
                paginationKey = find.Groups["cPaginationKey"].ToString();
            }while (movieIndex == ratedItems.Count);
            #endregion

            #region Watchlist
            if (AppSettings.IMDbSyncWatchlist)
            {
                UIUtils.UpdateStatus("Reading IMDb watchlist from web...");

                string url      = "http://www.imdb.com/user/" + username + "/watchlist";
                string response = TraktWeb.Transmit(url, null, false);
                if (response != null)
                {
                    var sub = response.Substring(0, response.IndexOf("</head>", 0));
                    reg = new Regex("ls\\d+");

                    // Get IMDb Watchlist ID
                    find = reg.Match(sub);

                    url = "http://www.imdb.com/list/" + find.Value + "/export";

                    using (StreamReader reader = TraktWeb.GetCsvStream(url))
                    {
                        if (reader == null)
                        {
                            UIUtils.UpdateStatus("Failed to download watchlist from IMDb.", true);
                            Thread.Sleep(2000);
                        }
                        else
                        {
                            lWatchlistItems = ParseCsvFile <IMDbListItem>(reader);
                            if (lWatchlistItems == null)
                            {
                                UIUtils.UpdateStatus("Failed to parse IMDb watchlist file!", true);
                                Thread.Sleep(2000);
                            }
                        }
                    }
                }

                // only log response when set to trace as it's very verbose in this case
                if (AppSettings.LogSeverityLevel >= AppSettings.LoggingSeverity.Trace)
                {
                    FileLog.Trace("Response: {0}", response);
                }
            }
            #endregion
            #endregion

            if (importCancelled)
            {
                return;
            }

            #region Sync Ratings
            #region Movies
            var movies = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            if (movies.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var currentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (currentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus(string.Format("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count()));
                    // Filter out movies to rate from existing ratings online
                    movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.ImdbId == m[IMDbFieldMapping.cIMDbID]));
                }

                UIUtils.UpdateStatus("Importing {0} new IMDb movie ratings to trakt.tv", movies.Count());

                if (movies.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)movies.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(Helper.GetRateMoviesData(movies.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region TV Shows
            var shows = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Show && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
            if (shows.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
                var currentUserShowRatings = TraktAPI.GetRatedShows();

                if (currentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv show ratings on trakt.tv", currentUserShowRatings.Count());
                    // Filter out shows to rate from existing ratings online
                    shows.RemoveAll(s => currentUserShowRatings.Any(c => (c.Show.Ids.ImdbId == s[IMDbFieldMapping.cIMDbID]) || (c.Show.Title == s[IMDbFieldMapping.cTitle] && c.Show.Year.ToString() == s[IMDbFieldMapping.cYear])));
                }

                if (shows.Count > 0)
                {
                    UIUtils.UpdateStatus("Importing {0} new IMDb tv show ratings to trakt.tv", shows.Count());

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)shows.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated shows...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddShowsToRatings(Helper.GetRateShowsData(shows.Skip(i * pageSize).Take(pageSize)));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb show ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion

            #region Episodes
            var imdbEpisodes = new List <IMDbEpisode>();
            var episodes     = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Episode).ToList();
            if (episodes.Any())
            {
                // we can't rely on the imdb id as trakt most likely wont have the info for episodes

                // search and cache all series info needed for syncing
                // use the tvdb API to first search for each unique series name
                // then GetSeries by TVDb ID to get a list of all episodes
                // each episode will have TVDb ID which we can use for syncing.

                imdbEpisodes.AddRange(episodes.Select(Helper.GetIMDbEpisodeFromTrakt).Where(imdbEpisode => imdbEpisode != null));

                UIUtils.UpdateStatus("Retrieving existing tv episode ratings from trakt.tv");
                var currentUserEpisodeRatings = TraktAPI.GetRatedEpisodes();

                if (currentUserEpisodeRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user tv episode ratings on trakt.tv", currentUserEpisodeRatings.Count());

                    // Filter out episodes to rate from existing ratings online
                    imdbEpisodes.RemoveAll(e => currentUserEpisodeRatings.Any(c => c.Episode.Ids.Trakt == e.TraktId));
                }

                UIUtils.UpdateStatus("Importing {0} episode ratings to trakt.tv", imdbEpisodes.Count());

                if (imdbEpisodes.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)imdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesRated = Helper.GetTraktEpisodeRateData(imdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb rated episodes...", i + 1, pages);

                        var response = TraktAPI.AddsEpisodesToRatings(episodesRated);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} IMDb episodes as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (importCancelled)
            {
                return;
            }
            #endregion
            #endregion

            #region Mark as Watched
            IEnumerable <TraktMoviePlays> watchedTraktMovies = null;

            if (AppSettings.MarkAsWatched)
            {
                #region Movies
                // compare all movies rated against what's not watched on trakt
                movies = ratedItems.Where(r => r[IMDbFieldMapping.cType].ItemType() == IMDbType.Movie && !string.IsNullOrEmpty(r[IMDbFieldMapping.cRating])).ToList();
                if (movies.Count > 0)
                {
                    // get watched movies from trakt.tv
                    UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                    watchedTraktMovies = TraktAPI.GetWatchedMovies();
                    if (watchedTraktMovies == null)
                    {
                        UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                        Thread.Sleep(2000);
                    }
                    else
                    {
                        if (importCancelled)
                        {
                            return;
                        }

                        UIUtils.UpdateStatus("Found {0} watched movies on trakt", watchedTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                        movies.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w[IMDbFieldMapping.cIMDbID] || (t.Movie.Title.ToLowerInvariant() == w[IMDbFieldMapping.cTitle] && t.Movie.Year.ToString() == w[IMDbFieldMapping.cYear])) != null);

                        // mark all rated movies as watched
                        UIUtils.UpdateStatus("Importing {0} IMDb movies as watched...", movies.Count);

                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)movies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} IMDb movies as watched...", i + 1, pages);

                            var response = TraktAPI.AddMoviesToWatchedHistory(Helper.GetSyncWatchedMoviesData(movies.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (response == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watched status for IMDb movies", true);
                                Thread.Sleep(2000);
                            }
                            else if (response.NotFound.Movies.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watched state for {0} IMDb movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                                Thread.Sleep(1000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion

                #region Episodes

                if (imdbEpisodes != null && imdbEpisodes.Any())
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)imdbEpisodes.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        var episodesWatched = Helper.GetTraktEpisodeWatchedData(imdbEpisodes.Skip(i * pageSize).Take(pageSize));

                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb watched episodes...", i + 1, pages);

                        var response = TraktAPI.AddEpisodesToWatchedHistory(episodesWatched);
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes as watched to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync {0} IMDb episodes as watched, as they're not found on trakt.tv!", response.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion
            }
            #endregion

            #region Sync Watchlist
            if (AppSettings.IMDbSyncWatchlist)
            {
                #region Movies
                var lWatchlistedMovies = lWatchlistItems.Where(r => r.Type.ItemType() == IMDbType.Movie)
                                         .Select(s => s.ToTraktMovie()).ToList();
                if (lWatchlistedMovies.Any())
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                    var lWatchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                    if (lWatchlistTraktMovies != null)
                    {
                        UIUtils.UpdateStatus($"Found {0} watchlist movies on trakt", lWatchlistTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                        lWatchlistedMovies.RemoveAll(w => lWatchlistTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                               (t.Movie.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Movie.Year == w.Year)) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && lWatchlistedMovies.Count > 0)
                    {
                        // get watched movies from trakt so we don't import movies into watchlist that are already watched
                        // we may already have this if we imported rated items as watched
                        if (watchedTraktMovies == null)
                        {
                            UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                            watchedTraktMovies = TraktAPI.GetWatchedMovies();
                            if (watchedTraktMovies == null)
                            {
                                UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                        }

                        if (watchedTraktMovies != null)
                        {
                            UIUtils.UpdateStatus($"Found {0} watched movies on trakt", watchedTraktMovies.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist movies that are watched on trakt.tv");

                            // remove movies from sync list which are watched already
                            lWatchlistedMovies.RemoveAll(w => watchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                                (t.Movie.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Movie.Year == w.Year)) != null);
                        }
                    }

                    // add movies to watchlist
                    UIUtils.UpdateStatus($"Importing {0} IMDb watchlist movies to trakt.tv...", lWatchlistedMovies.Count());

                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lWatchlistedMovies.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {0}/{1} IMDb watchlist movies...", i + 1, lPages);

                        var lWatchlistedToSync = new TraktMovieSync()
                        {
                            Movies = lWatchlistedMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        var lResponse = TraktAPI.AddMoviesToWatchlist(lWatchlistedToSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for IMDb movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", lResponse.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                if (importCancelled)
                {
                    return;
                }
                #endregion

                #region TV Shows
                IEnumerable <TraktShowPlays> lWatchedTraktShows = null;
                var lWatchlistedShows = lWatchlistItems.Where(r => r.Type.ItemType() == IMDbType.Show)
                                        .Select(s => s.ToTraktShow()).ToList();
                if (lWatchlistedShows.Any())
                {
                    UIUtils.UpdateStatus("Requesting existing watchlisted shows from trakt...");
                    var lWatchlistTraktShows = TraktAPI.GetWatchlistShows();
                    if (lWatchlistTraktShows != null)
                    {
                        UIUtils.UpdateStatus($"Found {0} watchlist shows on trakt", lWatchlistTraktShows.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                        lWatchlistedShows.RemoveAll(w => lWatchlistTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                             (t.Show.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Show.Year == w.Year)) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && lWatchlistedShows.Count > 0)
                    {
                        UIUtils.UpdateStatus("Requesting watched shows from trakt...");

                        // get watched movies from trakt so we don't import shows into watchlist that are already watched
                        lWatchedTraktShows = TraktAPI.GetWatchedShows();
                        if (lWatchedTraktShows != null)
                        {
                            UIUtils.UpdateStatus($"Found {0} watched shows on trakt", lWatchedTraktShows.Count());
                            UIUtils.UpdateStatus("Filtering out watchlist shows containing watched episodes on trakt.tv.");

                            // remove shows from sync list which are watched already
                            lWatchlistedShows.RemoveAll(w => lWatchedTraktShows.FirstOrDefault(t => (t.Show.Ids.ImdbId == w.Ids.ImdbId) ||
                                                                                               (t.Show.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Show.Year == w.Year)) != null);
                        }
                    }

                    // add shows to watchlist
                    UIUtils.UpdateStatus($"Importing {0} IMDb watchlist shows to trakt.tv...", lWatchlistedShows.Count());

                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lWatchlistedShows.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {0}/{1} IMDb watchlist shows...", i + 1, lPages);

                        var lWatchlistShowsToSync = new TraktShowSync
                        {
                            Shows = lWatchlistedShows.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        var lResponse = TraktAPI.AddShowsToWatchlist(lWatchlistShowsToSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watchlist for IMDb tv shows", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", lResponse.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (importCancelled)
                        {
                            return;
                        }
                    }
                }
                if (importCancelled)
                {
                    return;
                }
                #endregion

                #region Episodes
                var lImdbEpisodes            = new List <IMDbEpisode>();
                var lImdbWatchlistedEpisodes = lWatchlistItems.Where(r => r.Type.ItemType() == IMDbType.Episode).ToList();

                if (lImdbWatchlistedEpisodes.Any())
                {
                    UIUtils.UpdateStatus($"Found {0} IMDb watchlisted episodes", lImdbWatchlistedEpisodes.Count());

                    lImdbEpisodes.AddRange(lImdbWatchlistedEpisodes.Select(Helper.GetIMDbEpisodeFromTrakt).Where(imdbEpisode => imdbEpisode != null));
                    if (importCancelled)
                    {
                        return;
                    }

                    // filter out existing watchlist episodes
                    UIUtils.UpdateStatus("Requesting existing watchlist episodes from trakt...");
                    var lWatchlistedTraktEpisodes = TraktAPI.GetWatchlistEpisodes();
                    if (lWatchlistedTraktEpisodes != null)
                    {
                        UIUtils.UpdateStatus($"Found {0} watchlist episodes on trakt", lWatchlistedTraktEpisodes.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist episodes that are already in watchlist on trakt.tv");
                        lImdbEpisodes.RemoveAll(e => lWatchlistedTraktEpisodes.FirstOrDefault(w => w.Episode.Ids.Trakt == e.TraktId) != null);
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist && lImdbEpisodes.Count > 0)
                    {
                        // we already might have it from the shows sync
                        if (lWatchedTraktShows == null)
                        {
                            UIUtils.UpdateStatus("Requesting watched episodes from trakt...");

                            // get watched episodes from trakt so we don't import episodes into watchlist that are already watched
                            lWatchedTraktShows = TraktAPI.GetWatchedShows();
                        }

                        if (lWatchedTraktShows != null)
                        {
                            UIUtils.UpdateStatus("Filtering out watchlist episodes containing watched episodes on trakt.tv");

                            // this wont work atm due to show IMDb ID not being set in the IMDbEpisode object
                            lImdbEpisodes.RemoveAll(e => lWatchedTraktShows.Where(s => s.Show.Ids.ImdbId == e.ShowImdbId)
                                                    .Any(s => s.Seasons.Exists(se => se.Number == e.SeasonNumber &&
                                                                               se.Episodes.Exists(ep => ep.Number == e.EpisodeNumber))));
                        }
                    }

                    UIUtils.UpdateStatus($"Importing {0} episodes in watchlist to trakt.tv", lImdbEpisodes.Count());

                    if (lImdbEpisodes.Count > 0)
                    {
                        int lPageSize = AppSettings.BatchSize;
                        int lPages    = (int)Math.Ceiling((double)lImdbEpisodes.Count / lPageSize);
                        for (int i = 0; i < lPages; i++)
                        {
                            UIUtils.UpdateStatus($"Importing page {0}/{1} IMDb watchlisted episodes...", i + 1, lPages);

                            var lResponse = TraktAPI.AddEpisodesToWatchlist(Helper.GetTraktEpisodeData(lImdbEpisodes.Skip(i * lPageSize).Take(lPageSize)));
                            if (lResponse == null)
                            {
                                UIUtils.UpdateStatus("Error importing IMDb episode watchlist to trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                            else if (lResponse.NotFound.Episodes.Count > 0)
                            {
                                UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb episodes as they're not found on trakt.tv!", lResponse.NotFound.Episodes.Count);
                                Thread.Sleep(1000);
                            }

                            if (importCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion
            }
            #endregion
        }
Example #28
0
        public void ImportRatings()
        {
            mImportCancelled = false;

            var lRatedCsvItems     = new List <IMDbRateItem>();
            var lWatchlistCsvItems = new List <IMDbListItem>();
            var lCustomLists       = new Dictionary <string, List <IMDbListItem> >();

            #region Parse Ratings CSV
            UIUtils.UpdateStatus("Reading IMDb ratings export...");
            if (mImportCsvRatings)
            {
                mCsvConfiguration.RegisterClassMap <IMDbRatingCsvMap>();

                lRatedCsvItems = ParseCsvFile <IMDbRateItem>(mRatingsFileCsv);
                if (lRatedCsvItems == null)
                {
                    UIUtils.UpdateStatus("Failed to parse IMDb ratings file!", true);
                    Thread.Sleep(2000);
                    return;
                }
                mCsvConfiguration.UnregisterClassMap <IMDbRatingCsvMap>();
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Watchlist CSV
            UIUtils.UpdateStatus("Reading IMDb watchlist export...");
            if (mImportCsvWatchlist)
            {
                mCsvConfiguration.RegisterClassMap <IMDbListCsvMap>();

                lWatchlistCsvItems = ParseCsvFile <IMDbListItem>(mWatchlistFileCsv);
                if (lWatchlistCsvItems == null)
                {
                    UIUtils.UpdateStatus("Failed to parse IMDb watchlist file!", true);
                    Thread.Sleep(2000);
                    return;
                }
                mCsvConfiguration.UnregisterClassMap <IMDbListCsvMap>();
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Parse Custom List CSVs
            UIUtils.UpdateStatus("Reading IMDb custom lists export...");
            if (mImportCsvCustomLists)
            {
                mCsvConfiguration.RegisterClassMap <IMDbListCsvMap>();

                foreach (var list in mCustomListsCsvs)
                {
                    UIUtils.UpdateStatus($"Reading IMDb custom list '{list}'");

                    var lListCsvItems = ParseCsvFile <IMDbListItem>(list);
                    if (lListCsvItems == null)
                    {
                        UIUtils.UpdateStatus("Failed to parse IMDb custom list file!", true);
                        Thread.Sleep(2000);
                        continue;
                    }
                    lCustomLists.Add(list, lListCsvItems);
                }
                mCsvConfiguration.UnregisterClassMap <IMDbListCsvMap>();
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Movies
            var lRatedCsvMovies = lRatedCsvItems.Where(r => r.Type.ItemType() == IMDbType.Movie && r.MyRating != null)
                                  .Select(s => s.ToTraktRatedMovie()).ToList();

            FileLog.Info($"Found {lRatedCsvMovies.Count} movie ratings in CSV file");
            if (lRatedCsvMovies.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var lCurrentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (lCurrentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus($"Found {lCurrentUserMovieRatings.Count()} user movie ratings on trakt.tv");
                    // Filter out movies to rate from existing ratings online
                    lRatedCsvMovies.RemoveAll(m => lCurrentUserMovieRatings.Any(c => c.Movie.Ids.ImdbId == m.Ids.ImdbId));
                }

                UIUtils.UpdateStatus($"Importing {lRatedCsvMovies.Count()} new movie ratings to trakt.tv");

                if (lRatedCsvMovies.Count > 0)
                {
                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lRatedCsvMovies.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb rated movies...");

                        var lRatingsToSync = new TraktMovieRatingSync()
                        {
                            movies = lRatedCsvMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        TraktSyncResponse lResponse = TraktAPI.AddMoviesToRatings(lRatingsToSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync ratings for {lResponse.NotFound.Movies.Count} movies as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated TV Shows
            var lRatedCsvShows = lRatedCsvItems.Where(r => r.Type.ItemType() == IMDbType.Show && r.MyRating != null)
                                 .Select(s => s.ToTraktRatedShow()).ToList();

            FileLog.Info($"Found {lRatedCsvShows.Count} tv show ratings in CSV file");
            if (lRatedCsvShows.Any())
            {
                UIUtils.UpdateStatus("Retrieving existing tv show ratings from trakt.tv");
                var lCurrentUserShowRatings = TraktAPI.GetRatedShows();

                if (lCurrentUserShowRatings != null)
                {
                    UIUtils.UpdateStatus($"Found {lCurrentUserShowRatings.Count()} user tv show ratings on trakt.tv");
                    // Filter out shows to rate from existing ratings online
                    lRatedCsvShows.RemoveAll(s => lCurrentUserShowRatings.Any(c => (c.Show.Ids.ImdbId == s.Ids.ImdbId) ||
                                                                              (c.Show.Title.ToLowerInvariant() == s.Title.ToLowerInvariant() && c.Show.Year == s.Year)));
                }

                UIUtils.UpdateStatus($"Importing {lRatedCsvShows.Count()} tv show ratings to trakt.tv");

                if (lRatedCsvShows.Count > 0)
                {
                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lRatedCsvShows.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb rated shows...");

                        var lRatingsToSync = new TraktShowRatingSync()
                        {
                            shows = lRatedCsvShows.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        TraktSyncResponse lResponse = TraktAPI.AddShowsToRatings(lRatingsToSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb tv show ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync ratings for {lResponse.NotFound.Shows.Count} shows as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Rated Episodes
            var lImdbRatedEpisodes    = new List <IMDbEpisode>();
            var lImdbRatedCsvEpisodes = lRatedCsvItems.Where(r => r.Type.ItemType() == IMDbType.Episode).ToList();

            FileLog.Info($"Found {lImdbRatedCsvEpisodes.Count} tv episode ratings in CSV file");
            if (lImdbRatedCsvEpisodes.Any())
            {
                // we can't rely on the episode imdb id as trakt most likely wont have that info at the episode level
                lImdbRatedEpisodes.AddRange(lImdbRatedCsvEpisodes.Select(Helper.GetIMDbEpisodeFromTrakt).Where(imdbEpisode => imdbEpisode != null));
                if (mImportCancelled)
                {
                    return;
                }

                UIUtils.UpdateStatus("Retrieving existing tv episode ratings from trakt.tv");
                var lCurrentUserEpisodeRatings = TraktAPI.GetRatedEpisodes();

                if (lCurrentUserEpisodeRatings != null)
                {
                    UIUtils.UpdateStatus($"Found {lCurrentUserEpisodeRatings.Count()} user tv episode ratings on trakt.tv");

                    // Filter out episodes to rate from existing ratings online
                    lImdbRatedEpisodes.RemoveAll(e => lCurrentUserEpisodeRatings.Any(c => c.Episode.Ids.Trakt == e.TraktId));
                }

                UIUtils.UpdateStatus($"Importing {lImdbRatedEpisodes.Count()} episode ratings to trakt.tv");

                if (lImdbRatedEpisodes.Count > 0)
                {
                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lImdbRatedEpisodes.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        var lEpisodesRated = Helper.GetTraktEpisodeRateData(lImdbRatedEpisodes.Skip(i * lPageSize).Take(lPageSize));

                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb rated episodes...");

                        var lResponse = TraktAPI.AddsEpisodesToRatings(lEpisodesRated);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync ratings for {lResponse.NotFound.Episodes.Count} IMDb episodes as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Mark Rated Items as Watched
            IEnumerable <TraktMoviePlays> lWatchedTraktMovies = null;

            if (AppSettings.MarkAsWatched)
            {
                #region Movies
                var lWatchedCsvMovies = lRatedCsvItems.Where(r => r.Type.ItemType() == IMDbType.Movie)
                                        .Select(s => s.ToTraktWatchedMovie()).ToList();

                FileLog.Info("Found {0} movies in CSV file", lWatchedCsvMovies.Count);

                // compare all movies rated against what's not watched on trakt
                if (lWatchedCsvMovies.Count > 0)
                {
                    // get watched movies from trakt.tv
                    UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                    lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                    if (lWatchedTraktMovies == null)
                    {
                        UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                        Thread.Sleep(2000);
                    }
                    else
                    {
                        if (mImportCancelled)
                        {
                            return;
                        }

                        UIUtils.UpdateStatus($"Found {lWatchedTraktMovies.Count()} watched movies on trakt");
                        UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                        lWatchedCsvMovies.RemoveAll(w => lWatchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                            (t.Movie.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Movie.Year == w.Year)) != null);

                        // mark all rated movies as watched
                        UIUtils.UpdateStatus($"Importing {lWatchedCsvMovies.Count} IMDb movies as watched...");

                        int lPageSize = AppSettings.BatchSize;
                        int lPages    = (int)Math.Ceiling((double)lRatedCsvMovies.Count / lPageSize);
                        for (int i = 0; i < lPages; i++)
                        {
                            UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb movies as watched...");

                            var lMoviesToSync = new TraktMovieWatchedSync()
                            {
                                Movies = lWatchedCsvMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                            };

                            var lResponse = TraktAPI.AddMoviesToWatchedHistory(lMoviesToSync);
                            if (lResponse == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watched status for IMDb movies to trakt.tv", true);
                                Thread.Sleep(2000);
                            }
                            else if (lResponse.NotFound.Movies.Count > 0)
                            {
                                UIUtils.UpdateStatus($"Unable to sync watched states for {lResponse.NotFound.Movies.Count} movies as they're not found on trakt.tv!");
                                Thread.Sleep(1000);
                            }
                            if (mImportCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                #endregion

                #region Episodes
                if (lImdbRatedEpisodes != null && lImdbRatedEpisodes.Any())
                {
                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lImdbRatedEpisodes.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        var lEpisodesWatched = Helper.GetTraktEpisodeWatchedData(lImdbRatedEpisodes.Skip(i * lPageSize).Take(lPageSize));

                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb watched episodes...");

                        var lResponse = TraktAPI.AddEpisodesToWatchedHistory(lEpisodesWatched);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episodes as watched to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync {lResponse.NotFound.Episodes.Count} IMDb episodes as watched, as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
                #endregion
            }
            #endregion

            #region Import Watchlist Movies
            var lWatchlistedCsvMovies = lWatchlistCsvItems.Where(r => r.Type.ItemType() == IMDbType.Movie)
                                        .Select(s => s.ToTraktMovie()).ToList();

            FileLog.Info($"Found {lWatchlistedCsvMovies.Count} movies watchlisted in CSV file");
            if (lWatchlistedCsvMovies.Any())
            {
                UIUtils.UpdateStatus("Requesting existing watchlisted movies from trakt...");
                var lWatchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                if (lWatchlistTraktMovies != null)
                {
                    UIUtils.UpdateStatus($"Found {lWatchlistTraktMovies.Count()} watchlist movies on trakt");
                    UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                    lWatchlistedCsvMovies.RemoveAll(w => lWatchlistTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                              (t.Movie.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Movie.Year == w.Year)) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lWatchlistedCsvMovies.Count > 0)
                {
                    // get watched movies from trakt so we don't import movies into watchlist that are already watched
                    // we may already have this if we imported rated items as watched
                    if (lWatchedTraktMovies != null)
                    {
                        UIUtils.UpdateStatus("Requesting watched movies from trakt...");
                        lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                        if (lWatchedTraktMovies == null)
                        {
                            UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                    }

                    if (lWatchedTraktMovies != null)
                    {
                        UIUtils.UpdateStatus($"Found {lWatchedTraktMovies.Count()} watched movies on trakt");
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are watched on trakt.tv");

                        // remove movies from sync list which are watched already
                        lWatchlistedCsvMovies.RemoveAll(w => lWatchedTraktMovies.FirstOrDefault(t => t.Movie.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                                (t.Movie.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Movie.Year == w.Year)) != null);
                    }
                }

                // add movies to watchlist
                UIUtils.UpdateStatus($"Importing {lWatchlistedCsvMovies.Count()} IMDb watchlist movies to trakt.tv...");

                int lPageSize = AppSettings.BatchSize;
                int lPages    = (int)Math.Ceiling((double)lWatchlistedCsvMovies.Count / lPageSize);
                for (int i = 0; i < lPages; i++)
                {
                    UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb watchlist movies...");

                    var lWatchlistedToSync = new TraktMovieSync()
                    {
                        Movies = lWatchlistedCsvMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                    };

                    var lResponse = TraktAPI.AddMoviesToWatchlist(lWatchlistedToSync);
                    if (lResponse == null)
                    {
                        UIUtils.UpdateStatus("Failed to send watchlist for IMDb movies", true);
                        Thread.Sleep(2000);
                    }
                    else if (lResponse.NotFound.Movies.Count > 0)
                    {
                        UIUtils.UpdateStatus($"Unable to sync watchlist for {lResponse.NotFound.Movies.Count} movies as they're not found on trakt.tv!");
                        Thread.Sleep(1000);
                    }

                    if (mImportCancelled)
                    {
                        return;
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watchlist TV Shows
            IEnumerable <TraktShowPlays> lWatchedTraktShows = null;
            var lWatchlistedCsvShows = lWatchlistCsvItems.Where(r => r.Type.ItemType() == IMDbType.Show)
                                       .Select(s => s.ToTraktShow()).ToList();

            FileLog.Info($"Found {lWatchlistedCsvShows.Count} tv shows watchlisted in CSV file");
            if (lWatchlistedCsvShows.Any())
            {
                UIUtils.UpdateStatus("Requesting existing watchlisted shows from trakt...");
                var lWatchlistTraktShows = TraktAPI.GetWatchlistShows();
                if (lWatchlistTraktShows != null)
                {
                    UIUtils.UpdateStatus($"Found {lWatchlistTraktShows.Count()} watchlist shows on trakt");
                    UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv");
                    lWatchlistedCsvShows.RemoveAll(w => lWatchlistTraktShows.FirstOrDefault(t => t.Show.Ids.ImdbId == w.Ids.ImdbId ||
                                                                                            (t.Show.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Show.Year == w.Year)) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lWatchlistedCsvShows.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting watched shows from trakt...");

                    // get watched movies from trakt so we don't import shows into watchlist that are already watched
                    lWatchedTraktShows = TraktAPI.GetWatchedShows();
                    if (lWatchedTraktShows != null)
                    {
                        UIUtils.UpdateStatus($"Found {lWatchedTraktShows.Count()} watched shows on trakt");
                        UIUtils.UpdateStatus("Filtering out watchlist shows containing watched episodes on trakt.tv.");

                        // remove shows from sync list which are watched already
                        lWatchlistedCsvShows.RemoveAll(w => lWatchedTraktShows.FirstOrDefault(t => (t.Show.Ids.ImdbId == w.Ids.ImdbId) ||
                                                                                              (t.Show.Title.ToLowerInvariant() == w.Title.ToLowerInvariant() && t.Show.Year == w.Year)) != null);
                    }
                }

                // add shows to watchlist
                UIUtils.UpdateStatus($"Importing {lWatchlistedCsvShows.Count()} IMDb watchlist shows to trakt.tv...");

                int lPageSize = AppSettings.BatchSize;
                int lPages    = (int)Math.Ceiling((double)lWatchlistedCsvShows.Count / lPageSize);
                for (int i = 0; i < lPages; i++)
                {
                    UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb watchlist shows...");

                    var lWatchlistShowsToSync = new TraktShowSync
                    {
                        Shows = lWatchlistedCsvShows.Skip(i * lPageSize).Take(lPageSize).ToList()
                    };

                    var lResponse = TraktAPI.AddShowsToWatchlist(lWatchlistShowsToSync);
                    if (lResponse == null)
                    {
                        UIUtils.UpdateStatus("Failed to send watchlist for IMDb tv shows", true);
                        Thread.Sleep(2000);
                    }
                    else if (lResponse.NotFound.Shows.Count > 0)
                    {
                        UIUtils.UpdateStatus($"Unable to sync watchlist for {lResponse.NotFound.Shows.Count} shows as they're not found on trakt.tv!");
                        Thread.Sleep(1000);
                    }

                    if (mImportCancelled)
                    {
                        return;
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Import Watchlist Episodes
            var lImdbWatchlistedEpisodes    = new List <IMDbEpisode>();
            var lImdbWatchlistedCsvEpisodes = lWatchlistCsvItems.Where(r => r.Type.ItemType() == IMDbType.Episode).ToList();

            FileLog.Info($"Found {lImdbWatchlistedCsvEpisodes.Count} tv episodes watchlisted in CSV file");

            if (lImdbWatchlistedCsvEpisodes.Any())
            {
                UIUtils.UpdateStatus($"Found {lImdbWatchlistedCsvEpisodes.Count()} IMDb watchlisted episodes");

                lImdbWatchlistedEpisodes.AddRange(lImdbWatchlistedCsvEpisodes.Select(Helper.GetIMDbEpisodeFromTrakt).Where(imdbEpisode => imdbEpisode != null));
                if (mImportCancelled)
                {
                    return;
                }

                // filter out existing watchlist episodes
                UIUtils.UpdateStatus("Requesting existing watchlist episodes from trakt...");
                var lWatchlistedTraktEpisodes = TraktAPI.GetWatchlistEpisodes();
                if (lWatchlistedTraktEpisodes != null)
                {
                    UIUtils.UpdateStatus($"Found {lWatchlistedTraktEpisodes.Count()} watchlist episodes on trakt");
                    UIUtils.UpdateStatus("Filtering out watchlist episodes that are already in watchlist on trakt.tv");
                    lImdbWatchlistedEpisodes.RemoveAll(e => lWatchlistedTraktEpisodes.FirstOrDefault(w => w.Episode.Ids.Trakt == e.TraktId) != null);
                }

                if (AppSettings.IgnoreWatchedForWatchlist && lImdbWatchlistedEpisodes.Count > 0)
                {
                    // we already might have it from the shows sync
                    if (lWatchedTraktShows == null)
                    {
                        UIUtils.UpdateStatus("Requesting watched episodes from trakt...");

                        // get watched episodes from trakt so we don't import episodes into watchlist that are already watched
                        lWatchedTraktShows = TraktAPI.GetWatchedShows();
                    }

                    if (lWatchedTraktShows != null)
                    {
                        UIUtils.UpdateStatus("Filtering out watchlist episodes containing watched episodes on trakt.tv");

                        // this wont work atm due to show IMDb ID not being set in the IMDbEpisode object
                        lImdbWatchlistedEpisodes.RemoveAll(e => lWatchedTraktShows.Where(s => s.Show.Ids.ImdbId == e.ShowImdbId)
                                                           .Any(s => s.Seasons.Exists(se => se.Number == e.SeasonNumber &&
                                                                                      se.Episodes.Exists(ep => ep.Number == e.EpisodeNumber))));
                    }
                }

                UIUtils.UpdateStatus($"Importing {lImdbWatchlistedEpisodes.Count()} episodes in watchlist to trakt.tv");

                if (lImdbWatchlistedEpisodes.Count > 0)
                {
                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lImdbWatchlistedEpisodes.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb watchlisted episodes...");

                        var lResponse = TraktAPI.AddEpisodesToWatchlist(Helper.GetTraktEpisodeData(lImdbWatchlistedEpisodes.Skip(i * lPageSize).Take(lPageSize)));
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Error importing IMDb episode watchlist to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Episodes.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watchlist for {0} IMDb episodes as they're not found on trakt.tv!", lResponse.NotFound.Episodes.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion

            #region Import Custom Lists
            if (lCustomLists.Count > 0)
            {
                UIUtils.UpdateStatus("Requesting custom lists from trakt...");
                var lTraktCustomLists = TraktAPI.GetCustomLists();
                if (lTraktCustomLists == null)
                {
                    UIUtils.UpdateStatus("Error requesting custom lists from trakt.tv", true);
                    Thread.Sleep(2000);
                    return;
                }

                UIUtils.UpdateStatus($"Found {lTraktCustomLists.Count()} custom lists on trakt.tv");

                foreach (var list in lCustomLists)
                {
                    bool   lListCreated = false;
                    string lListName    = Path.GetFileNameWithoutExtension(list.Key);

                    // create the list if we don't have it
                    TraktListDetail lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                    if (lTraktCustomList == null)
                    {
                        UIUtils.UpdateStatus($"Creating new custom list '{lListName}' on trakt.tv");
                        var lTraktList = new TraktList
                        {
                            Name           = lListName,
                            DisplayNumbers = true,
                        };

                        lTraktCustomList = TraktAPI.CreateCustomList(lTraktList);
                        if (lTraktCustomList == null)
                        {
                            UIUtils.UpdateStatus("Error creating custom list on trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        lListCreated = true;
                    }

                    // get the CSV list items parsed
                    var lIMDbCsvListItems = list.Value;

                    var lImdbCsvListMovies = lIMDbCsvListItems.Where(l => l.Type.ItemType() == IMDbType.Movie).Select(m => m.ToTraktMovie()).ToList();
                    var lImdbCsvListShows  = lIMDbCsvListItems.Where(l => l.Type.ItemType() == IMDbType.Show).Select(m => m.ToTraktShow()).ToList();

                    FileLog.Info($"Found {lIMDbCsvListItems.Count} movies and {lImdbCsvListShows.Count} shows in IMDb {lListName} list", lListName);

                    // if the list already exists, get current items for list
                    if (!lListCreated)
                    {
                        lTraktCustomList = lTraktCustomLists.FirstOrDefault(l => l.Name == lListName);

                        UIUtils.UpdateStatus($"Requesting existing custom list '{lListName}' items from trakt...");
                        var lTraktListItems = TraktAPI.GetCustomListItems(lTraktCustomList.Ids.Trakt.ToString());
                        if (lTraktListItems == null)
                        {
                            UIUtils.UpdateStatus("Error requesting custom list items from trakt.tv, skipping list creation", true);
                            Thread.Sleep(2000);
                            continue;
                        }

                        // filter out existing items from CSV so we don't send again
                        FileLog.Info($"Filtering out existing items from IMDb list '{lListName}' so we don't send again to trakt.tv");
                        lImdbCsvListMovies.RemoveAll(i => lTraktListItems.FirstOrDefault(l => l.Movie.Ids.ImdbId == i.Ids.ImdbId) != null);
                        lImdbCsvListShows.RemoveAll(i => lTraktListItems.FirstOrDefault(l => l.Show.Ids.ImdbId == i.Ids.ImdbId) != null);
                    }

                    #region Movies

                    UIUtils.UpdateStatus($"Importing {lImdbCsvListMovies.Count} new movies into {lListName} custom list...");

                    int lPageSize = AppSettings.BatchSize;
                    int lPages    = (int)Math.Ceiling((double)lImdbCsvListMovies.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus($"Importing page {i + 1}/{lPages} IMDb custom list movies...");

                        // create list sync object to hold list items
                        var lTraktMovieSync = new TraktSyncAll
                        {
                            Movies = lImdbCsvListMovies.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        var lResponse = TraktAPI.AddItemsToList(lTraktCustomList.Ids.Trakt.ToString(), lTraktMovieSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send custom list items for IMDb movies", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus($"Unable to sync custom list items for {lResponse.NotFound.Movies.Count} movies as they're not found on trakt.tv!");
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                    #endregion

                    #region Shows

                    UIUtils.UpdateStatus("Importing {0} new shows into {1} custom list...", lImdbCsvListShows.Count(), lListName);

                    lPageSize = AppSettings.BatchSize;
                    lPages    = (int)Math.Ceiling((double)lImdbCsvListShows.Count / lPageSize);
                    for (int i = 0; i < lPages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} IMDb custom list shows...", i + 1, lPages);

                        // create list sync object to hold list items
                        var lTraktShowSync = new TraktSyncAll
                        {
                            Shows = lImdbCsvListShows.Skip(i * lPageSize).Take(lPageSize).ToList()
                        };

                        var lResponse = TraktAPI.AddItemsToList(lTraktCustomList.Ids.Trakt.ToString(), lTraktShowSync);
                        if (lResponse == null)
                        {
                            UIUtils.UpdateStatus("Failed to send custom list items for IMDb shows", true);
                            Thread.Sleep(2000);
                        }
                        else if (lResponse.NotFound.Shows.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync custom list items for {0} shows as they're not found on trakt.tv!", lResponse.NotFound.Shows.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }

                    #endregion
                }
            }
            #endregion
        }
Example #29
0
        public void ImportRatings()
        {
            mImportCancelled = false;

            var lAllMovies          = new List <FlixsterMovieRating>();
            var lAllMovieRatings    = new List <FlixsterMovieRating>();
            var lAllMoviesWatchlist = new List <FlixsterMovieRating>();

            #region Get Rated Movies
            int lPageSize = 50;

            UIUtils.UpdateStatus("Getting page 1 of Flixster rated movies...");
            var lPagedMovieRatings = FlixsterAPI.GetRatedMovies(mUserId.ToString(), 1, lPageSize);
            if (mImportCancelled)
            {
                return;
            }

            if (lPagedMovieRatings == null)
            {
                UIUtils.UpdateStatus("Failed to get movie ratings from Flixster", true);
                Thread.Sleep(2000);
                return;
            }

            // see if there are any more movie ratings to request
            // we don't get back a number of pages so need to manually work it out
            if (lPagedMovieRatings.Count() >= lPageSize)
            {
                lAllMovies.AddRange(lPagedMovieRatings);

                int  lPage        = 2;
                bool lRequestMore = true;

                while (lRequestMore)
                {
                    UIUtils.UpdateStatus("Getting page {0} of Flixster rated movies...", lPage);
                    lPagedMovieRatings = FlixsterAPI.GetRatedMovies(mUserId.ToString(), lPage++, lPageSize);
                    if (lPagedMovieRatings == null)
                    {
                        lRequestMore = false;
                        UIUtils.UpdateStatus(string.Format("Failed to get movie ratings on page {0} from Flixster", lPage - 1), true);
                        Thread.Sleep(2000);
                    }
                    else if (lPagedMovieRatings.Count() > 0)
                    {
                        // when we request another page, if there are no more movies, it *sometimes* returns the same ones again
                        // we can just check if the first movie returned already exists in our collection
                        if (lAllMovies.Exists(r => r.Movie.Title == lPagedMovieRatings.First().Movie.Title&& r.Movie.Year == lPagedMovieRatings.First().Movie.Year))
                        {
                            lRequestMore = false;
                        }
                        else
                        {
                            lAllMovies.AddRange(lPagedMovieRatings);

                            // check if there is any more pages worth requesting based on size returned in last batch
                            if (lPagedMovieRatings.Count() < lPageSize)
                            {
                                lRequestMore = false;
                            }
                        }
                    }
                    else
                    {
                        lRequestMore = false;
                    }
                }
            }

            #endregion

            #region Import Rated Movies
            lAllMovieRatings.AddRange(lAllMovies.Where(m => m.UserScore.IsFloat()));

            FileLog.Info("Found {0} movie ratings on Flixster", lAllMovieRatings.Count);
            if (lAllMovieRatings.Any())
            {
                var lMovieRatings = new List <FlixsterMovieRating>(lAllMovieRatings);

                UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv");
                var lCurrentUserMovieRatings = TraktAPI.GetRatedMovies();

                if (lCurrentUserMovieRatings != null)
                {
                    UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", lCurrentUserMovieRatings.Count());
                    lMovieRatings.RemoveAll(r => lCurrentUserMovieRatings.Any(c => c.Movie.Title.ToLowerInvariant() == r.Movie.Title.ToLowerInvariant() && c.Movie.Year == r.Movie.Year.ToYear()));
                }

                UIUtils.UpdateStatus("Importing {0} new movie ratings to trakt.tv", lMovieRatings.Count());

                if (lMovieRatings.Count > 0)
                {
                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lMovieRatings.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Flixster rated movies...", i + 1, pages);

                        TraktSyncResponse response = TraktAPI.AddMoviesToRatings(GetSyncRateMoviesData(lMovieRatings.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Error importing Flixster movie ratings to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }

                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            if (mImportCancelled)
            {
                return;
            }
            #endregion

            #region Mark Rated Items as Watched
            IEnumerable <TraktMoviePlays> lWatchedTraktMovies = null;

            if (AppSettings.MarkAsWatched && lAllMovieRatings.Count > 0)
            {
                if (mImportCancelled)
                {
                    return;
                }

                var lMoviesWatched = new List <FlixsterMovieRating>(lAllMovieRatings);

                // get watched movies from trakt.tv
                UIUtils.UpdateStatus("Requesting watched movies from trakt.tv...");
                lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                if (lWatchedTraktMovies == null)
                {
                    UIUtils.UpdateStatus("Failed to get watched movies from trakt.tv, skipping watched movie import", true);
                    Thread.Sleep(2000);
                }
                else
                {
                    if (mImportCancelled)
                    {
                        return;
                    }

                    UIUtils.UpdateStatus("Found {0} watched movies on trakt", lWatchedTraktMovies.Count());
                    UIUtils.UpdateStatus("Filtering out watched movies that are already watched on trakt.tv");

                    lMoviesWatched.RemoveAll(w => lWatchedTraktMovies.Any(t => t.Movie.Title.ToLowerInvariant() == w.Movie.Title.ToLowerInvariant() && t.Movie.Year == w.Movie.Year.ToYear()));

                    // mark all rated movies as watched
                    UIUtils.UpdateStatus("Importing {0} Flixster movies as watched...", lMoviesWatched.Count);

                    int pageSize = AppSettings.BatchSize;
                    int pages    = (int)Math.Ceiling((double)lMoviesWatched.Count / pageSize);
                    for (int i = 0; i < pages; i++)
                    {
                        UIUtils.UpdateStatus("Importing page {0}/{1} Flixster movies as watched...", i + 1, pages);

                        var response = TraktAPI.AddMoviesToWatchedHistory(GetSyncWatchedMoviesData(lMoviesWatched.Skip(i * pageSize).Take(pageSize).ToList()));
                        if (response == null)
                        {
                            UIUtils.UpdateStatus("Failed to send watched status for Flixster movies to trakt.tv", true);
                            Thread.Sleep(2000);
                        }
                        else if (response.NotFound.Movies.Count > 0)
                        {
                            UIUtils.UpdateStatus("Unable to sync watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
                            Thread.Sleep(1000);
                        }
                        if (mImportCancelled)
                        {
                            return;
                        }
                    }
                }
            }
            #endregion

            #region Sync Watchlist

            if (mSyncWantToSee)
            {
                if (mImportCancelled)
                {
                    return;
                }

                lAllMoviesWatchlist.AddRange(lAllMovies.Where(m => m.UserScore == "+"));

                if (lAllMoviesWatchlist.Count > 0)
                {
                    UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt...");
                    var lWatchlistTraktMovies = TraktAPI.GetWatchlistMovies();
                    if (lWatchlistTraktMovies != null)
                    {
                        UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", lWatchlistTraktMovies.Count());
                        UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv");
                        lAllMoviesWatchlist.RemoveAll(w => lWatchlistTraktMovies.Any(t => t.Movie.Title.ToLowerInvariant() == w.Movie.Title.ToLowerInvariant() && t.Movie.Year == w.Movie.Year.ToYear()));
                    }
                    if (mImportCancelled)
                    {
                        return;
                    }

                    if (AppSettings.IgnoreWatchedForWatchlist)
                    {
                        UIUtils.UpdateStatus("Requesting watched movies from trakt...");

                        // get watched movies from trakt so we don't import movies into watchlist that are already watched
                        if (lWatchedTraktMovies == null)
                        {
                            lWatchedTraktMovies = TraktAPI.GetWatchedMovies();
                            if (lWatchedTraktMovies != null)
                            {
                                UIUtils.UpdateStatus("Found {0} watched movies on trakt", lWatchedTraktMovies.Count());

                                // remove movies from sync list which are watched already
                                lAllMoviesWatchlist.RemoveAll(w => lWatchedTraktMovies.Any(t => t.Movie.Title.ToLowerInvariant() == w.Movie.Title.ToLowerInvariant() && t.Movie.Year == w.Movie.Year.ToYear()));
                            }
                        }
                        if (mImportCancelled)
                        {
                            return;
                        }
                    }

                    // add all movies to watchlist
                    UIUtils.UpdateStatus("Importing {0} Flixster wanttosee movies to trakt.tv watchlist...", lAllMoviesWatchlist.Count());

                    if (lAllMoviesWatchlist.Count > 0)
                    {
                        int pageSize = AppSettings.BatchSize;
                        int pages    = (int)Math.Ceiling((double)lAllMoviesWatchlist.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            UIUtils.UpdateStatus("Importing page {0}/{1} Flixster wantlist movies to trakt.tv watchlist...", i + 1, pages);

                            var watchlistMoviesResponse = TraktAPI.AddMoviesToWatchlist(GetSyncMoviesData(lAllMoviesWatchlist.Skip(i * pageSize).Take(pageSize).ToList()));
                            if (watchlistMoviesResponse == null)
                            {
                                UIUtils.UpdateStatus("Failed to send watchlist for Flixster movies", true);
                                Thread.Sleep(2000);
                            }

                            if (mImportCancelled)
                            {
                                return;
                            }
                        }
                    }
                }
            }

            #endregion
        }
Example #30
0
        public bool SyncMovies()
        {
            ISettingsManager settingsManager = ServiceRegistration.Get <ISettingsManager>();
            TraktSettings    settings        = settingsManager.Load <TraktSettings>();

            #region Get online data from cache

            #region Get unwatched / watched movies from trakt.tv
            IEnumerable <TraktMovieWatched> traktWatchedMovies = null;

            var traktUnWatchedMovies = TraktCache.GetUnWatchedMoviesFromTrakt();
            if (traktUnWatchedMovies == null)
            {
                TraktLogger.Error("Error getting unwatched movies from trakt server, unwatched and watched sync will be skipped");
            }
            else
            {
                TraktLogger.Info("There are {0} unwatched movies since the last sync with trakt.tv", traktUnWatchedMovies.Count());

                traktWatchedMovies = TraktCache.GetWatchedMoviesFromTrakt();
                if (traktWatchedMovies == null)
                {
                    TraktLogger.Error("Error getting watched movies from trakt server, watched sync will be skipped");
                }
                else
                {
                    TraktLogger.Info("There are {0} watched movies in trakt.tv library", traktWatchedMovies.Count().ToString());
                }
            }
            #endregion

            #region Get collected movies from trakt.tv
            var traktCollectedMovies = TraktCache.GetCollectedMoviesFromTrakt();
            if (traktCollectedMovies == null)
            {
                TraktLogger.Error("Error getting collected movies from trakt server");
            }
            else
            {
                TraktLogger.Info("There are {0} collected movies in trakt.tv library", traktCollectedMovies.Count());
            }
            #endregion

            #region Get rated movies from trakt.tv
            //var traktRatedMovies = TraktCache.GetRatedMoviesFromTrakt();
            //if (traktRatedMovies == null)
            //{
            //  TraktLogger.Error("Error getting rated movies from trakt server");
            //}
            //else
            //{
            //  TraktLogger.Info("There are {0} rated movies in trakt.tv library", traktRatedMovies.Count());
            //}
            #endregion

            #region Get watchlisted movies from trakt.tv
            //var traktWatchlistedMovies = TraktCache.GetWatchlistedMoviesFromTrakt();
            //if (traktWatchlistedMovies == null)
            //{
            //  TraktLogger.Error("Error getting watchlisted movies from trakt server");
            //}
            //else
            //{
            //  TraktLogger.Info("There are {0} watchlisted movies in trakt.tv library", traktWatchlistedMovies.Count());
            //}
            #endregion

            #region Get custom lists from trakt.tv
            //var traktCustomLists = TraktCache.GetCustomLists();
            //if (traktCustomLists == null)
            //{
            //  TraktLogger.Error("Error getting custom lists from trakt server");
            //}
            //else
            //{
            //  TraktLogger.Info("There are {0} custom lists in trakt.tv library", traktCustomLists.Count());
            //}
            #endregion
            #endregion

            try
            {
                TestStatus = "[Trakt.SyncMovies]";
                Guid[] types            = { MediaAspect.ASPECT_ID, MovieAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID };
                var    contentDirectory = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
                if (contentDirectory == null)
                {
                    TestStatus = "[Trakt.MediaLibraryNotConnected]";
                    return(false);
                }

                #region Get local database info

                var collectedMovies = contentDirectory.Search(new MediaItemQuery(types, null, null), true);

                TraktLogger.Info("Found {0} movies available to sync in local database", collectedMovies.Count);

                // get the movies that we have watched
                var watchedMovies = collectedMovies.Where(IsWatched).ToList();
                TraktLogger.Info("Found {0} watched movies available to sync in local database", watchedMovies.Count);

                #endregion

                #region Add movies to watched history at trakt.tv
                if (traktWatchedMovies != null)
                {
                    var syncWatchedMovies = new List <TraktSyncMovieWatched>();
                    TraktLogger.Info("Finding movies to add to trakt.tv watched history");

                    syncWatchedMovies = (from movie in watchedMovies
                                         where !traktWatchedMovies.ToList().Exists(c => MovieMatch(movie, c.Movie))
                                         select new TraktSyncMovieWatched
                    {
                        Ids = new TraktMovieId {
                            Imdb = GetMovieImdbId(movie), Tmdb = GetMovieTmdbId(movie)
                        },
                        Title = GetMovieTitle(movie),
                        Year = GetMovieYear(movie),
                        WatchedAt = GetLastPlayedDate(movie),
                    }).ToList();

                    TraktLogger.Info("Adding {0} movies to trakt.tv watched history", syncWatchedMovies.Count);

                    if (syncWatchedMovies.Count > 0)
                    {
                        // update internal cache
                        TraktCache.AddMoviesToWatchHistory(syncWatchedMovies);

                        int pageSize = settings.SyncBatchSize;
                        int pages    = (int)Math.Ceiling((double)syncWatchedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Adding movies [{0}/{1}] to trakt.tv watched history", i + 1, pages);

                            var pagedMovies = syncWatchedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(s => TraktLogger.Info("Adding movie to trakt.tv watched history. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}', Date Watched = '{4}'",
                                                                      s.Title, s.Year.HasValue ? s.Year.ToString() : "<empty>", s.Ids.Imdb ?? "<empty>", s.Ids.Tmdb.HasValue ? s.Ids.Tmdb.ToString() : "<empty>", s.WatchedAt));

                            // remove title/year such that match against online ID only
                            if (settings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m => { m.Title = null; m.Year = null; });
                            }

                            var response = TraktAPI.AddMoviesToWatchedHistory(new TraktSyncMoviesWatched {
                                Movies = pagedMovies
                            });
                            TraktLogger.LogTraktResponse <TraktSyncResponse>(response);

                            // remove movies from cache which didn't succeed
                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count > 0)
                            {
                                TraktCache.RemoveMoviesFromWatchHistory(response.NotFound.Movies);
                            }
                        }
                    }
                }
                #endregion

                #region Add movies to collection at trakt.tv
                if (traktCollectedMovies != null)
                {
                    var syncCollectedMovies = new List <TraktSyncMovieCollected>();
                    TraktLogger.Info("Finding movies to add to trakt.tv collection");

                    syncCollectedMovies = (from movie in collectedMovies
                                           where !traktCollectedMovies.ToList().Exists(c => MovieMatch(movie, c.Movie))
                                           select new TraktSyncMovieCollected
                    {
                        Ids = new TraktMovieId {
                            Imdb = GetMovieImdbId(movie), Tmdb = GetMovieTmdbId(movie)
                        },
                        Title = GetMovieTitle(movie),
                        Year = GetMovieYear(movie),
                        CollectedAt = GetDateAddedToDb(movie),
                        MediaType = GetVideoMediaType(movie),
                        Resolution = GetVideoResolution(movie),
                        AudioCodec = GetVideoAudioCodec(movie),
                        AudioChannels = "",
                        Is3D = false
                    }).ToList();

                    TraktLogger.Info("Adding {0} movies to trakt.tv watched history", syncCollectedMovies.Count);

                    if (syncCollectedMovies.Count > 0)
                    {
                        //update internal cache
                        TraktCache.AddMoviesToCollection(syncCollectedMovies);
                        int pageSize = settings.SyncBatchSize;
                        int pages    = (int)Math.Ceiling((double)syncCollectedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Adding movies [{0}/{1}] to trakt.tv collection", i + 1, pages);

                            var pagedMovies = syncCollectedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(s => TraktLogger.Info("Adding movie to trakt.tv collection. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}', Date Added = '{4}', MediaType = '{5}', Resolution = '{6}', Audio Codec = '{7}', Audio Channels = '{8}'",
                                                                      s.Title, s.Year.HasValue ? s.Year.ToString() : "<empty>", s.Ids.Imdb ?? "<empty>", s.Ids.Tmdb.HasValue ? s.Ids.Tmdb.ToString() : "<empty>",
                                                                      s.CollectedAt, s.MediaType ?? "<empty>", s.Resolution ?? "<empty>", s.AudioCodec ?? "<empty>", s.AudioChannels ?? "<empty>"));

                            //// remove title/year such that match against online ID only
                            if (settings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m =>
                                {
                                    m.Title = null;
                                    m.Year  = null;
                                });
                            }

                            var response = TraktAPI.AddMoviesToCollecton(new TraktSyncMoviesCollected {
                                Movies = pagedMovies
                            });
                            TraktLogger.LogTraktResponse(response);

                            // remove movies from cache which didn't succeed
                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count > 0)
                            {
                                TraktCache.RemoveMoviesFromCollection(response.NotFound.Movies);
                            }
                        }
                    }
                }
                #endregion
                return(true);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex);
            }
            return(false);
        }