Exemplo n.º 1
0
        /// <summary>
        /// Saves any movies that return as 'already_exists' from library sync calls
        /// </summary>
        /// <param name="response">Trakt Sync Movie Response</param>
        public static void InsertAlreadyExistMovies(TraktSyncResponse response)
        {
            if (response == null || response.AlreadyExistMovies == null)
            {
                return;
            }

            foreach (var movie in response.AlreadyExistMovies)
            {
                if (TraktSettings.AlreadyExistMovies == null)
                {
                    TraktSettings.AlreadyExistMovies = new SyncMovieCheck();
                }

                TraktLogger.Info("Inserting movie into already-exist list: Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);

                if (TraktSettings.AlreadyExistMovies.Movies != null)
                {
                    if (!TraktSettings.AlreadyExistMovies.Movies.Contains(movie))
                    {
                        TraktSettings.AlreadyExistMovies.Movies.Add(movie);
                    }
                }
                else
                {
                    TraktSettings.AlreadyExistMovies.Movies = new List <TraktMovieSync.Movie>();
                    TraktSettings.AlreadyExistMovies.Movies.Add(movie);
                }
            }
        }
        private void LogTraktResponseDataContract(TraktSyncResponse dataContract)
        {
            _logger.LogDebug("TraktResponse Added Movies: " + dataContract.added.movies);
            _logger.LogDebug("TraktResponse Added Shows: " + dataContract.added.shows);
            _logger.LogDebug("TraktResponse Added Seasons: " + dataContract.added.seasons);
            _logger.LogDebug("TraktResponse Added Episodes: " + dataContract.added.episodes);
            foreach (var traktMovie in dataContract.not_found.movies)
            {
                _logger.LogError("TraktResponse not Found: {TraktMovie}", _jsonSerializer.SerializeToString(traktMovie));
            }

            foreach (var traktShow in dataContract.not_found.shows)
            {
                _logger.LogError("TraktResponse not Found: {TraktShow}", _jsonSerializer.SerializeToString(traktShow));
            }

            foreach (var traktSeason in dataContract.not_found.seasons)
            {
                _logger.LogError("TraktResponse not Found: {TraktSeason}", _jsonSerializer.SerializeToString(traktSeason));
            }

            foreach (var traktEpisode in dataContract.not_found.episodes)
            {
                _logger.LogError("TraktResponse not Found: {TraktEpisode}", _jsonSerializer.SerializeToString(traktEpisode));
            }
        }
Exemplo n.º 3
0
        private void LogTraktResponseDataContract(TraktSyncResponse dataContract)
        {
            _logger.Debug("TraktResponse Added Movies: " + dataContract.Added.Movies);
            _logger.Debug("TraktResponse Added Shows: " + dataContract.Added.Shows);
            _logger.Debug("TraktResponse Added Seasons: " + dataContract.Added.Seasons);
            _logger.Debug("TraktResponse Added Episodes: " + dataContract.Added.Episodes);
            foreach (var traktMovie in dataContract.NotFound.Movies)
            {
                _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktMovie));
            }

            foreach (var traktShow in dataContract.NotFound.Shows)
            {
                _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktShow));
            }

            foreach (var traktSeason in dataContract.NotFound.Seasons)
            {
                _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktSeason));
            }

            foreach (var traktEpisode in dataContract.NotFound.Episodes)
            {
                _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktEpisode));
            }
        }
        /// <summary>
        /// Saves any movies that return as 'already_exists' from library sync calls
        /// </summary>
        /// <param name="response">Trakt Sync Movie Response</param>
        internal static void InsertAlreadyExistMovies(TraktSyncResponse response)
        {
            //TODO
            //if (response == null || response.AlreadyExistMovies == null) return;

            //foreach (var movie in response.AlreadyExistMovies)
            //{

            //    if (TraktSettings.AlreadyExistMovies == null)
            //        TraktSettings.AlreadyExistMovies = new SyncMovieCheck();

            //    TraktLogger.Info("Inserting movie into already-exist list: Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);

            //    if (TraktSettings.AlreadyExistMovies.Movies != null)
            //    {
            //        if (!TraktSettings.AlreadyExistMovies.Movies.Contains(movie))
            //            TraktSettings.AlreadyExistMovies.Movies.Add(movie);
            //    }
            //    else
            //    {
            //        TraktSettings.AlreadyExistMovies.Movies = new List<TraktMovieSync.Movie>();
            //        TraktSettings.AlreadyExistMovies.Movies.Add(movie);
            //    }
            //}
        }
Exemplo n.º 5
0
 private void HandleMovieResponse(TraktSyncResponse response)
 {
     if (response == null)
     {
         UIUtils.UpdateStatus("Error importing Criticker movie list to trakt.tv", true);
         Thread.Sleep(2000);
     }
     else if (response.NotFound.Movies.Count > 0)
     {
         UIUtils.UpdateStatus("Unable to process {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count);
         foreach (var movie in response.NotFound.Movies)
         {
             UIUtils.UpdateStatus("Unable to process movie: Title = {0}, Year = {1}, IMDb = {2}", movie.Title, movie.Year, movie.Ids.ImdbId);
         }
         Thread.Sleep(1000);
     }
 }
Exemplo n.º 6
0
 private void HandleShowResponse(TraktSyncResponse response)
 {
     if (response == null)
     {
         UIUtils.UpdateStatus("Error importing Criticker tv show list to trakt.tv", true);
         Thread.Sleep(2000);
     }
     else if (response.NotFound.Shows.Count > 0)
     {
         UIUtils.UpdateStatus("Unable to process {0} tv shows as they're not found on trakt.tv!", response.NotFound.Shows.Count);
         foreach (var show in response.NotFound.Shows)
         {
             UIUtils.UpdateStatus("Unable to process tv show: Title = {0}, Year = {1}, IMDb = {2}", show.Title, show.Year, show.Ids.ImdbId);
         }
         Thread.Sleep(1000);
     }
 }
Exemplo n.º 7
0
        private void LogTraktResponseDataContract(TraktSyncResponse dataContract)
        {
            try
            {
                _logger.Debug("TraktResponse Added Movies: " + dataContract?.added?.movies);
                _logger.Debug("TraktResponse Added Shows: " + dataContract?.added?.shows);
                _logger.Debug("TraktResponse Added Seasons: " + dataContract?.added?.seasons);
                _logger.Debug("TraktResponse Added Episodes: " + dataContract?.added?.episodes);

                _logger.Debug("TraktResponse Deleted Movies: " + dataContract?.deleted?.movies);
                _logger.Debug("TraktResponse Deleted Shows: " + dataContract?.deleted?.shows);
                _logger.Debug("TraktResponse Deleted Seasons: " + dataContract?.deleted?.seasons);
                _logger.Debug("TraktResponse Deleted Episodes: " + dataContract?.deleted?.episodes);

                _logger.Debug("TraktResponse Existing Movies: " + dataContract?.existing?.movies);
                _logger.Debug("TraktResponse Existing Shows: " + dataContract?.existing?.shows);
                _logger.Debug("TraktResponse Existing Seasons: " + dataContract?.existing?.seasons);
                _logger.Debug("TraktResponse Existing Episodes: " + dataContract?.existing?.episodes);

                foreach (var traktMovie in dataContract.not_found.movies)
                {
                    _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktMovie));
                }

                foreach (var traktShow in dataContract.not_found.shows)
                {
                    _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktShow));
                }

                foreach (var traktSeason in dataContract.not_found.seasons)
                {
                    _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktSeason));
                }

                foreach (var traktEpisode in dataContract.not_found.episodes)
                {
                    _logger.Error("TraktResponse not Found:" + _jsonSerializer.SerializeToString(traktEpisode));
                }
            }
            catch (NullReferenceException e)
            {
                _logger.ErrorException("Couldn't decode trakt response", e);
                _logger.Debug("Response object: {0}", _jsonSerializer.SerializeToString(dataContract));
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Logs the result of Trakt api call
        /// </summary>
        /// <typeparam name="T">Response Type of message</typeparam>
        /// <param name="response">The response object holding the message to log</param>
        internal static bool LogTraktResponse <T>(T response)
        {
            try
            {
                TraktResponse traktResponse = (response as TraktResponse);
                if (traktResponse == null || traktResponse.Status == null)
                {
                    // server is probably temporarily unavailable
                    // return true even though it failed, so we can try again
                    // currently the return value is only being used in livetv/recordings
                    Error("Response from server was unexpected.");
                    return(true);
                }

                // check response error status
                if (traktResponse.Status != "success")
                {
                    Error(traktResponse.Error == "The remote server returned an error: (401) Unauthorized." ? "401 Unauthorized, Please check your Username and Password" : traktResponse.Error);
                    return(false);
                }

                // success
                if (!string.IsNullOrEmpty(traktResponse.Message))
                {
                    Info("Response: {0}", traktResponse.Message);
                }
                else
                {
                    // no message returned on movie sync success
                    TraktSyncResponse traktSyncResponse = (response as TraktSyncResponse);
                    if (traktSyncResponse != null)
                    {
                        string message = "Response: Items Inserted: {0}, Items Already Exist: {1}, Items Skipped: {2}";
                        Info(message, traktSyncResponse.Inserted, traktSyncResponse.AlreadyExist, traktSyncResponse.Skipped);
                    }
                }
                return(true);
            }
            catch (Exception)
            {
                Info("Response: {0}", "Failed to interpret response from server");
                return(false);
            }
        }
Exemplo n.º 9
0
    private List <Episode> FindNotFoundEpisodes(IEnumerable <Episode> episodeChunk, TraktSyncResponse traktSyncResponse)
    {
        // episodes not found. if using IDs, try again without them
        List <Episode> episodes = new List <Episode>();

        // build a list of unfound episodes with ids
        foreach (TraktEpisode traktEpisode in traktSyncResponse.NotFound.Episodes.Where(i => HasAnyProviderTvIds(i.Ids)))
        {
            // find matching episode in JF based on ids provide
            var notFoundEpisode = episodeChunk.First(e => e.GetProviderId(MetadataProvider.Imdb) == traktEpisode.Ids.Imdb ||
                                                     e.GetProviderId(MetadataProvider.Tmdb) == traktEpisode.Ids.Tmdb?.ToString(CultureInfo.InvariantCulture) ||
                                                     e.GetProviderId(MetadataProvider.Tvdb) == traktEpisode.Ids.Tvdb?.ToString(CultureInfo.InvariantCulture) ||
                                                     e.GetProviderId(MetadataProvider.TvRage) == traktEpisode.Ids.Tvrage?.ToString(CultureInfo.InvariantCulture));

            if (notFoundEpisode != null)
            {
                episodes.Add(notFoundEpisode);
            }
        }

        return(episodes);
    }
Exemplo n.º 10
0
        internal static void AddRemoveItemInList(List <string> slugs, List <TraktListItem> items, bool remove)
        {
            Thread listThread = new Thread(delegate(object obj)
            {
                foreach (var slug in slugs)
                {
                    TraktList list = new TraktList
                    {
                        UserName = TraktSettings.Username,
                        Password = TraktSettings.Password,
                        Slug     = slug,
                        Items    = items
                    };
                    TraktSyncResponse response = null;
                    if (!remove)
                    {
                        response = TraktAPI.TraktAPI.ListAddItems(list);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.ListDeleteItems(list);
                    }

                    TraktAPI.TraktAPI.LogTraktResponse <TraktSyncResponse>(response);
                    if (response.Status == "success")
                    {
                        // clear current items in any lists
                        // list items will be refreshed online if we try to request them
                        TraktLists.ClearItemsInList(TraktSettings.Username, slug);
                    }
                }
            })
            {
                Name         = remove ? "RemoveList" : "AddList",
                IsBackground = true
            };

            listThread.Start();
        }
Exemplo n.º 11
0
        internal static void AddRemoveItemInList(List <string> listnames, List <TraktListItem> items, bool remove)
        {
            Thread listThread = new Thread(delegate(object obj)
            {
                foreach (var listname in listnames)
                {
                    TraktList list = new TraktList
                    {
                        UserName = TraktSettings.Username,
                        Password = TraktSettings.Password,
                        Slug     = listname,
                        Items    = items
                    };
                    TraktSyncResponse response = null;
                    if (!remove)
                    {
                        response = SendListAddItems(list);
                    }
                    else
                    {
                        response = SendListDeleteItems(list);
                    }

                    if (response.Status == "success")
                    {
                        // all fine!
                    }
                }
            })
            {
                Name         = remove ? "RemoveList" : "AddList",
                IsBackground = true
            };

            listThread.Start();
        }
Exemplo n.º 12
0
        public static void RemoveMovieFromWatchList(string title, string year, string imdbid, bool updateMovingPicturesFilters)
        {
            if (!GUICommon.CheckLogin(false))
            {
                return;
            }

            TraktMovieSync syncObject = BasicHandler.CreateMovieSyncData(title, year, imdbid);

            if (syncObject == null)
            {
                return;
            }

            Thread syncThread = new Thread(delegate(object obj)
            {
                TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(obj as TraktMovieSync, TraktSyncModes.unwatchlist);
                if (response == null || response.Status != "success")
                {
                    return;
                }
                if (updateMovingPicturesFilters && IsMovingPicturesAvailableAndEnabled)
                {
                    // Update Categories & Filters
                    MovingPictures.ClearWatchListCache();
                    MovingPictures.UpdateCategoriesAndFilters();
                }
                GUI.GUIWatchListMovies.ClearCache(TraktSettings.Username);
            })
            {
                IsBackground = true,
                Name         = "RemoveWatchList"
            };

            syncThread.Start(syncObject);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Shows a Trakt Rate Dialog
        /// </summary>
        /// <param name="rateObject">Type of object being rated</param>
        public static int ShowRateDialog <T>(T rateObject)
        {
            if (!GUICommon.CheckLogin(false))
            {
                return(-1);
            }

            if (GUIGraphicsContext.form.InvokeRequired)
            {
                ShowRateDialogDelegate <T> d = ShowRateDialog <T>;
                return((int)GUIGraphicsContext.form.Invoke(d, rateObject));
            }

            TraktRateValue currentRating = TraktRateValue.unrate;

            var ratingDlg = (GUIRateDialog)GUIWindowManager.GetWindow(GUIRateDialog.ID);

            ratingDlg.Reset();

            ratingDlg.SetHeading(Translation.RateHeading);

            // if item is not rated, it will default to seven
            if (rateObject is TraktSyncEpisodeRated)
            {
                var item = rateObject as TraktSyncEpisodeRated;
                ratingDlg.SetLine(1, string.Format("{0}x{1} - {2}", item.Season, item.Number, item.Title));
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }
            else if (rateObject is TraktSyncShowRatedEx)
            {
                // for when episode ids are not available we need to sync with both episode and show details
                var item = rateObject as TraktSyncShowRatedEx;
                ratingDlg.SetLine(1, string.Format("{0} - {1}x{2}", item.Title, item.Seasons[0].Number, item.Seasons[0].Episodes[0].Number));
                ratingDlg.Rated = item.Seasons[0].Episodes[0].Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Seasons[0].Episodes[0].Rating);
            }
            else if (rateObject is TraktSyncShowRated)
            {
                var item = rateObject as TraktSyncShowRated;
                ratingDlg.SetLine(1, item.Title);
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }
            else if (rateObject is TraktSyncSeasonRatedEx)
            {
                // for when season ids are not available we need to sync with both season and show details
                var item = rateObject as TraktSyncSeasonRatedEx;
                ratingDlg.SetLine(1, string.Format("{0} - {1} {2}", item.Title, Translation.Season, item.Seasons[0].Number));
                ratingDlg.Rated = item.Seasons[0].Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Seasons[0].Rating);
            }
            else
            {
                var item = rateObject as TraktSyncMovieRated;
                ratingDlg.SetLine(1, item.Title);
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }

            // show dialog
            ratingDlg.DoModal(ratingDlg.GetID);

            if (!ratingDlg.IsSubmitted)
            {
                return(-1);
            }

            TraktSyncResponse response = null;

            if (rateObject is TraktSyncEpisodeRated)
            {
                var item = rateObject as TraktSyncEpisodeRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncEpisodeRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddEpisodeToRatings(obj as TraktSyncEpisodeRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveEpisodeFromRatings(obj as TraktEpisode);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncShowRatedEx)
            {
                // for when episode ids are not available we need to sync with both episode and show details
                var item = rateObject as TraktSyncShowRatedEx;
                currentRating = ratingDlg.Rated;
                item.Seasons[0].Episodes[0].Rating = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncShowRatedEx).Seasons[0].Episodes[0].Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddEpisodeToRatingsEx(obj as TraktSyncShowRatedEx);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveEpisodeFromRatingsEx(obj as TraktSyncShowRatedEx);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncShowRated)
            {
                var item = rateObject as TraktSyncShowRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncShowRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddShowToRatings(obj as TraktSyncShowRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveShowFromRatings(obj as TraktShow);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncSeasonRatedEx)
            {
                // for when season ids are not available we need to sync with both season and show details
                var item = rateObject as TraktSyncSeasonRatedEx;
                currentRating          = ratingDlg.Rated;
                item.Seasons[0].Rating = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncSeasonRatedEx).Seasons[0].Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddSeasonToRatingsEx(obj as TraktSyncSeasonRatedEx);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveSeasonFromRatingsEx(obj as TraktSyncSeasonRatedEx);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else
            {
                var item = rateObject as TraktSyncMovieRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncMovieRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddMovieToRatings(obj as TraktSyncMovieRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveMovieFromRatings(obj as TraktMovie);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }

            return((int)currentRating);
        }
Exemplo n.º 14
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
        }
Exemplo n.º 15
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
        }
Exemplo n.º 16
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
        }
Exemplo n.º 17
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
        }
Exemplo n.º 18
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
        }
Exemplo n.º 19
0
        /// <summary>
        /// Shows a Trakt Rate Dialog
        /// </summary>
        /// <param name="rateObject">Type of object being rated</param>
        public static int ShowRateDialog <T>(T rateObject)
        {
            // Wait playback is fully stopped to avoid loop on stop
            while (g_Player.FullScreen || GUIGraphicsContext.Vmr9Active)
            {
                Thread.Sleep(10);
            }

            if (!GUICommon.CheckLogin(false))
            {
                return(-1);
            }

            if (GUIGraphicsContext.form.InvokeRequired)
            {
                ShowRateDialogDelegate <T> d = ShowRateDialog <T>;
                return((int)GUIGraphicsContext.form.Invoke(d, rateObject));
            }

            // The WiFi Remote is using an older version of the API which causes a conflict after recent refactoring
            // This check is put in place so it does not cripple users experience when rate dialog is invoked
            if (!TraktHelper.IsWifiRemotePluginCompatible)
            {
                GUIUtils.ShowOKDialog(Translation.Error, Translation.WifiRemotePluginInCompatible);
                return(-1);
            }

            TraktRateValue currentRating = TraktRateValue.unrate;

            var ratingDlg = (GUIRateDialog)GUIWindowManager.GetWindow(GUIRateDialog.ID);

            ratingDlg.Reset();

            ratingDlg.SetHeading(Translation.RateHeading);

            // if item is not rated, it will default to seven
            if (rateObject is TraktSyncEpisodeRated)
            {
                var item = rateObject as TraktSyncEpisodeRated;
                ratingDlg.SetLine(1, string.Format("{0}x{1} - {2}", item.Season, item.Number, item.Title));
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }
            else if (rateObject is TraktSyncShowRatedEx)
            {
                // for when episode ids are not available we need to sync with both episode and show details
                var item = rateObject as TraktSyncShowRatedEx;
                ratingDlg.SetLine(1, string.Format("{0} - {1}x{2}", item.Title, item.Seasons[0].Number, item.Seasons[0].Episodes[0].Number));
                ratingDlg.Rated = item.Seasons[0].Episodes[0].Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Seasons[0].Episodes[0].Rating);
            }
            else if (rateObject is TraktSyncShowRated)
            {
                var item = rateObject as TraktSyncShowRated;
                ratingDlg.SetLine(1, item.Title);
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }
            else if (rateObject is TraktSyncSeasonRatedEx)
            {
                // for when season ids are not available we need to sync with both season and show details
                var item = rateObject as TraktSyncSeasonRatedEx;
                ratingDlg.SetLine(1, string.Format("{0} - {1} {2}", item.Title, Translation.Season, item.Seasons[0].Number));
                ratingDlg.Rated = item.Seasons[0].Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Seasons[0].Rating);
            }
            else
            {
                var item = rateObject as TraktSyncMovieRated;
                ratingDlg.SetLine(1, item.Title);
                ratingDlg.Rated = item.Rating == 0 ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
            }

            // show dialog
            ratingDlg.DoModal(ratingDlg.GetID);

            if (!ratingDlg.IsSubmitted)
            {
                return(-1);
            }

            TraktSyncResponse response = null;

            if (rateObject is TraktSyncEpisodeRated)
            {
                var item = rateObject as TraktSyncEpisodeRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncEpisodeRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddEpisodeToRatings(obj as TraktSyncEpisodeRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveEpisodeFromRatings(obj as TraktEpisode);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncShowRatedEx)
            {
                // for when episode ids are not available we need to sync with both episode and show details
                var item = rateObject as TraktSyncShowRatedEx;
                currentRating = ratingDlg.Rated;
                item.Seasons[0].Episodes[0].Rating = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncShowRatedEx).Seasons[0].Episodes[0].Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddEpisodeToRatingsEx(obj as TraktSyncShowRatedEx);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveEpisodeFromRatingsEx(obj as TraktSyncShowRatedEx);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncShowRated)
            {
                var item = rateObject as TraktSyncShowRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncShowRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddShowToRatings(obj as TraktSyncShowRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveShowFromRatings(obj as TraktShow);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktSyncSeasonRatedEx)
            {
                // for when season ids are not available we need to sync with both season and show details
                var item = rateObject as TraktSyncSeasonRatedEx;
                currentRating          = ratingDlg.Rated;
                item.Seasons[0].Rating = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncSeasonRatedEx).Seasons[0].Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddSeasonToRatingsEx(obj as TraktSyncSeasonRatedEx);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveSeasonFromRatingsEx(obj as TraktSyncSeasonRatedEx);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else
            {
                var item = rateObject as TraktSyncMovieRated;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating;
                var rateThread = new Thread((obj) =>
                {
                    if ((obj as TraktSyncMovieRated).Rating > 0)
                    {
                        response = TraktAPI.TraktAPI.AddMovieToRatings(obj as TraktSyncMovieRated);
                    }
                    else
                    {
                        response = TraktAPI.TraktAPI.RemoveMovieFromRatings(obj as TraktMovie);
                    }
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }

            return((int)currentRating);
        }
Exemplo n.º 20
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
        }
Exemplo n.º 21
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;
        }
Exemplo n.º 22
0
        public void SyncLibrary()
        {
            TraktLogger.Info("My Videos Starting Sync");

            if (TraktSettings.SyncLibrary)
            {
                // get all movies
                ArrayList myvideos = new ArrayList();
                VideoDatabase.GetMovies(ref myvideos);

                List <IMDBMovie> MovieList = (from IMDBMovie movie in myvideos select movie).ToList();

                #region Remove Blocked Movies
                MovieList.RemoveAll(m => TraktSettings.BlockedFolders.Any(f => m.Path.ToLowerInvariant().Contains(f.ToLowerInvariant())));

                List <int> blockedMovieIds = new List <int>();
                foreach (string file in TraktSettings.BlockedFilenames)
                {
                    int pathId  = 0;
                    int movieId = 0;

                    // get a list of ids for blocked filenames
                    // filename seems to always be empty for an IMDBMovie object!
                    if (VideoDatabase.GetFile(file, out pathId, out movieId, false) > 0)
                    {
                        blockedMovieIds.Add(movieId);
                    }
                }
                MovieList.RemoveAll(m => blockedMovieIds.Contains(m.ID));
                #endregion

                #region Skipped Movies Check
                // Remove Skipped Movies from previous Sync
                if (TraktSettings.SkippedMovies != null)
                {
                    // allow movies to re-sync again after 7-days in the case user has addressed issue ie. edited movie or added to themoviedb.org
                    if (TraktSettings.SkippedMovies.LastSkippedSync.FromEpoch() > DateTime.UtcNow.Subtract(new TimeSpan(7, 0, 0, 0)))
                    {
                        if (TraktSettings.SkippedMovies.Movies != null && TraktSettings.SkippedMovies.Movies.Count > 0)
                        {
                            TraktLogger.Info("Skipping {0} movies due to invalid data or movies don't exist on http://themoviedb.org. Next check will be {1}.", TraktSettings.SkippedMovies.Movies.Count, TraktSettings.SkippedMovies.LastSkippedSync.FromEpoch().Add(new TimeSpan(7, 0, 0, 0)));
                            foreach (var movie in TraktSettings.SkippedMovies.Movies)
                            {
                                TraktLogger.Info("Skipping movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                                MovieList.RemoveAll(m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.IMDBNumber == movie.IMDBID));
                            }
                        }
                    }
                    else
                    {
                        if (TraktSettings.SkippedMovies.Movies != null)
                        {
                            TraktSettings.SkippedMovies.Movies.Clear();
                        }
                        TraktSettings.SkippedMovies.LastSkippedSync = DateTime.UtcNow.ToEpoch();
                    }
                }
                #endregion

                #region Already Exists Movie Check
                // Remove Already-Exists Movies, these are typically movies that are using aka names and no IMDb/TMDb set
                // When we compare our local collection with trakt collection we have english only titles, so if no imdb/tmdb exists
                // we need to fallback to title matching. When we sync aka names are sometimes accepted if defined on themoviedb.org so we need to
                // do this to revent syncing these movies every sync interval.
                if (TraktSettings.AlreadyExistMovies != null && TraktSettings.AlreadyExistMovies.Movies != null && TraktSettings.AlreadyExistMovies.Movies.Count > 0)
                {
                    TraktLogger.Debug("Skipping {0} movies as they already exist in trakt library but failed local match previously.", TraktSettings.AlreadyExistMovies.Movies.Count.ToString());
                    var movies = new List <TraktMovieSync.Movie>(TraktSettings.AlreadyExistMovies.Movies);
                    foreach (var movie in movies)
                    {
                        Predicate <IMDBMovie> criteria = m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.IMDBNumber == movie.IMDBID);
                        if (MovieList.Exists(criteria))
                        {
                            TraktLogger.Debug("Skipping movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                            MovieList.RemoveAll(criteria);
                        }
                        else
                        {
                            // remove as we have now removed from our local collection or updated movie signature
                            if (TraktSettings.MoviePluginCount == 1)
                            {
                                TraktLogger.Debug("Removing 'AlreadyExists' movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                                TraktSettings.AlreadyExistMovies.Movies.Remove(movie);
                            }
                        }
                    }
                }
                #endregion

                TraktLogger.Info("{0} movies available to sync in My Videos database", MovieList.Count.ToString());

                // get the movies that we have watched
                List <IMDBMovie> SeenList = MovieList.Where(m => m.Watched > 0).ToList();

                TraktLogger.Info("{0} watched movies available to sync in My Videos database", SeenList.Count.ToString());

                // get the movies that we have yet to watch
                TraktLogger.Info("Getting user {0}'s movies from trakt", TraktSettings.Username);
                IEnumerable <TraktLibraryMovies> traktMoviesAll = TraktAPI.TraktAPI.GetAllMoviesForUser(TraktSettings.Username);
                if (traktMoviesAll == null)
                {
                    TraktLogger.Error("Error getting movies from trakt server, cancelling sync.");
                    return;
                }
                TraktLogger.Info("{0} movies in trakt library", traktMoviesAll.Count().ToString());

                #region Movies to Sync to Collection
                List <IMDBMovie>          moviesToSync            = new List <IMDBMovie>(MovieList);
                List <TraktLibraryMovies> NoLongerInOurCollection = new List <TraktLibraryMovies>();
                //Filter out a list of movies we have already sync'd in our collection
                foreach (TraktLibraryMovies tlm in traktMoviesAll)
                {
                    bool notInLocalCollection = true;
                    // if it is in both libraries
                    foreach (IMDBMovie libraryMovie in MovieList.Where(m => MovieMatch(m, tlm)))
                    {
                        // If the users IMDb Id is empty/invalid and we have matched one then set it
                        if (BasicHandler.IsValidImdb(tlm.IMDBID) && !BasicHandler.IsValidImdb(libraryMovie.IMDBNumber))
                        {
                            TraktLogger.Info("Movie '{0}' inserted IMDb Id '{1}'", libraryMovie.Title, tlm.IMDBID);
                            libraryMovie.IMDBNumber = tlm.IMDBID;
                            IMDBMovie details = libraryMovie;
                            VideoDatabase.SetMovieInfoById(libraryMovie.ID, ref details);
                        }

                        // if it is watched in Trakt but not My Videos update
                        // skip if movie is watched but user wishes to have synced as unseen locally
                        if (tlm.Plays > 0 && !tlm.UnSeen && libraryMovie.Watched == 0)
                        {
                            TraktLogger.Info("Movie '{0}' is watched on Trakt updating Database", libraryMovie.Title);
                            libraryMovie.Watched = 1;
                            if (libraryMovie.DateWatched == "0001-01-01 00:00:00")
                            {
                                libraryMovie.DateWatched = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            }
                            IMDBMovie details = libraryMovie;
                            VideoDatabase.SetMovieInfoById(libraryMovie.ID, ref details);

                            if (libraryMovie.WatchedCount == 0)
                            {
                                VideoDatabase.SetMovieWatchedCount(libraryMovie.ID, tlm.Plays);
                                VideoDatabase.SetMovieWatchedStatus(libraryMovie.ID, true, 0);
                            }
                        }

                        // mark movies as unseen if watched locally
                        if (tlm.UnSeen && libraryMovie.Watched > 0)
                        {
                            TraktLogger.Info("Movie '{0}' is unseen on Trakt, updating database", libraryMovie.Title);
                            libraryMovie.Watched = 0;
                            IMDBMovie details = libraryMovie;
                            VideoDatabase.SetMovieInfoById(libraryMovie.ID, ref details);
                            VideoDatabase.SetMovieWatchedStatus(libraryMovie.ID, false, 0);
                        }

                        notInLocalCollection = false;

                        //filter out if its already in collection
                        if (tlm.InCollection)
                        {
                            moviesToSync.RemoveAll(m => MovieMatch(m, tlm));
                        }
                        break;
                    }

                    if (notInLocalCollection && tlm.InCollection)
                    {
                        NoLongerInOurCollection.Add(tlm);
                    }
                }
                #endregion

                #region Movies to Sync to Seen Collection
                // filter out a list of movies already marked as watched on trakt
                // also filter out movie marked as unseen so we dont reset the unseen cache online
                List <IMDBMovie> watchedMoviesToSync = new List <IMDBMovie>(SeenList);
                foreach (TraktLibraryMovies tlm in traktMoviesAll.Where(t => t.Plays > 0 || t.UnSeen))
                {
                    foreach (IMDBMovie watchedMovie in SeenList.Where(m => MovieMatch(m, tlm)))
                    {
                        //filter out
                        watchedMoviesToSync.Remove(watchedMovie);
                    }
                }
                #endregion

                #region Sync Collection to trakt
                //Send Library/Collection
                TraktLogger.Info("{0} movies need to be added to Library", moviesToSync.Count.ToString());
                foreach (IMDBMovie m in moviesToSync)
                {
                    TraktLogger.Info("Sending movie to trakt library, Title: {0}, Year: {1}, IMDb: {2}", m.Title, m.Year.ToString(), m.IMDBNumber);
                }

                if (moviesToSync.Count > 0)
                {
                    TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(CreateSyncData(moviesToSync), TraktSyncModes.library);
                    BasicHandler.InsertSkippedMovies(response);
                    BasicHandler.InsertAlreadyExistMovies(response);
                    TraktLogger.LogTraktResponse(response);
                }
                #endregion

                #region Sync Seen to trakt
                //Send Seen
                TraktLogger.Info("{0} movies need to be added to SeenList", watchedMoviesToSync.Count.ToString());
                foreach (IMDBMovie m in watchedMoviesToSync)
                {
                    TraktLogger.Info("Sending movie to trakt as seen, Title: {0}, Year: {1}, IMDb: {2}", m.Title, m.Year.ToString(), m.IMDBNumber);
                }

                if (watchedMoviesToSync.Count > 0)
                {
                    TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(CreateSyncData(watchedMoviesToSync), TraktSyncModes.seen);
                    BasicHandler.InsertSkippedMovies(response);
                    BasicHandler.InsertAlreadyExistMovies(response);
                    TraktLogger.LogTraktResponse(response);
                }
                #endregion

                #region Clean Library
                //Dont clean library if more than one movie plugin installed
                if (TraktSettings.KeepTraktLibraryClean && TraktSettings.MoviePluginCount == 1)
                {
                    //Remove movies we no longer have in our local database from Trakt
                    foreach (var m in NoLongerInOurCollection)
                    {
                        TraktLogger.Info("Removing from Trakt Collection {0}", m.Title);
                    }

                    TraktLogger.Info("{0} movies need to be removed from Trakt Collection", NoLongerInOurCollection.Count.ToString());

                    if (NoLongerInOurCollection.Count > 0)
                    {
                        if (TraktSettings.AlreadyExistMovies != null && TraktSettings.AlreadyExistMovies.Movies != null && TraktSettings.AlreadyExistMovies.Movies.Count > 0)
                        {
                            TraktLogger.Warning("DISABLING CLEAN LIBRARY!!!, there are trakt library movies that can't be determined to be local in collection.");
                            TraktLogger.Warning("To fix this, check the 'already exist' entries in log, then check movies in local collection against this list and ensure IMDb id is set then run sync again.");
                        }
                        else
                        {
                            //Then remove from library
                            TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(BasicHandler.CreateMovieSyncData(NoLongerInOurCollection), TraktSyncModes.unlibrary);
                            TraktLogger.LogTraktResponse(response);
                        }
                    }
                }
                #endregion
            }

            TraktLogger.Info("My Videos Sync Completed");
        }
Exemplo n.º 23
0
        public void SyncLibrary()
        {
            TraktLogger.Info("My Films Starting Sync");
            SyncInProgress = true;

            // get all movies
            ArrayList myvideos = new ArrayList();

            BaseMesFilms.GetMovies(ref myvideos);
            TraktLogger.Info("BaseMesFilms.GetMovies: returning " + myvideos.Count + " movies");

            List <MFMovie> MovieList = (from MFMovie movie in myvideos select movie).ToList();

            // Remove any blocked movies
            MovieList.RemoveAll(movie => TraktSettings.BlockedFolders.Any(f => movie.File.ToLowerInvariant().Contains(f.ToLowerInvariant())));
            MovieList.RemoveAll(movie => TraktSettings.BlockedFilenames.Contains(movie.File));

            #region Skipped Movies Check
            // Remove Skipped Movies from previous Sync
            if (TraktSettings.SkippedMovies != null)
            {
                // allow movies to re-sync again after 7-days in the case user has addressed issue ie. edited movie or added to themoviedb.org
                if (TraktSettings.SkippedMovies.LastSkippedSync.FromEpoch() > DateTime.UtcNow.Subtract(new TimeSpan(7, 0, 0, 0)))
                {
                    if (TraktSettings.SkippedMovies.Movies != null && TraktSettings.SkippedMovies.Movies.Count > 0)
                    {
                        TraktLogger.Info("Skipping {0} movies due to invalid data or movies don't exist on http://themoviedb.org. Next check will be {1}.", TraktSettings.SkippedMovies.Movies.Count, TraktSettings.SkippedMovies.LastSkippedSync.FromEpoch().Add(new TimeSpan(7, 0, 0, 0)));
                        foreach (var movie in TraktSettings.SkippedMovies.Movies)
                        {
                            TraktLogger.Info("Skipping movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                            MovieList.RemoveAll(m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.IMDBNumber == movie.IMDBID));
                        }
                    }
                }
                else
                {
                    if (TraktSettings.SkippedMovies.Movies != null)
                    {
                        TraktSettings.SkippedMovies.Movies.Clear();
                    }
                    TraktSettings.SkippedMovies.LastSkippedSync = DateTime.UtcNow.ToEpoch();
                }
            }
            #endregion

            #region Already Exists Movie Check
            // Remove Already-Exists Movies, these are typically movies that are using aka names and no IMDb/TMDb set
            // When we compare our local collection with trakt collection we have english only titles, so if no imdb/tmdb exists
            // we need to fallback to title matching. When we sync aka names are sometimes accepted if defined on themoviedb.org so we need to
            // do this to revent syncing these movies every sync interval.
            if (TraktSettings.AlreadyExistMovies != null && TraktSettings.AlreadyExistMovies.Movies != null && TraktSettings.AlreadyExistMovies.Movies.Count > 0)
            {
                TraktLogger.Debug("Skipping {0} movies as they already exist in trakt library but failed local match previously.", TraktSettings.AlreadyExistMovies.Movies.Count.ToString());
                var movies = new List <TraktMovieSync.Movie>(TraktSettings.AlreadyExistMovies.Movies);
                foreach (var movie in movies)
                {
                    Predicate <MFMovie> criteria = m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.IMDBNumber == movie.IMDBID);
                    if (MovieList.Exists(criteria))
                    {
                        TraktLogger.Debug("Skipping movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                        MovieList.RemoveAll(criteria);
                    }
                    else
                    {
                        // remove as we have now removed from our local collection or updated movie signature
                        if (TraktSettings.MoviePluginCount == 1)
                        {
                            TraktLogger.Debug("Removing 'AlreadyExists' movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
                            TraktSettings.AlreadyExistMovies.Movies.Remove(movie);
                        }
                    }
                }
            }
            #endregion

            TraktLogger.Info("{0} movies available to sync in MyFilms database(s)", MovieList.Count.ToString());

            // get the movies that we have watched
            List <MFMovie> SeenList = MovieList.Where(m => m.Watched == true).ToList();

            TraktLogger.Info("{0} watched movies available to sync in MyFilms database(s)", SeenList.Count.ToString());

            // get the movies that we have yet to watch
            IEnumerable <TraktLibraryMovies> traktMoviesAll = TraktAPI.TraktAPI.GetAllMoviesForUser(TraktSettings.Username);
            if (traktMoviesAll == null)
            {
                SyncInProgress = false;
                TraktLogger.Error("Error getting movies from trakt server, cancelling sync.");
                return;
            }
            TraktLogger.Info("{0} movies in trakt library", traktMoviesAll.Count().ToString());

            #region Movies to Sync to Collection
            List <MFMovie>            moviesToSync            = new List <MFMovie>(MovieList);
            List <TraktLibraryMovies> NoLongerInOurCollection = new List <TraktLibraryMovies>();
            //Filter out a list of movies we have already sync'd in our collection
            foreach (TraktLibraryMovies tlm in traktMoviesAll)
            {
                bool notInLocalCollection = true;
                // if it is in both libraries
                foreach (MFMovie libraryMovie in MovieList.Where(m => MovieMatch(m, tlm)))
                {
                    // If the users IMDb Id is empty/invalid and we have matched one then set it
                    if (BasicHandler.IsValidImdb(tlm.IMDBID) && !BasicHandler.IsValidImdb(libraryMovie.IMDBNumber))
                    {
                        TraktLogger.Info("Movie '{0}' inserted IMDb Id '{1}'", libraryMovie.Title, tlm.IMDBID);
                        libraryMovie.IMDBNumber = tlm.IMDBID;
                        libraryMovie.Username   = TraktSettings.Username;
                        libraryMovie.Commit();
                    }

                    // If the users TMDb Id is empty/invalid and we have one then set it
                    if (string.IsNullOrEmpty(libraryMovie.TMDBNumber) && !string.IsNullOrEmpty(tlm.TMDBID))
                    {
                        TraktLogger.Info("Movie '{0}' inserted TMDb Id '{1}'", libraryMovie.Title, tlm.TMDBID);
                        libraryMovie.TMDBNumber = tlm.TMDBID;
                        libraryMovie.Username   = TraktSettings.Username;
                        libraryMovie.Commit();
                    }

                    // if it is watched in Trakt but not My Films update
                    // skip if movie is watched but user wishes to have synced as unseen locally
                    if (tlm.Plays > 0 && !tlm.UnSeen && libraryMovie.Watched == false)
                    {
                        TraktLogger.Info("Movie '{0}' is watched on Trakt updating Database", libraryMovie.Title);
                        libraryMovie.Watched      = true;
                        libraryMovie.WatchedCount = tlm.Plays;
                        libraryMovie.Username     = TraktSettings.Username;
                        libraryMovie.Commit();
                    }

                    // mark movies as unseen if watched locally
                    if (tlm.UnSeen && libraryMovie.Watched == true)
                    {
                        TraktLogger.Info("Movie '{0}' is unseen on Trakt, updating database", libraryMovie.Title);
                        libraryMovie.Watched      = false;
                        libraryMovie.WatchedCount = tlm.Plays;
                        libraryMovie.Username     = TraktSettings.Username;
                        libraryMovie.Commit();
                    }

                    notInLocalCollection = false;

                    //filter out if its already in collection
                    if (tlm.InCollection)
                    {
                        moviesToSync.RemoveAll(m => MovieMatch(m, tlm));
                    }
                    break;
                }

                if (notInLocalCollection && tlm.InCollection)
                {
                    NoLongerInOurCollection.Add(tlm);
                }
            }
            #endregion

            #region Movies to Sync to Seen Collection
            // filter out a list of movies already marked as watched on trakt
            // also filter out movie marked as unseen so we dont reset the unseen cache online
            List <MFMovie> watchedMoviesToSync = new List <MFMovie>(SeenList);
            foreach (TraktLibraryMovies tlm in traktMoviesAll.Where(t => t.Plays > 0 || t.UnSeen))
            {
                foreach (MFMovie watchedMovie in SeenList.Where(m => MovieMatch(m, tlm)))
                {
                    //filter out
                    watchedMoviesToSync.Remove(watchedMovie);
                }
            }
            #endregion

            #region Send Library/Collection
            TraktLogger.Info("{0} movies need to be added to Library", moviesToSync.Count.ToString());
            foreach (MFMovie m in moviesToSync)
            {
                TraktLogger.Info("Sending movie to trakt library, Title: {0}, Year: {1}, IMDb: {2}, TMDb: {3}", m.Title, m.Year.ToString(), m.IMDBNumber, m.TMDBNumber);
            }

            if (moviesToSync.Count > 0)
            {
                TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(CreateSyncData(moviesToSync), TraktSyncModes.library);
                BasicHandler.InsertSkippedMovies(response);
                BasicHandler.InsertAlreadyExistMovies(response);
                TraktAPI.TraktAPI.LogTraktResponse(response);
            }
            #endregion

            #region Send Seen
            TraktLogger.Info("{0} movies need to be added to SeenList", watchedMoviesToSync.Count.ToString());
            foreach (MFMovie m in watchedMoviesToSync)
            {
                TraktLogger.Info("Sending movie to trakt as seen, Title: {0}, Year: {1}, IMDb: {2}, TMDb: {3}", m.Title, m.Year.ToString(), m.IMDBNumber, m.TMDBNumber);
            }

            if (watchedMoviesToSync.Count > 0)
            {
                TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(CreateSyncData(watchedMoviesToSync), TraktSyncModes.seen);
                BasicHandler.InsertSkippedMovies(response);
                BasicHandler.InsertAlreadyExistMovies(response);
                TraktAPI.TraktAPI.LogTraktResponse(response);
            }
            #endregion

            #region Ratings Sync
            // only sync ratings if we are using Advanced Ratings
            if (TraktSettings.SyncRatings)
            {
                var traktRatedMovies = TraktAPI.TraktAPI.GetUserRatedMovies(TraktSettings.Username);
                if (traktRatedMovies == null)
                {
                    TraktLogger.Error("Error getting rated movies from trakt server.");
                }
                else
                {
                    TraktLogger.Info("{0} rated movies in trakt library", traktRatedMovies.Count().ToString());
                }

                if (traktRatedMovies != null)
                {
                    // get the movies that we have rated/unrated
                    var RatedList   = MovieList.Where(m => m.RatingUser > 0.0).ToList();
                    var UnRatedList = MovieList.Except(RatedList).ToList();
                    TraktLogger.Info("{0} rated movies available to sync in MyFilms database", RatedList.Count.ToString());

                    List <MFMovie> ratedMoviesToSync = new List <MFMovie>(RatedList);
                    foreach (var trm in traktRatedMovies)
                    {
                        foreach (var movie in UnRatedList.Where(m => MovieMatch(m, trm)))
                        {
                            // update local collection rating
                            TraktLogger.Info("Inserting rating '{0}/10' for movie '{1} ({2})'", trm.RatingAdvanced, movie.Title, movie.Year);
                            movie.RatingUser = trm.RatingAdvanced;
                            movie.Username   = TraktSettings.Username;
                            movie.Commit();
                        }

                        foreach (var movie in RatedList.Where(m => MovieMatch(m, trm)))
                        {
                            // if rating is not synced, update local collection rating to get in sync
                            if ((int)movie.RatingUser != trm.RatingAdvanced)
                            {
                                TraktLogger.Info("Updating rating '{0}/10' for movie '{1} ({2})'", trm.RatingAdvanced, movie.Title, movie.Year);
                                movie.RatingUser = trm.RatingAdvanced;
                                movie.Username   = TraktSettings.Username;
                                movie.Commit();
                            }

                            // already rated on trakt, so remove from sync collection
                            ratedMoviesToSync.Remove(movie);
                        }
                    }

                    TraktLogger.Info("{0} rated movies to sync to trakt", ratedMoviesToSync.Count);
                    if (ratedMoviesToSync.Count > 0)
                    {
                        ratedMoviesToSync.ForEach(a => TraktLogger.Info("Importing rating '{0}/10' for movie '{1} ({2})'", a.RatingUser, a.Title, a.Year));
                        TraktResponse response = TraktAPI.TraktAPI.RateMovies(CreateRatingMoviesData(ratedMoviesToSync));
                        TraktAPI.TraktAPI.LogTraktResponse(response);
                    }
                }
            }
            #endregion

            #region Clean Library
            //Dont clean library if more than one movie plugin installed
            if (TraktSettings.KeepTraktLibraryClean && TraktSettings.MoviePluginCount == 1)
            {
                //Remove movies we no longer have in our local database from Trakt
                foreach (var m in NoLongerInOurCollection)
                {
                    TraktLogger.Info("Removing from Trakt Collection {0}", m.Title);
                }

                TraktLogger.Info("{0} movies need to be removed from Trakt Collection", NoLongerInOurCollection.Count.ToString());

                if (NoLongerInOurCollection.Count > 0)
                {
                    if (TraktSettings.AlreadyExistMovies != null && TraktSettings.AlreadyExistMovies.Movies != null && TraktSettings.AlreadyExistMovies.Movies.Count > 0)
                    {
                        TraktLogger.Warning("DISABLING CLEAN LIBRARY!!!, there are trakt library movies that can't be determined to be local in collection.");
                        TraktLogger.Warning("To fix this, check the 'already exist' entries in log, then check movies in local collection against this list and ensure IMDb id is set then run sync again.");
                    }
                    else
                    {
                        //Then remove from library
                        TraktSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(BasicHandler.CreateMovieSyncData(NoLongerInOurCollection), TraktSyncModes.unlibrary);
                        TraktAPI.TraktAPI.LogTraktResponse(response);
                    }
                }
            }
            #endregion

            #region Trakt Category Tags
            List <MFMovie> movieListAll = (from MFMovie movie in myvideos select movie).ToList(); // Add tags also to blocked movies, as it is only local
            // get the movies that locally have trakt categories
            var categoryTraktList = movieListAll.Where(m => m.CategoryTrakt.Count > 0).ToList();

            if (TraktSettings.MyFilmsCategories)
            {
                TraktLogger.Info("{0} trakt-categorized movies available in MyFilms database", categoryTraktList.Count.ToString());

                #region update watchlist tags
                IEnumerable <TraktWatchListMovie> traktWatchListMovies = null;
                string Watchlist = Translation.WatchList;
                TraktLogger.Info("Retrieving watchlist from trakt");
                traktWatchListMovies = TraktAPI.TraktAPI.GetWatchListMovies(TraktSettings.Username);

                if (traktWatchListMovies != null)
                {
                    TraktLogger.Info("Retrieved {0} watchlist items from trakt", traktWatchListMovies.Count());

                    var cleanupList = movieListAll.Where(m => m.CategoryTrakt.Contains(Watchlist)).ToList();
                    foreach (var trm in traktWatchListMovies)
                    {
                        TraktLogger.Debug("Processing trakt watchlist movie - Title '{0}', Year '{1}' Imdb '{2}'", trm.Title ?? "null", trm.Year, trm.IMDBID ?? "null");
                        foreach (var movie in movieListAll.Where(m => MovieMatch(m, trm)))
                        {
                            if (!movie.CategoryTrakt.Contains(Watchlist))
                            {
                                TraktLogger.Info("Inserting trakt category '{0}' for movie '{1} ({2})'", Watchlist, movie.Title, movie.Year);
                                movie.CategoryTrakt.Add(Watchlist);
                                movie.Username = TraktSettings.Username;
                                movie.Commit();
                            }
                            cleanupList.Remove(movie);
                        }
                    }
                    // remove tag from remaining films
                    foreach (var movie in cleanupList)
                    {
                        TraktLogger.Info("Removing trakt category '{0}' for movie '{1} ({2})'", Watchlist, movie.Title, movie.Year);
                        movie.CategoryTrakt.Remove(Watchlist);
                        movie.Username = TraktSettings.Username;
                        movie.Commit();
                    }
                }
                #endregion

                #region update user list tags
                IEnumerable <TraktUserList> traktUserLists = null;
                string Userlist = Translation.List;
                TraktLogger.Info("Retrieving user lists from trakt");
                traktUserLists = TraktAPI.TraktAPI.GetUserLists(TraktSettings.Username);

                if (traktUserLists != null)
                {
                    TraktLogger.Info("Retrieved {0} user lists from trakt", traktUserLists.Count());

                    foreach (TraktUserList traktUserList in traktUserLists)
                    {
                        TraktUserList traktUserListMovies = TraktAPI.TraktAPI.GetUserList(TraktSettings.Username, traktUserList.Slug);
                        if (traktUserListMovies == null)
                        {
                            continue;
                        }

                        string userListName = Userlist + ": " + traktUserList.Name;
                        var    cleanupList  = movieListAll.Where(m => m.CategoryTrakt.Contains(userListName)).ToList();
                        TraktLogger.Info("Processing trakt user list '{0}' as tag '{1}' with '{2}' items", traktUserList.Name, userListName, traktUserListMovies.Items.Count);

                        // process 'movies' only
                        foreach (var trm in traktUserListMovies.Items.Where(m => m.Type == "movie"))
                        {
                            TraktLogger.Debug("Processing trakt user list movie - Title '{0}', Year '{1}' ImdbId '{2}'", trm.Title ?? "null", trm.Year ?? "null", trm.ImdbId ?? "null");
                            foreach (var movie in movieListAll.Where(m => MovieMatch(m, trm.Movie)))
                            {
                                if (!movie.CategoryTrakt.Contains(userListName))
                                {
                                    // update local trakt category
                                    TraktLogger.Info("Inserting trakt user list '{0}' for movie '{1} ({2})'", userListName, movie.Title, movie.Year);
                                    movie.CategoryTrakt.Add(userListName);
                                    movie.Username = TraktSettings.Username;
                                    movie.Commit();
                                }
                                cleanupList.Remove(movie);
                            }
                        }

                        // remove tag from remaining films
                        foreach (var movie in cleanupList)
                        {
                            TraktLogger.Info("Removing trakt user list '{0}' for movie '{1} ({2})'", userListName, movie.Title, movie.Year);
                            movie.CategoryTrakt.Remove(userListName);
                            movie.Username = TraktSettings.Username;
                            movie.Commit();
                        }
                    }
                }
                #endregion

                #region update recommendation tags
                IEnumerable <TraktMovie> traktRecommendationMovies = null;
                string Recommendations = Translation.Recommendations;
                TraktLogger.Info("Retrieving recommendations from trakt");
                traktRecommendationMovies = TraktAPI.TraktAPI.GetRecommendedMovies();

                if (traktRecommendationMovies != null)
                {
                    TraktLogger.Info("Retrieved {0} recommendations items from trakt", traktRecommendationMovies.Count());

                    var cleanupList = movieListAll.Where(m => m.CategoryTrakt.Contains(Recommendations)).ToList();
                    foreach (var trm in traktRecommendationMovies)
                    {
                        TraktLogger.Debug("Processing trakt recommendations movie - Title '{0}', Year '{1}' Imdb '{2}'", trm.Title ?? "null", trm.Year ?? "null", trm.IMDBID ?? "null");
                        foreach (var movie in movieListAll.Where(m => MovieMatch(m, trm)))
                        {
                            if (!movie.CategoryTrakt.Contains(Recommendations))
                            {
                                // update local trakt category
                                TraktLogger.Info("Inserting trakt category '{0}' for movie '{1} ({2})'", Recommendations, movie.Title, movie.Year);
                                movie.CategoryTrakt.Add(Recommendations);
                                movie.Username = TraktSettings.Username;
                                movie.Commit();
                            }
                            cleanupList.Remove(movie);
                        }
                    }
                    // remove tag from remaining films
                    foreach (var movie in cleanupList)
                    {
                        // update local trakt category
                        TraktLogger.Info("Removing trakt category '{0}' for movie '{1} ({2})'", Recommendations, movie.Title, movie.Year);
                        movie.CategoryTrakt.Remove(Recommendations);
                        movie.Username = TraktSettings.Username;
                        movie.Commit();
                    }
                }
                #endregion

                #region update trending tags

                /*IEnumerable<TraktTrendingMovie> traktTrendingMovies = null;
                 * string Trending = Translation.Trending;
                 * TraktLogger.Info("Retrieving trending movies from trakt");
                 * traktTrendingMovies = TraktAPI.TraktAPI.GetTrendingMovies();
                 *
                 * if (traktTrendingMovies != null)
                 * {
                 *  TraktLogger.Info("Retrieved {0} trending items from trakt", traktTrendingMovies.Count());
                 *
                 *  var cleanupList = movieListAll.Where(m => m.CategoryTrakt.Contains(Trending)).ToList();
                 *  foreach (var trm in traktTrendingMovies)
                 *  {
                 *      TraktLogger.Debug("Processing trakt user list movie trm.Title '{0}', trm.Year '{1}' trm.Imdb '{2}'", trm.Title ?? "null", trm.Year ?? "null", trm.Imdb ?? "null");
                 *      foreach (var movie in movieListAll.Where(m => MovieMatch(m, trm)))
                 *      {
                 *          if (!movie.CategoryTrakt.Contains(Trending))
                 *          {
                 *              // update local trakt category
                 *              TraktLogger.Info("Inserting trakt category '{0}' for movie '{1} ({2})'", Trending, movie.Title, movie.Year);
                 *              movie.CategoryTrakt.Add(Trending);
                 *              movie.Username = TraktSettings.Username;
                 *              movie.Commit();
                 *          }
                 *          cleanupList.Remove(movie);
                 *      }
                 *  }
                 *  // remove tag from remaining films
                 *  foreach (var movie in cleanupList)
                 *  {
                 *      // update local trakt category
                 *      TraktLogger.Info("Removing trakt category '{0}' for movie '{1} ({2})'", Trending, movie.Title, movie.Year);
                 *      movie.CategoryTrakt.Remove(Trending);
                 *      movie.Username = TraktSettings.Username;
                 *      movie.Commit();
                 *  }
                 * }*/
                #endregion
            }
            else
            {
                if (categoryTraktList.Count > 0)
                {
                    TraktLogger.Info("clearing trakt-categorized movies from MyFilms database", categoryTraktList.Count.ToString());

                    foreach (var movie in categoryTraktList)
                    {
                        movie.CategoryTrakt.Clear();
                        movie.Commit();
                    }
                }
            }
            #endregion

            myvideos.Clear();

            SyncInProgress = false;
            TraktLogger.Info("My Films Sync Completed");
        }
Exemplo n.º 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
        }