private TMDbTrailers GetTvEpisodeTrailersFromCache(string showId, int?season, int?episode) { string key = string.Format("{0}_{1}_{2}_{3}_{4}_{5}", showId, season, episode, PluginSettings.PreferredLanguage, PluginSettings.FallbackToEnglishLanguage, PluginSettings.AlwaysGetEnglishTrailers); TMDbTrailers trailers = null; // check if we have a cached request TrailerCache.TryGetValue(key, out trailers); // check if web request cache has expired and make a new request if (trailers == null || LastWebRequest < DateTime.UtcNow.Subtract(new TimeSpan(0, PluginSettings.WebRequestCacheMinutes, 0))) { // check if we have already cached the request trailers = TMDbAPI.GetEpisodeTrailers(showId, season.ToString(), episode.ToString(), PluginSettings.PreferredLanguage, PluginSettings.FallbackToEnglishLanguage, PluginSettings.AlwaysGetEnglishTrailers); // remove from cache if already exists if (TrailerCache.ContainsKey(key)) { TrailerCache.Remove(key); } // add to cache TrailerCache.Add(key, trailers); LastWebRequest = DateTime.UtcNow; } return(trailers); }
public static string RequestToken() { UIUtils.UpdateStatus("Requesting token from TMDb..."); TMDbTokenResponse response = TMDbAPI.RequestToken(); if (response == null || !response.Success) { UIUtils.UpdateStatus("Failed to get TMDb token", true); Thread.Sleep(2000); return(null); } return(response.RequestToken); }
private List <GUITrailerListItem> SearchMovieTrailers(MediaItem searchItem) { string searchTerm = string.Empty; var listItems = new List <GUITrailerListItem>(); if (!string.IsNullOrEmpty(searchItem.TMDb)) { searchTerm = searchItem.TMDb; } else if (!string.IsNullOrEmpty((searchItem.IMDb ?? string.Empty).Trim())) { var externalId = PluginSettings.IMDbIds.FirstOrDefault(t => t.ExternalId == searchItem.IMDb); if (externalId == null) { // use the find method to lookup by external source id FileLog.Debug("Searching themoviedb.org for all objects with IMDb ID '{0}'", searchItem.IMDb); var findResults = TMDbAPI.TMDbFind(searchItem.IMDb, TMDbAPI.ExternalSource.imdb_id); if (findResults == null || findResults.Movies == null || findResults.Movies.Count == 0) { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, no matches found using IMDb ID"); return(listItems); } // there should only be one searchTerm = findResults.Movies.First().Id.ToString(); // cache id so we can use it again PluginSettings.IMDbIds.Add(new PluginSettings.ExternalID { ExternalId = searchItem.IMDb, TmdbId = findResults.Movies.First().Id }); } else { FileLog.Debug("Found cached TMDb ID '{0}' for IMDb External ID: '{1}'", externalId.TmdbId.ToString(), searchItem.IMDb); searchTerm = externalId.TmdbId.ToString(); } } else if (!string.IsNullOrEmpty(searchItem.Title)) { // we do the best we can with out any proper movie id's FileLog.Debug("Searching themoviedb.org for movie: Title: '{0}', Year: '{1}'", searchItem.Title, searchItem.Year); var searchResults = TMDbAPI.SearchMovies(searchItem.Title, language: "en", year: searchItem.Year <= 1900 ? null : searchItem.Year.ToString()); if (searchResults == null || searchResults.TotalResults == 0) { FileLog.Warning("No movies found, skipping search from the themoviedb.org."); return(listItems); } else { foreach (var movie in searchResults.Results) { FileLog.Debug("Found movie: Title: '{0}', Original Title: '{1}', Release Date: '{2}', TMDb: '{3}', Popularity: '{4}'", movie.Title, movie.OriginalTitle, movie.ReleaseDate, movie.Id, movie.Popularity); } } // get the movie id of the first result, this would be the most likely match (based on popularity) // we can think about providing a menu of choices as well based on demand searchTerm = searchResults.Results.First().Id.ToString(); searchItem.TMDb = searchTerm; } else { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, require IMDb ID, TMDb ID or Title+Year."); return(listItems); } FileLog.Debug("Searching for movie trailers using search term '{0}' from themoviedb.org...", searchTerm); var trailers = GetMovieTrailersFromCache(searchTerm); if (trailers == null || trailers.Results == null) { FileLog.Error("Error getting movie trailers from themoviedb.org."); return(listItems); } foreach (var trailer in trailers.Results) { var listItem = new GUITrailerListItem(); string itemName = string.IsNullOrEmpty(trailer.Type) || trailer.Name.ToLowerInvariant().Contains(trailer.Type.ToLowerInvariant()) ? trailer.Name : string.Format("{0} - {1}", trailer.Name, trailer.Type); itemName = string.IsNullOrEmpty(trailer.Size) || itemName.ToLowerInvariant().Contains(trailer.Size.ToLowerInvariant()) ? itemName : string.Format("{0} ({1})", itemName, trailer.Size); if (PluginSettings.PreferredLanguage != "en") { itemName = string.Format("{0} [{1}]", itemName, trailer.LanguageCode); } listItem.Label = itemName; listItem.Label2 = Localisation.Translation.Online; listItem.URL = WebUtils.GetYouTubeURL(trailer.Key); listItem.TVTag = trailer; listItem.IsOnlineItem = true; listItem.CurrentMedia = searchItem; listItems.Add(listItem); } FileLog.Info("Found {0} movie trailer(s) from themoviedb.org", trailers.Results.Count.ToString()); return(listItems); }
public static string GetMovieSearchTerm(string imdbid, string tmdbid, string title, string year) { string searchTerm = null; if (!string.IsNullOrEmpty(tmdbid)) { searchTerm = tmdbid; } else if (!string.IsNullOrEmpty((imdbid ?? string.Empty).Trim())) { var externalId = PluginSettings.IMDbIds.FirstOrDefault(t => t.ExternalId == imdbid); if (externalId == null) { // use the find method to lookup by external source id FileLog.Debug("Searching themoviedb.org for all objects with IMDb ID '{0}'", imdbid); var findResults = TMDbAPI.TMDbFind(imdbid, TMDbAPI.ExternalSource.imdb_id); if (findResults == null || findResults.Movies == null || findResults.Movies.Count == 0) { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, no matches found using IMDb ID"); return(searchTerm); } // there should only be one searchTerm = findResults.Movies.First().Id.ToString(); // cache id so we can use it again PluginSettings.IMDbIds.Add(new PluginSettings.ExternalID { ExternalId = imdbid, TmdbId = findResults.Movies.First().Id }); } else { FileLog.Debug("Found cached TMDb ID '{0}' for IMDb External ID: '{1}'", externalId.TmdbId.ToString(), imdbid); searchTerm = externalId.TmdbId.ToString(); } } else if (!string.IsNullOrEmpty(title)) { // we do the best we can with out any proper movie id's FileLog.Debug("Searching themoviedb.org for movie: Title: '{0}', Year: '{1}'", title, year); int iYear = 0; int.TryParse(year, out iYear); var searchResults = TMDbAPI.SearchMovies(title, language: "en", year: iYear <= 1900 ? null : year); if (searchResults == null || searchResults.TotalResults == 0) { FileLog.Warning("No movies found, skipping search from the themoviedb.org."); return(searchTerm); } else { foreach (var movie in searchResults.Results) { FileLog.Debug("Found movie: Title: '{0}', Original Title: '{1}', Release Date: '{2}', TMDb: '{3}', Popularity: '{4}'", movie.Title, movie.OriginalTitle, movie.ReleaseDate, movie.Id, movie.Popularity); } } // get the movie id of the first result, this would be the most likely match (based on popularity) // we can think about providing a menu of choices as well based on demand searchTerm = searchResults.Results.First().Id.ToString(); } else { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, require IMDb ID, TMDb ID or Title+Year."); } return(searchTerm); }
private List <GUITrailerListItem> SearchShowTrailers(MediaItem searchItem) { string searchTerm = string.Empty; var listItems = new List <GUITrailerListItem>(); if (!string.IsNullOrEmpty(searchItem.TMDb)) { searchTerm = searchItem.TMDb; } else if (!string.IsNullOrEmpty(searchItem.TVDb)) { // check if external id is cached var externalId = PluginSettings.TVDbIds.FirstOrDefault(t => t.ExternalId == searchItem.TVDb); if (externalId == null) { // use the find method to lookup by external source id FileLog.Debug("Searching themoviedb.org for all objects with TVDb ID '{0}'", searchItem.TVDb); var findResults = TMDbAPI.TMDbFind(searchItem.TVDb, TMDbAPI.ExternalSource.tvdb_id); if (findResults == null || findResults.Shows == null || findResults.Shows.Count == 0) { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, no matches found using TVDb ID"); return(listItems); } // there should only be one searchTerm = findResults.Shows.First().Id.ToString(); // cache id so we can use it again PluginSettings.TVDbIds.Add(new PluginSettings.ExternalID { ExternalId = searchItem.TVDb, TmdbId = findResults.Shows.First().Id }); } else { FileLog.Debug("Found cached TMDb ID '{0}' for TVDb External ID: '{1}'", externalId.TmdbId.ToString(), searchItem.TVDb); searchTerm = externalId.TmdbId.ToString(); } } else if (!string.IsNullOrEmpty(searchItem.IMDb)) { // check if external id is cached var externalId = PluginSettings.IMDbIds.FirstOrDefault(t => t.ExternalId == searchItem.IMDb); if (externalId == null) { FileLog.Debug("Searching themoviedb.org for all objects with IMDb ID '{0}'", searchItem.IMDb); var findResults = TMDbAPI.TMDbFind(searchItem.IMDb, TMDbAPI.ExternalSource.imdb_id); if (findResults == null || findResults.Shows == null || findResults.Shows.Count == 0) { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, no matches found using IMDb ID"); return(listItems); } // there should only be one searchTerm = findResults.Shows.First().Id.ToString(); // cache id so we can use it again PluginSettings.IMDbIds.Add(new PluginSettings.ExternalID { ExternalId = searchItem.IMDb, TmdbId = findResults.Shows.First().Id }); } else { FileLog.Debug("Found cached TMDb ID '{0}' for IMDb External ID: '{1}'", externalId.TmdbId.ToString(), searchItem.IMDb); searchTerm = externalId.TmdbId.ToString(); } } else if (!string.IsNullOrEmpty(searchItem.TVRage)) { // check if external id is cached var externalId = PluginSettings.TVRageIds.FirstOrDefault(t => t.ExternalId == searchItem.TVRage); if (externalId == null) { FileLog.Debug("Searching themoviedb.org for all objects with TVRage ID '{0}'", searchItem.TVRage); var findResults = TMDbAPI.TMDbFind(searchItem.TVRage, TMDbAPI.ExternalSource.tvrage_id); if (findResults == null || findResults.Shows == null || findResults.Shows.Count == 0) { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, no matches found using TVRage ID"); return(listItems); } // there should only be one searchTerm = findResults.Shows.First().Id.ToString(); // cache id so we can use it again PluginSettings.TVRageIds.Add(new PluginSettings.ExternalID { ExternalId = searchItem.TVRage, TmdbId = findResults.Shows.First().Id }); } else { FileLog.Debug("Found cached TMDb ID '{0}' for TVRage External ID: '{1}'", externalId.TmdbId.ToString(), searchItem.TVRage); searchTerm = externalId.TmdbId.ToString(); } } else if (!string.IsNullOrEmpty(searchItem.Title)) { // we do the best we can with out any proper show id's FileLog.Debug("Searching themoviedb.org for show: Title: '{0}', FirstAired: '{1}'", searchItem.Title, searchItem.AirDate ?? "<empty>"); var searchResults = TMDbAPI.SearchShows(searchItem.Title, language: "en", firstAirDate: string.IsNullOrEmpty(searchItem.AirDate) ? null : searchItem.AirDate); if (searchResults == null || searchResults.TotalResults == 0) { FileLog.Warning("No shows found, skipping search from the themoviedb.org."); return(listItems); } else { foreach (var show in searchResults.Results) { FileLog.Debug("Found show: Name: '{0}', Original Name: '{1}', Air Date: '{2}', TMDb: '{3}', Popularity: '{4}'", show.Name, show.OriginalName, show.FirstAirDate, show.Id, show.Popularity); } } // get the show id of the first result, this would be the most likely match (based on popularity) // we can think about providing a menu of choices as well based on demand searchTerm = searchResults.Results.First().Id.ToString(); searchItem.TMDb = searchTerm; } else { FileLog.Warning("Not enough information to search for trailers from themoviedb.org, require IMDb, TVDb, TMDb or TVRage ID or Title+Year."); return(listItems); } FileLog.Debug("Searching for tv {0} trailers using search term '{1}' from themoviedb.org...", searchItem.MediaType.ToString().ToLower(), searchTerm); TMDb.DataStructures.TMDbTrailers trailers = null; // search for correct type switch (searchItem.MediaType) { case MediaItemType.Show: trailers = GetTvShowTrailersFromCache(searchTerm); break; case MediaItemType.Season: trailers = GetTvSeasonTrailersFromCache(searchTerm, searchItem.Season); break; case MediaItemType.Episode: trailers = GetTvEpisodeTrailersFromCache(searchTerm, searchItem.Season, searchItem.Episode); break; } if (trailers == null || trailers.Results == null) { FileLog.Error("Error getting trailers from themoviedb.org."); return(listItems); } foreach (var trailer in trailers.Results) { var listItem = new GUITrailerListItem(); string itemName = string.IsNullOrEmpty(trailer.Type) || trailer.Name.ToLowerInvariant().Contains(trailer.Type.ToLowerInvariant()) ? trailer.Name : string.Format("{0} - {1}", trailer.Name, trailer.Type); itemName = string.IsNullOrEmpty(trailer.Size) || itemName.ToLowerInvariant().Contains(trailer.Size.ToLowerInvariant()) ? itemName : string.Format("{0} ({1})", itemName, trailer.Size); if (PluginSettings.PreferredLanguage != "en") { itemName = string.Format("{0} [{1}]", itemName, trailer.LanguageCode); } listItem.Label = itemName; listItem.Label2 = Localisation.Translation.Online; listItem.URL = WebUtils.GetYouTubeURL(trailer.Key); listItem.TVTag = trailer; listItem.IsOnlineItem = true; listItem.CurrentMedia = searchItem; listItems.Add(listItem); } FileLog.Info("Found {0} tv {1} trailer(s) from themoviedb.org", trailers.Results.Count.ToString(), searchItem.MediaType.ToString().ToLower()); return(listItems); }
public void ImportRatings() { ImportCancelled = false; List <TMDbMovie> watchedMovies = new List <TMDbMovie>(); #region Session Id // check if we have a session id // note: request token if new is only valid for 60mins if (string.IsNullOrEmpty(AppSettings.TMDbSessionId)) { UIUtils.UpdateStatus("Getting TMDb Authentication Session Id..."); var sessionResponse = TMDbAPI.RequestSessionId(AppSettings.TMDbRequestToken); if (sessionResponse == null || !sessionResponse.Success) { UIUtils.UpdateStatus("Unable to get TMDb Authentication Session Id.", true); Thread.Sleep(2000); return; } AppSettings.TMDbSessionId = sessionResponse.SessionId; } if (ImportCancelled) { return; } #endregion #region Account Information UIUtils.UpdateStatus("Getting TMDb Account Id..."); var accountInfo = TMDbAPI.GetAccountId(AppSettings.TMDbSessionId); if (accountInfo == null) { UIUtils.UpdateStatus("Unable to get TMDb Account Id.", true); Thread.Sleep(2000); return; } if (ImportCancelled) { return; } #endregion #region Get Rated Movies UIUtils.UpdateStatus("Getting first batch of TMDb Rated Movies.."); var ratings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1); if (ImportCancelled) { return; } #endregion #region Import Movie Ratings if (ratings.TotalResults == 0) { return; } UIUtils.UpdateStatus(string.Format("[{0}/{1}] Importing {2} TMDb Movie Ratings...", ratings.Page, ratings.TotalPages, ratings.Movies.Count)); var response = TraktAPI.TraktAPI.RateMovies(GetRateMoviesData(ratings.Movies)); if (response == null || response.Status != "success") { UIUtils.UpdateStatus("Failed to send ratings for TMDb movies.", true); Thread.Sleep(2000); if (ImportCancelled) { return; } } // add to list of movies to mark as watched watchedMovies.AddRange(ratings.Movies); // get each page of movies for (int i = 2; i <= ratings.TotalPages; i++) { UIUtils.UpdateStatus(string.Format("[{0}/{1}] Getting next batch of TMDb Rated Movies...", ratings.Page, ratings.TotalPages)); ratings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i); if (ImportCancelled) { return; } UIUtils.UpdateStatus(string.Format("[{0}/{1}] Importing {2} TMDb Movie Ratings...", ratings.Page, ratings.TotalPages, ratings.Movies.Count)); response = TraktAPI.TraktAPI.RateMovies(GetRateMoviesData(ratings.Movies)); if (response == null || response.Status != "success") { UIUtils.UpdateStatus("Failed to send ratings for TMDb movies.", true); Thread.Sleep(2000); if (ImportCancelled) { return; } } // add to list of movies to mark as watched watchedMovies.AddRange(ratings.Movies); } #endregion #region Mark As Watched if (AppSettings.MarkAsWatched && watchedMovies.Count > 0) { // mark all movies as watched if rated UIUtils.UpdateStatus(string.Format("Importing {0} TMDb Movies as Watched...", watchedMovies.Count)); TraktMovieSyncResponse watchedResponse = TraktAPI.TraktAPI.SyncMovieLibrary(GetWatchedMoviesData(watchedMovies), TraktSyncModes.seen); if (watchedResponse == null || watchedResponse.Status != "success") { UIUtils.UpdateStatus("Failed to send watched status for TMDb movies.", true); Thread.Sleep(2000); if (ImportCancelled) { return; } } } #endregion return; }
internal static void ProcessAndDownloadTrailers(MovieTrailers cache, MoviePluginSource pluginSource) { // get a list of movies from the cache that require trailer searches i.e. // where trailer count equals zero and update interval is greater than (now - lastupdate) // typically this will be for any new movies added to library int onlineOps = 0; int saveThreshold = 10; var moviesWithoutTrailers = cache.Movies.Where(m => m.Trailers.Count == 0); foreach (var movie in moviesWithoutTrailers) { // check the date last processed is longer than max period for update (default 7 days) DateTime lastUpdate = DateTime.MinValue; DateTime.TryParse(movie.UpdateTime, out lastUpdate); if (DateTime.Now.Subtract(new TimeSpan(PluginSettings.AutoDownloadUpdateInterval, 0, 0, 0)) < lastUpdate) { continue; } // update the last update time movie.UpdateTime = DateTime.Now.ToString(); // get the search term for trailer search // if there is no 'id' we will get one from a movie lookup FileLog.Info("Searching for trailers from themoviedb.org, Title: '{0}', Year: '{1}', IMDb: '{2}', TMDb: '{3}'", movie.Title, movie.Year, movie.IMDbID ?? "<empty>", movie.TMDbID ?? "<empty>"); string searchTerm = TMDbTrailerProvider.GetMovieSearchTerm(movie.IMDbID, movie.TMDbID, movie.Title, movie.Year); if (searchTerm == null) { continue; } // search for trailers var trailers = TMDbAPI.GetMovieTrailers(searchTerm, PluginSettings.PreferredLanguage, PluginSettings.FallbackToEnglishLanguage, PluginSettings.AlwaysGetEnglishTrailers); if (trailers == null || trailers.Results == null || trailers.Results.Count == 0) { continue; } // save the list of trailers to the cached movie var trailersFound = new List <Trailer>(); foreach (var trailer in trailers.Results) { FileLog.Info("Found Youtube video, Name: '{0}', Quality: '{1}', Source: '{2}', Type: '{3}'", trailer.Name, trailer.Size, trailer.Key, trailer.Type); trailersFound.Add(new Trailer { Name = trailer.Name, Quality = trailer.Size, Source = trailer.Key, Type = trailer.Type, Language = trailer.LanguageCode, IsValid = true }); onlineOps++; } // persist trailers found and update time movie.Trailers = trailersFound; // save cache semi-regularly in case we shutdown/enter stand-by if (onlineOps >= saveThreshold) { TrailerDownloader.SaveMovieList(pluginSource, cache); saveThreshold += 10; } } // now download trailers that have not been processed yet i.e. don't have a physical file path and are valid moviesWithoutTrailers = cache.Movies.Where(m => m.Trailers.Count(t => string.IsNullOrEmpty(t.Path) && t.IsValid) > 0); onlineOps = 0; saveThreshold = 10; foreach (var movie in moviesWithoutTrailers) { FileLog.Info("Checking for trailer downloads, Title: {0}, Year: {1}, IMDb: {2}, TMDb: {3}", movie.Title, movie.Year, movie.IMDbID ?? "<empty>", movie.TMDbID ?? "<empty>"); // only process valid trailers foreach (var trailer in movie.Trailers.Where(t => t.IsValid)) { // if the file already exists skip if (!string.IsNullOrEmpty(trailer.Path)) { if (File.Exists(trailer.Path)) { FileLog.Info("Skipping trailer '{0}' download for '{1}', file already exists", trailer.Name, trailer.Path); continue; } } // check user wants video if (!CheckAllowedTrailerTypes(trailer)) { FileLog.Info("Skipping trailer download for, Name='{0}', Type='{1}', Reason='Unwanted Type'", trailer.Name, trailer.Type); continue; } FileLog.Info("Getting download options for video, Name: {0}, Quality: {1}, Source: {2}, Type: {3}", trailer.Name, trailer.Quality, trailer.Source, trailer.Type); var options = OnlineVideosHandler.GetPlaybackOptionsFromYoutubeUrl(trailer.Source); if (options == null) { FileLog.Warning("Unable to get download options for trailer, marking as invalid"); trailer.IsValid = false; continue; } // get the preferred (best) video codec and type var downloadDetails = TrailerDownloader.GetDownloadDetails(movie, trailer, options); if (downloadDetails == null) { FileLog.Warning("Could not find any matching resolution or lower for download, skipping trailer download"); continue; } // download trailer trailer.IsValid = WebUtils.DownloadFile(downloadDetails.SourceUrl, downloadDetails.DestinationFilename); trailer.Path = downloadDetails.DestinationFilename; onlineOps++; } // save cache semi-regularly in case we shutdown/enter stand-by if (onlineOps >= saveThreshold) { TrailerDownloader.SaveMovieList(pluginSource, cache); saveThreshold += 10; } } // save cache TrailerDownloader.SaveMovieList(pluginSource, cache); }
public void ImportRatings() { importCancelled = false; List <TMDbMovie> watchedMovies = new List <TMDbMovie>(); #region Session Id // check if we have a session id // note: request token if new is only valid for 60mins if (string.IsNullOrEmpty(AppSettings.TMDbSessionId)) { UIUtils.UpdateStatus("Getting TMDb Authentication Session Id..."); var sessionResponse = TMDbAPI.RequestSessionId(AppSettings.TMDbRequestToken); if (sessionResponse == null || !sessionResponse.Success) { UIUtils.UpdateStatus("Unable to get TMDb Authentication Session Id.", true); Thread.Sleep(2000); return; } AppSettings.TMDbSessionId = sessionResponse.SessionId; } if (importCancelled) { return; } #endregion #region Account Information UIUtils.UpdateStatus("Getting TMDb Account Id..."); var accountInfo = TMDbAPI.GetAccountId(AppSettings.TMDbSessionId); if (accountInfo == null) { UIUtils.UpdateStatus("Unable to get TMDb Account Id.", true); Thread.Sleep(2000); return; } if (importCancelled) { return; } #endregion #region Get Rated Movies UIUtils.UpdateStatus("Getting first batch of TMDb rated movies..."); var movieRatings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1); if (importCancelled) { return; } #endregion #region Import Movie Ratings if (movieRatings != null && movieRatings.TotalResults > 0) { UIUtils.UpdateStatus("Retrieving existing movie ratings from trakt.tv"); var currentUserMovieRatings = TraktAPI.GetRatedMovies(); if (currentUserMovieRatings != null) { UIUtils.UpdateStatus("Found {0} user movie ratings on trakt.tv", currentUserMovieRatings.Count()); UIUtils.UpdateStatus("Filtering out movies already rated on trakt.tv"); movieRatings.Movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.TmdbId == m.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Movie Ratings...", movieRatings.Page, movieRatings.TotalPages, movieRatings.Movies.Count); if (movieRatings.Movies.Count > 0) { var response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(movieRatings.Movies)); if (response == null) { UIUtils.UpdateStatus("Failed to send ratings for TMDb movies", true); Thread.Sleep(2000); } else if (response.NotFound.Movies.Count > 0) { UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count); Thread.Sleep(1000); } if (importCancelled) { return; } // add to list of movies to mark as watched watchedMovies.AddRange(movieRatings.Movies); } // get each page of movies for (int i = 2; i <= movieRatings.TotalPages; i++) { UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb Rated Movies...", movieRatings.Page, movieRatings.TotalPages); movieRatings = TMDbAPI.GetRatedMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i); if (movieRatings == null || movieRatings.TotalResults == 0 || importCancelled) { return; } if (currentUserMovieRatings != null) { UIUtils.UpdateStatus("Filtering out movies already rated on trakt.tv"); movieRatings.Movies.RemoveAll(m => currentUserMovieRatings.Any(c => c.Movie.Ids.TmdbId == m.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Movie Ratings...", movieRatings.Page, movieRatings.TotalPages, movieRatings.Movies.Count); if (movieRatings.Movies.Count > 0) { var response = TraktAPI.AddMoviesToRatings(GetRateMoviesData(movieRatings.Movies)); if (response == null) { UIUtils.UpdateStatus("Failed to send ratings for TMDb movies", true); Thread.Sleep(2000); } else if (response.NotFound.Movies.Count > 0) { UIUtils.UpdateStatus("Unable to sync ratings for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count); Thread.Sleep(1000); } if (importCancelled) { return; } // add to list of movies to mark as watched watchedMovies.AddRange(movieRatings.Movies); } } } if (importCancelled) { return; } #endregion #region Mark As Watched if (AppSettings.MarkAsWatched && watchedMovies.Count > 0) { // mark all rated movies as watched UIUtils.UpdateStatus("Importing {0} TMDb movies as watched...", watchedMovies.Count); int pageSize = AppSettings.BatchSize; int pages = (int)Math.Ceiling((double)watchedMovies.Count / pageSize); for (int i = 0; i < pages; i++) { UIUtils.UpdateStatus("Importing page {0}/{1} TMDb movies as watched...", i + 1, pages); var response = TraktAPI.AddMoviesToWatchedHistory(GetSyncWatchedMoviesData(watchedMovies.Skip(i * pageSize).Take(pageSize).ToList())); if (response == null) { UIUtils.UpdateStatus("Failed to send watched status for TMDb movies to trakt.tv", true); Thread.Sleep(2000); } else if (response.NotFound.Movies.Count > 0) { UIUtils.UpdateStatus("Unable to sync watched states for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } } #endregion #region Get Rated Shows UIUtils.UpdateStatus("Getting first batch of TMDb rated shows..."); var showRatings = TMDbAPI.GetRatedShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1); if (importCancelled) { return; } #endregion #region Import Show Ratings if (showRatings != null && showRatings.TotalResults > 0) { return; } { UIUtils.UpdateStatus("Retrieving existing show ratings from trakt.tv"); var currentUserShowRatings = TraktAPI.GetRatedShows(); if (currentUserShowRatings != null) { UIUtils.UpdateStatus("Found {0} user show ratings on trakt.tv", currentUserShowRatings.Count()); UIUtils.UpdateStatus("Filtering out shows already rated on trakt.tv"); showRatings.Shows.RemoveAll(s => currentUserShowRatings.Any(c => c.Show.Ids.TmdbId == s.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb Show Ratings...", showRatings.Page, showRatings.TotalPages, showRatings.Shows.Count); if (showRatings == null || showRatings.Shows.Count > 0) { var response = TraktAPI.AddShowsToRatings(GetRateShowsData(showRatings.Shows)); if (response == null) { UIUtils.UpdateStatus("Failed to send ratings for TMDb shows", true); Thread.Sleep(2000); } else if (response.NotFound.Shows.Count > 0) { UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } // get each page of movies for (int i = 2; i <= showRatings.TotalPages; i++) { UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb rated shows...", showRatings.Page, showRatings.TotalPages); showRatings = TMDbAPI.GetRatedShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i); if (importCancelled) { return; } if (currentUserShowRatings != null) { UIUtils.UpdateStatus("Filtering out shows already rated on trakt.tv"); showRatings.Shows.RemoveAll(s => currentUserShowRatings.Any(c => c.Show.Ids.TmdbId == s.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb show ratings...", showRatings.Page, showRatings.TotalPages, showRatings.Shows.Count); if (showRatings == null || showRatings.Shows.Count > 0) { var response = TraktAPI.AddShowsToRatings(GetRateShowsData(showRatings.Shows)); if (response == null) { UIUtils.UpdateStatus("Failed to send ratings for TMDb shows.", true); Thread.Sleep(2000); } else if (response.NotFound.Shows.Count > 0) { UIUtils.UpdateStatus("Unable to sync ratings for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } } } if (importCancelled) { return; } #endregion #region Import Watchlist if (AppSettings.TMDbSyncWatchlist) { #region Movies IEnumerable <TraktMoviePlays> traktWatchedMovies = null; UIUtils.UpdateStatus("Getting first batch of TMDb watchlist movies..."); var moviesInWatchlist = TMDbAPI.GetWatchlistMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1); if (importCancelled) { return; } if (moviesInWatchlist != null && moviesInWatchlist.TotalResults > 0) { UIUtils.UpdateStatus("Requesting existing watchlist movies from trakt..."); var traktWatchlistMovies = TraktAPI.GetWatchlistMovies(); if (traktWatchlistMovies != null) { UIUtils.UpdateStatus("Found {0} watchlist movies on trakt", traktWatchlistMovies.Count()); UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv"); moviesInWatchlist.Movies.RemoveAll(w => traktWatchlistMovies.FirstOrDefault(t => t.Movie.Ids.TmdbId == w.Id) != null); } if (importCancelled) { return; } if (AppSettings.IgnoreWatchedForWatchlist) { UIUtils.UpdateStatus("Retrieving existing watched movies from trakt.tv"); traktWatchedMovies = TraktAPI.GetWatchedMovies(); if (traktWatchedMovies != null) { UIUtils.UpdateStatus("Found {0} watched movies on trakt.tv", traktWatchedMovies.Count()); UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watched on trakt.tv"); moviesInWatchlist.Movies.RemoveAll(m => traktWatchedMovies.Any(c => c.Movie.Ids.TmdbId == m.Id)); } } if (importCancelled) { return; } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages, moviesInWatchlist.Movies.Count); if (moviesInWatchlist.Movies.Count > 0) { var response = TraktAPI.AddMoviesToWatchlist(GetSyncMoviesData(moviesInWatchlist.Movies)); if (response == null) { UIUtils.UpdateStatus("Failed to send watchlist for TMDb movies", true); Thread.Sleep(2000); } else if (response.NotFound.Movies.Count > 0) { UIUtils.UpdateStatus(string.Format("Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count)); Thread.Sleep(1000); } if (importCancelled) { return; } } // get each page of movies for (int i = 2; i <= moviesInWatchlist.TotalPages; i++) { UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages); moviesInWatchlist = TMDbAPI.GetWatchlistMovies(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i); if (importCancelled) { return; } if (moviesInWatchlist != null && moviesInWatchlist.TotalResults > 0) { if (traktWatchlistMovies != null) { UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watchlist on trakt.tv"); moviesInWatchlist.Movies.RemoveAll(w => traktWatchlistMovies.FirstOrDefault(t => t.Movie.Ids.TmdbId == w.Id) != null); } if (traktWatchedMovies != null) { UIUtils.UpdateStatus("Filtering out watchlist movies that are already in watched on trakt.tv"); moviesInWatchlist.Movies.RemoveAll(m => traktWatchedMovies.Any(c => c.Movie.Ids.TmdbId == m.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist movies...", moviesInWatchlist.Page, moviesInWatchlist.TotalPages, moviesInWatchlist.Movies.Count); if (moviesInWatchlist.Movies.Count > 0) { var response = TraktAPI.AddMoviesToWatchlist(GetSyncMoviesData(moviesInWatchlist.Movies)); if (response == null) { UIUtils.UpdateStatus("Failed to send watchlist for TMDb movies", true); Thread.Sleep(2000); } else if (response.NotFound.Movies.Count > 0) { UIUtils.UpdateStatus("Unable to sync watchlist for {0} movies as they're not found on trakt.tv!", response.NotFound.Movies.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } } } } if (importCancelled) { return; } #endregion #region Shows IEnumerable <TraktShowPlays> traktWatchedShows = null; UIUtils.UpdateStatus("Getting first batch of TMDb watchlist shows..."); var showsInWatchlist = TMDbAPI.GetWatchlistShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, 1); if (importCancelled) { return; } if (showsInWatchlist != null || showsInWatchlist.TotalResults > 0) { UIUtils.UpdateStatus("Requesting existing watchlist shows from trakt..."); var traktWatchlistShows = TraktAPI.GetWatchlistShows(); if (traktWatchlistShows != null) { UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", traktWatchlistShows.Count()); UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv"); showsInWatchlist.Shows.RemoveAll(w => traktWatchlistShows.FirstOrDefault(t => t.Show.Ids.TmdbId == w.Id) != null); } if (AppSettings.IgnoreWatchedForWatchlist) { UIUtils.UpdateStatus("Retrieving existing watched shows from trakt.tv."); traktWatchedShows = TraktAPI.GetWatchedShows(); if (traktWatchedShows != null) { UIUtils.UpdateStatus("Found {0} watched shows on trakt.tv", traktWatchedShows.Count()); UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watched on trakt.tv"); showsInWatchlist.Shows.RemoveAll(s => traktWatchedShows.Any(c => c.Show.Ids.TmdbId == s.Id)); } } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages, showsInWatchlist.Shows.Count); if (showsInWatchlist.Shows.Count > 0) { var response = TraktAPI.AddShowsToWatchlist(GetSyncShowsData(showsInWatchlist.Shows)); if (response == null) { UIUtils.UpdateStatus("Failed to send watchlist for TMDb shows.", true); Thread.Sleep(2000); } else if (response.NotFound.Shows.Count > 0) { UIUtils.UpdateStatus("Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } // get each page of movies for (int i = 2; i <= showsInWatchlist.TotalPages; i++) { UIUtils.UpdateStatus("[{0}/{1}] Getting next batch of TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages); showsInWatchlist = TMDbAPI.GetWatchlistShows(accountInfo.Id.ToString(), AppSettings.TMDbSessionId, i); if (importCancelled) { return; } if (showsInWatchlist != null || showsInWatchlist.TotalResults > 0) { if (traktWatchlistShows != null) { UIUtils.UpdateStatus("Found {0} watchlist shows on trakt", traktWatchlistShows.Count()); UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watchlist on trakt.tv"); showsInWatchlist.Shows.RemoveAll(w => traktWatchlistShows.FirstOrDefault(t => t.Show.Ids.TmdbId == w.Id) != null); } if (traktWatchedShows != null) { UIUtils.UpdateStatus("Filtering out watchlist shows that are already in watched on trakt.tv"); showsInWatchlist.Shows.RemoveAll(s => traktWatchedShows.Any(c => c.Show.Ids.TmdbId == s.Id)); } UIUtils.UpdateStatus("[{0}/{1}] Importing {2} TMDb watchlist shows...", showsInWatchlist.Page, showsInWatchlist.TotalPages, showsInWatchlist.Shows.Count); if (showsInWatchlist.Shows.Count > 0) { var response = TraktAPI.AddShowsToWatchlist(GetSyncShowsData(showsInWatchlist.Shows)); if (response == null) { UIUtils.UpdateStatus("Failed to send watchlist for TMDb shows", true); Thread.Sleep(2000); } else if (response.NotFound.Shows.Count > 0) { UIUtils.UpdateStatus("Unable to sync watchlist for {0} shows as they're not found on trakt.tv!", response.NotFound.Shows.Count); Thread.Sleep(1000); } if (importCancelled) { return; } } } } } if (importCancelled) { return; } #endregion } #endregion }