/// <summary> /// Creates Sync Data based on a TraktLibraryShows object /// </summary> /// <param name="show">The show to base the object on</param> /// <returns>The Trakt Sync data to send</returns> public static TraktEpisodeSync CreateEpisodeSyncData(TraktLibraryShow show) { TraktEpisodeSync syncData = new TraktEpisodeSync { SeriesID = show.SeriesId, Title = show.Title, UserName = TraktSettings.Username, Password = TraktSettings.Password }; var episodes = new List <TraktEpisodeSync.Episode>(); foreach (var season in show.Seasons) { foreach (var episode in season.Episodes) { episodes.Add(new TraktEpisodeSync.Episode { EpisodeIndex = episode.ToString(), SeasonIndex = season.Season.ToString() }); } } syncData.EpisodeList = episodes; return(syncData); }
private TraktEpisodeSync CreateEpisodeSyncData(TraktUserListItem item) { if (item == null) { return(null); } TraktEpisodeSync.Episode syncEpisode = new TraktEpisodeSync.Episode { EpisodeIndex = item.EpisodeNumber.ToString(), SeasonIndex = item.SeasonNumber.ToString() }; TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = TraktSettings.Username, Password = TraktSettings.Password, SeriesID = item.Show.Tvdb, Title = item.Show.Title, Year = item.Year, EpisodeList = new List <TraktEpisodeSync.Episode> { syncEpisode } }; return(syncData); }
private TraktEpisodeSync CreateSyncData(KeyValuePair <TraktShow, TraktWatchListEpisode.Episode> item) { var series = item.Key; var episode = item.Value; List <TraktEpisodeSync.Episode> episodes = new List <TraktEpisodeSync.Episode>(); TraktEpisodeSync.Episode ep = new TraktEpisodeSync.Episode { EpisodeIndex = episode.Number.ToString(), SeasonIndex = episode.Season.ToString() }; episodes.Add(ep); TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = TraktSettings.Username, Password = TraktSettings.Password, SeriesID = series.Tvdb, Title = series.Title, Year = series.Year.ToString(), EpisodeList = episodes }; return(syncData); }
private void OnToggleWatched(List <AnimeEpisode> episodes, bool state) { if (TraktSettings.AccountStatus != ConnectionState.Connected) { return; } TraktLogger.Info("Received togglewatched event from my anime"); Thread toggleWatched = new Thread(delegate() { foreach (var series in episodes.Select(e => e.Series.TvDB_ID).Distinct().ToList()) { if (series == null) { continue; } TraktEpisodeSync episodeSyncData = CreateSyncData(AnimeSeries.GetSeriesWithSpecificTvDB((int)series).First(), episodes); if (episodeSyncData == null) { return; } TraktResponse response = TraktAPI.TraktAPI.SyncEpisodeLibrary(episodeSyncData, state ? TraktSyncModes.seen : TraktSyncModes.unseen); TraktAPI.TraktAPI.LogTraktResponse(response); } }) { IsBackground = true, Name = "ToggleWatched" }; toggleWatched.Start(); }
/// <summary> /// Removes all episode ratings from trakt /// </summary> /// <param name="syncData">list of episodes</param> public static TraktSyncResponse RemoveEpisodesFromRatings(TraktEpisodeSync syncData) { if (syncData == null) { return(null); } var response = TraktWeb.PostToTrakt(TraktURIs.SyncRatingsRemove, syncData.ToJSON()); return(response.FromJSON <TraktSyncResponse>()); }
/// <summary> /// Creates Sync Data based on Series object and a List of Episode objects /// </summary> /// <param name="series">The series to base the object on</param> /// <param name="epsiodes">The list of episodes to base the object on</param> /// <returns>The Trakt Sync data to send</returns> private TraktEpisodeSync CreateSyncData(AnimeSeries series, List <FileLocal> episodes) { if (series == null || series.TvDB_ID == null) { return(null); } // set series properties for episodes TraktEpisodeSync traktSync = new TraktEpisodeSync { Password = TraktSettings.Password, UserName = TraktSettings.Username, SeriesID = series.TvDB_ID.ToString(), Year = GetStartYear(series), Title = series.SeriesName }; // get list of episodes for series List <TraktEpisodeSync.Episode> epList = new List <TraktEpisodeSync.Episode>(); foreach (FileLocal file in episodes.Where(e => (e.AniDB_File != null && e.AniDB_File.AnimeSeries.TvDB_ID == series.TvDB_ID))) { TraktEpisodeSync.Episode episode = new TraktEpisodeSync.Episode(); // can have multiple episodes linked to a file? foreach (var ep in file.AnimeEpisodes) { string seriesid = series.TvDB_ID.ToString(); int seasonidx = 0; int episodeidx = 0; if (GetTVDBEpisodeInfo(ep, out seriesid, out seasonidx, out episodeidx)) { episode.SeasonIndex = seasonidx.ToString(); episode.EpisodeIndex = episodeidx.ToString(); epList.Add(episode); } else { TraktLogger.Info("Unable to find match for episode: '{0} | airDate: {1}'", ep.ToString(), ep.AniDB_Episode.AirDateAsDate.ToString("yyyy-MM-dd")); } } } if (epList.Count == 0) { TraktLogger.Warning("Unable to find any matching TVDb episodes for series '{0}', confirm Absolute Order and/or Episode Names and/or AirDates for episodes are correct on http://theTVDb.com and your database.", series.SeriesName); return(null); } traktSync.EpisodeList = epList; return(traktSync); }
/// <summary> /// Sends episode sync data to Trakt Watchlist /// </summary> /// <param name="syncData">The sync data to send</param> /// <returns>The response from trakt</returns> public static TraktSyncResponse AddEpisodesToWatchlist(TraktEpisodeSync syncData) { // check that we have everything we need if (syncData == null || syncData.Episodes == null || syncData.Episodes.Count == 0) return null; // serialize data to JSON and send to server string response = TraktWeb.PostToTrakt(TraktURIs.SyncWatchlist, syncData.ToJSON()); // return success or failure return response.FromJSON<TraktSyncResponse>(); }
/// <summary> /// Sends episode sync data to Trakt Watchlist /// </summary> /// <param name="syncData">The sync data to send</param> /// <returns>The response from trakt</returns> public static TraktSyncResponse AddEpisodesToWatchlist(TraktEpisodeSync syncData) { // check that we have everything we need if (syncData == null || syncData.Episodes == null || syncData.Episodes.Count == 0) { return(null); } // serialize data to JSON and send to server string response = TraktWeb.PostToTrakt(TraktURIs.SyncWatchlist, syncData.ToJSON()); // return success or failure return(response.FromJSON <TraktSyncResponse>()); }
/// <summary> /// Sends episode sync data to Trakt /// </summary> /// <param name="syncData">The sync data to send</param> /// <param name="mode">The sync mode to use</param> public static TraktResponse SyncEpisodeLibrary(TraktEpisodeSync syncData, TraktSyncModes mode) { // check that we have everything we need if (syncData == null || string.IsNullOrEmpty(syncData.SeriesID)) { return(null); } // serialize data to JSON and send to server string response = TraktWeb.Transmit(string.Format(TraktURIs.SyncEpisodeLibrary, mode.ToString()), syncData.ToJSON()); // return success or failure return(response.FromJSON <TraktResponse>()); }
public static void RemoveEpisodesFromWatchlist() { if (Cancel) { return; } UIUtils.UpdateStatus("Getting watchlisted episodes from trakt.tv"); var watchlistedEpisodes = TraktAPI.TraktAPI.GetWatchlistEpisodes(); if (watchlistedEpisodes != null) { UIUtils.UpdateStatus("Found {0} episodes watchlisted on trakt.tv", watchlistedEpisodes.Count()); int pageSize = AppSettings.BatchSize; int pages = (int)Math.Ceiling((double)watchlistedEpisodes.Count() / pageSize); for (int i = 0; i < pages; i++) { if (Cancel) { return; } var syncData = new TraktEpisodeSync { Episodes = watchlistedEpisodes.Select(r => new TraktEpisode { Ids = r.Episode.Ids }) .Skip(i * pageSize).Take(pageSize).ToList() }; UIUtils.UpdateStatus("[{0}/{1}] Removing episodes from trakt.tv watchlist", i + 1, pages); var syncResponse = TraktAPI.TraktAPI.RemoveEpisodesFromWatchlist(syncData); if (syncResponse == null) { UIUtils.UpdateStatus(string.Format("[{0}/{1}] Failed to remove episodes from trakt.tv watchlist", i + 1, pages), true); Thread.Sleep(2000); continue; } } } else { UIUtils.UpdateStatus("Failed to get current list of watchlisted episodes from trakt.tv", true); Thread.Sleep(2000); } }
public static TraktEpisodeSync CreateEpisodeSyncData(string title, string year, string tvdbid, string seasonidx, string episodeidx) { TraktEpisodeSync syncData = new TraktEpisodeSync { SeriesID = tvdbid, Title = title, EpisodeList = new List <TraktEpisodeSync.Episode> { new TraktEpisodeSync.Episode { EpisodeIndex = episodeidx, SeasonIndex = seasonidx } }, UserName = TraktSettings.Username, Password = TraktSettings.Password }; return(syncData); }
/// <summary> /// returns a list of shows with episodes to mark as watched /// must send to trakt per show! /// </summary> private List <TraktEpisodeSync> GetWatchedEpisodeData(List <TraktEpisode> episodes) { var traktEpisodesSync = new List <TraktEpisodeSync>(); // seperate episodes list into shows foreach (var showId in episodes.Select(e => e.TVDbId).Distinct()) { var episodesInShow = episodes.Where(e => e.TVDbId == showId); var episodesWatchedData = new List <TraktEpisodeSync.Episode>(); if (episodesInShow.Count() == 0) { continue; } episodesWatchedData.AddRange(from episode in episodesInShow select new TraktEpisodeSync.Episode { EpisodeIndex = episode.Episode.ToString(), SeasonIndex = episode.Season.ToString() }); if (episodesWatchedData.Count() == 0) { continue; } var episodeSyncData = new TraktEpisodeSync { UserName = AppSettings.TraktUsername, Password = AppSettings.TraktPassword, EpisodeList = episodesWatchedData, SeriesID = showId.ToString(), Title = episodesInShow.First().Title, Year = episodesInShow.First().Year.ToString() }; traktEpisodesSync.Add(episodeSyncData); } return(traktEpisodesSync); }
/// <summary> /// Syncronize our collection on trakt /// </summary> /// <param name="episodes">local tvseries dbepisode list</param> /// <param name="mode">trakt sync mode</param> private void SyncLibrary(List <FileLocal> episodes, TraktSyncModes mode) { if (episodes.Count == 0) { return; } // get unique series ids var uniqueSeries = (from s in episodes where (s.AniDB_File != null && s.AniDB_File.AnimeSeries.TvDB_ID > 0) select s.AniDB_File.AnimeSeries.TvDB_ID).Distinct().ToList(); if (uniqueSeries.Count == 0) { TraktLogger.Info("TVDb info not available for series, can not sync '{0}' with trakt.", mode.ToString()); } // go over each series, can only send one series at a time foreach (int seriesid in uniqueSeries) { // There should only be one series List <AnimeSeries> series = AnimeSeries.GetSeriesWithSpecificTvDB(seriesid); if (series == null) { continue; } TraktLogger.Info("Synchronizing '{0}' episodes for series '{1}'.", mode.ToString(), series[0].ToString()); // upload to trakt TraktEpisodeSync episodeSync = CreateSyncData(series[0], episodes); if (episodeSync != null) { TraktResponse response = TraktAPI.TraktAPI.SyncEpisodeLibrary(episodeSync, mode); // check for any error and log result TraktAPI.TraktAPI.LogTraktResponse(response); // wait a short period before uploading another series Thread.Sleep(2000); } } }
/// <summary> /// Removes episodes on trakt that no longer exist in users database /// </summary> /// <param name="traktShows">trakt episode collection</param> /// <param name="episodes">list of local episodes</param> /// <param name="seriesID">tvdb series id of series</param> /// <returns>true if episode exists</returns> private TraktEpisodeSync GetEpisodesForTraktRemoval(TraktLibraryShow traktShow, List <FileLocal> episodes) { List <TraktEpisodeSync.Episode> episodeList = new List <TraktEpisodeSync.Episode>(); foreach (var season in traktShow.Seasons) { foreach (var episode in season.Episodes) { var query = episodes.Where(e => e.AniDB_File != null && e.AniDB_File.AnimeSeries.TvDB_ID.ToString() == traktShow.SeriesId && e.AniDB_File.AnimeSeries.TvDB_Episodes.Where(t => !string.IsNullOrEmpty(t.Filename) && t.SeasonNumber == season.Season && t.EpisodeNumber == episode).Count() == 1).ToList(); if (query.Count == 0) { // we dont have the episode anymore TraktLogger.Info("{0} - {1}x{2} does not exist in local database, marked for removal from trakt", traktShow.ToString(), season.Season.ToString(), episode.ToString()); TraktEpisodeSync.Episode ep = new TraktEpisodeSync.Episode { EpisodeIndex = episode.ToString(), SeasonIndex = season.Season.ToString() }; episodeList.Add(ep); } } } if (episodeList.Count > 0) { TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = TraktSettings.Username, Password = TraktSettings.Password, SeriesID = traktShow.SeriesId, EpisodeList = episodeList }; return(syncData); } return(null); }
private TraktEpisodeSync CreateEpisodeSyncData(TraktEpisode episode) { List <TraktEpisodeSync.Episode> episodes = new List <TraktEpisodeSync.Episode>(); TraktEpisodeSync.Episode ep = new TraktEpisodeSync.Episode { EpisodeIndex = episode.Number.ToString(), SeasonIndex = episode.Season.ToString() }; episodes.Add(ep); TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = TraktSettings.Username, Password = TraktSettings.Password, SeriesID = Show.Tvdb, Title = Show.Title, Year = Show.Year.ToString(), EpisodeList = episodes }; return(syncData); }
public static void RemoveEpisodeFromLibrary(string title, string year, string tvdbid, string seasonidx, string episodeidx) { TraktEpisodeSync syncObject = BasicHandler.CreateEpisodeSyncData(title, year, tvdbid, seasonidx, episodeidx); if (syncObject == null) { return; } Thread syncThread = new Thread(delegate(object obj) { TraktResponse response = TraktAPI.TraktAPI.SyncEpisodeWatchList((obj as TraktEpisodeSync), TraktSyncModes.unlibrary); if (response == null || response.Status != "success") { return; } }) { IsBackground = true, Name = "RemoveLibrary" }; syncThread.Start(syncObject); }
public static TraktEpisodeSync GetTraktEpisodeData(IEnumerable <IMDbEpisode> episodes) { if (episodes == null) { return(null); } var traktEpisodes = new List <TraktEpisode>(); traktEpisodes.AddRange(from episode in episodes select new TraktEpisode { Ids = new TraktEpisodeId { TvdbId = episode.TvdbId, ImdbId = episode.ImdbId } }); var episodeSync = new TraktEpisodeSync { Episodes = traktEpisodes }; return(episodeSync); }
public static void RemoveEpisodesFromRatings() { if (Cancel) return; UIUtils.UpdateStatus("Getting rated episodes from trakt.tv"); var ratedEpisodes = TraktAPI.TraktAPI.GetRatedEpisodes(); if (ratedEpisodes != null) { UIUtils.UpdateStatus("Found {0} episodes rated on trakt.tv", ratedEpisodes.Count()); int pageSize = AppSettings.BatchSize; int pages = (int)Math.Ceiling((double)ratedEpisodes.Count() / pageSize); for (int i = 0; i < pages; i++) { if (Cancel) return; var syncData = new TraktEpisodeSync { Episodes = ratedEpisodes.Select(r => new TraktEpisode { Ids = r.Episode.Ids }) .Skip(i * pageSize).Take(pageSize).ToList() }; UIUtils.UpdateStatus("[{0}/{1}] Removing episodes from trakt.tv ratings", i + 1, pages); var syncResponse = TraktAPI.TraktAPI.RemoveEpisodesFromRatings(syncData); if (syncResponse == null) { UIUtils.UpdateStatus(string.Format("[{0}/{1}] Failed to remove episodes from trakt.tv ratings", i + 1, pages), true); Thread.Sleep(2000); continue; } } } else { UIUtils.UpdateStatus("Failed to get current list of rated episodes from trakt.tv", true); Thread.Sleep(2000); } }
public static TraktEpisodeSync GetTraktEpisodeData(IEnumerable<IMDbEpisode> episodes) { if (episodes == null) return null; var traktEpisodes = new List<TraktEpisode>(); traktEpisodes.AddRange(from episode in episodes select new TraktEpisode { Ids = new TraktEpisodeId { TvdbId = episode.TvdbId, ImdbId = episode.ImdbId } }); var episodeSync = new TraktEpisodeSync { Episodes = traktEpisodes }; return episodeSync; }
public bool SyncSeries() { try { TestStatus = "[Trakt.SyncSeries]"; Guid[] types = { MediaAspect.ASPECT_ID, SeriesAspect.ASPECT_ID }; MediaItemQuery mediaItemQuery = new MediaItemQuery(types, null, null); var contentDirectory = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory; if (contentDirectory == null) { TestStatus = "[Trakt.MediaLibraryNotConnected]"; return(false); } var episodes = contentDirectory.Search(mediaItemQuery, true); var series = episodes.ToLookup(GetSeriesKey); foreach (var serie in series) { var imdbId = serie.Select(episode => { string value; return(MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) ? value : null); }).FirstOrDefault(value => !string.IsNullOrWhiteSpace(value)); var tvdbId = serie.Select(episode => { int value; return(MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_TVDB_ID, out value) ? value : 0); }).FirstOrDefault(value => value != 0); TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = Username, Password = Password, EpisodeList = new List <TraktEpisodeSync.Episode>(), Title = serie.Key, Year = serie.Min(e => { int year; string seriesTitle; GetSeriesTitleAndYear(e, out seriesTitle, out year); return(year); }).ToString() }; if (!string.IsNullOrWhiteSpace(imdbId)) { syncData.IMDBID = imdbId; } if (tvdbId > 0) { syncData.SeriesID = tvdbId.ToString(); } HashSet <TraktEpisodeSync.Episode> uniqueEpisodes = new HashSet <TraktEpisodeSync.Episode>(); foreach (var episode in serie) { string seriesTitle; int year = 0; if (!GetSeriesTitle/*AndYear*/ (episode, out seriesTitle /*, out year*/)) { continue; } // First send all movies to Trakt that we have so they appear in library CollectionUtils.AddAll(uniqueEpisodes, ToSeries(episode)); } syncData.EpisodeList = uniqueEpisodes.ToList(); TraktSyncModes traktSyncMode = TraktSyncModes.library; var response = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode); ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error); // Then send only the watched movies as "seen" uniqueEpisodes.Clear(); foreach (var seenEpisode in episodes.Where(IsWatched)) { CollectionUtils.AddAll(uniqueEpisodes, ToSeries(seenEpisode)); } syncData.EpisodeList = uniqueEpisodes.ToList(); traktSyncMode = TraktSyncModes.seen; response = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode); ServiceRegistration.Get <ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error); return(true); } } catch (Exception ex) { ServiceRegistration.Get <ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex); } return(false); }
/// <summary> /// Removes all episodes from watchlist from trakt /// </summary> /// <param name="syncData">list of episodes</param> public static TraktSyncResponse RemoveEpisodesFromWatchlist(TraktEpisodeSync syncData) { if (syncData == null) return null; var response = TraktWeb.PostToTrakt(TraktURIs.SyncWatchlistRemove, syncData.ToJSON()); return response.FromJSON<TraktSyncResponse>(); }
public void SyncLibrary() { TraktLogger.Info("My Anime Starting Sync"); #region Get online data // get all episodes on trakt that are marked as in 'collection' IEnumerable <TraktLibraryShow> traktCollectionEpisodes = TraktAPI.TraktAPI.GetLibraryEpisodesForUser(TraktSettings.Username); if (traktCollectionEpisodes == null) { TraktLogger.Error("Error getting show collection from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows in trakt collection", traktCollectionEpisodes.Count().ToString()); // get all episodes on trakt that are marked as 'seen' or 'watched' IEnumerable <TraktLibraryShow> traktWatchedEpisodes = TraktAPI.TraktAPI.GetWatchedEpisodesForUser(TraktSettings.Username); if (traktWatchedEpisodes == null) { TraktLogger.Error("Error getting shows watched from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows with watched episodes in trakt library", traktWatchedEpisodes.Count().ToString()); // get all episodes on trakt that are marked as 'unseen' IEnumerable <TraktLibraryShow> traktUnSeenEpisodes = TraktAPI.TraktAPI.GetUnSeenEpisodesForUser(TraktSettings.Username); if (traktUnSeenEpisodes == null) { TraktLogger.Error("Error getting shows unseen from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows with unseen episodes in trakt library", traktUnSeenEpisodes.Count().ToString()); #endregion #region Get local data List <FileLocal> localCollectionEpisodes = new List <FileLocal>(); List <FileLocal> localWatchedEpisodes = new List <FileLocal>(); // Get all local episodes in database localCollectionEpisodes = FileLocal.GetAll().Where(f => !string.IsNullOrEmpty(f.FileNameFull) && f.AnimeEpisodes.Count > 0).ToList(); TraktLogger.Info("{0} episodes with local files in my anime database", localCollectionEpisodes.Count.ToString()); // Get only Valid Episodes types localCollectionEpisodes.RemoveAll(lc => lc.AnimeEpisodes.Where(e => (e.EpisodeTypeEnum != enEpisodeType.Normal && e.EpisodeTypeEnum != enEpisodeType.Special)).Count() > 0); TraktLogger.Info("{0} episodes with valid episode types in my anime database", localCollectionEpisodes.Count.ToString()); // Get watched episodes localWatchedEpisodes = localCollectionEpisodes.Where(f => (f.AniDB_File != null && f.AniDB_File.IsWatched > 0) || (f.AnimeEpisodes != null && f.AnimeEpisodes[0].IsWatched > 0)).ToList(); TraktLogger.Info("{0} episodes watched in my anime database", localWatchedEpisodes.Count.ToString()); #endregion #region Sync collection/library to trakt // get list of episodes that we have not already trakt'd List <FileLocal> localEpisodesToSync = new List <FileLocal>(localCollectionEpisodes); foreach (FileLocal ep in localCollectionEpisodes) { if (TraktEpisodeExists(traktCollectionEpisodes, ep)) { // no interest in syncing, remove localEpisodesToSync.Remove(ep); } } // sync unseen episodes TraktLogger.Info("{0} episodes need to be added to Library", localEpisodesToSync.Count.ToString()); SyncLibrary(localEpisodesToSync, TraktSyncModes.library); #endregion #region Sync seen to trakt // get list of episodes that we have not already trakt'd // filter out any marked as UnSeen List <FileLocal> localWatchedEpisodesToSync = new List <FileLocal>(localWatchedEpisodes); foreach (FileLocal ep in localWatchedEpisodes) { if (TraktEpisodeExists(traktWatchedEpisodes, ep) || TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // no interest in syncing, remove localWatchedEpisodesToSync.Remove(ep); } } // sync seen episodes TraktLogger.Info("{0} episodes need to be added to SeenList", localWatchedEpisodesToSync.Count.ToString()); SyncLibrary(localWatchedEpisodesToSync, TraktSyncModes.seen); #endregion #region Sync watched flags from trakt locally // Sync watched flags from trakt to local database // do not mark as watched locally if UnSeen on trakt foreach (FileLocal ep in localCollectionEpisodes.Where(e => e.AnimeEpisodes[0].IsWatched == 0)) { if (TraktEpisodeExists(traktWatchedEpisodes, ep) && !TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // mark episode as watched TraktLogger.Info("Marking episode '{0}' as watched", ep.ToString()); ep.AnimeEpisodes[0].ToggleWatchedStatus(true, false); } } #endregion #region Sync unseen flags from trakt locally foreach (FileLocal ep in localCollectionEpisodes.Where(e => e.AnimeEpisodes[0].IsWatched > 1)) { if (TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // mark episode as unwatched TraktLogger.Info("Marking episode '{0}' as unwatched", ep.ToString()); ep.AnimeEpisodes[0].ToggleWatchedStatus(false, false); } } #endregion #region Clean Library if (TraktSettings.KeepTraktLibraryClean && TraktSettings.TvShowPluginCount == 1) { TraktLogger.Info("Removing shows From Trakt Collection no longer in database"); // if we no longer have a file reference in database remove from library foreach (var series in traktCollectionEpisodes) { TraktEpisodeSync syncData = GetEpisodesForTraktRemoval(series, localCollectionEpisodes.Where(e => e.AniDB_File.AnimeSeries.TvDB_ID.ToString() == series.SeriesId).ToList()); if (syncData == null) { continue; } TraktResponse response = TraktAPI.TraktAPI.SyncEpisodeLibrary(syncData, TraktSyncModes.unlibrary); TraktAPI.TraktAPI.LogTraktResponse(response); Thread.Sleep(500); } } #endregion TraktLogger.Info("My Anime Sync Completed"); }