/// <summary>
        /// Stops scrobbing an episode on trakt.tv
        /// </summary>
        /// <param name="watched">Determines if we should force watched on stop</param>
        internal static bool StopScrobbleEpisode(VideoInfo videoInfo, bool watched = false)
        {
            // get scrobble data to send to api
            var scrobbleData = CreateEpisodeScrobbleData(videoInfo);

            if (scrobbleData == null)
            {
                return(false);
            }

            // force watched
            if (watched && scrobbleData.Progress < 80)
            {
                scrobbleData.Progress = 100;
            }

            var response = TraktAPI.TraktAPI.StopEpisodeScrobble(scrobbleData);

            if (response != null && response.Show != null)
            {
                // add to cache
                if (response.Action == "scrobble")
                {
                    TraktCache.AddEpisodeToWatchHistory(response.Show, response.Episode);
                }
                else if (response.Action == "pause")
                {
                    TraktCache.AddEpisodeToPausedData(response.Show, response.Episode, response.Progress);
                }
            }

            return(TraktLogger.LogTraktResponse(response));
        }
        private void DismissRecommendation(TraktMovie movie)
        {
            Thread syncThread = new Thread(delegate(object obj)
            {
                TraktMovie dismissMovie = obj as TraktMovie;

                TraktMovieSlug syncMovie = new TraktMovieSlug
                {
                    UserName = TraktSettings.Username,
                    Password = TraktSettings.Password,
                    IMDbId   = dismissMovie.IMDBID,
                    TMDbId   = dismissMovie.TMDBID,
                    Title    = dismissMovie.Title,
                    Year     = dismissMovie.Year
                };

                TraktResponse response = TraktAPI.TraktAPI.DismissMovieRecommendation(syncMovie);
                TraktLogger.LogTraktResponse <TraktResponse>(response);
                if (response != null && response.Status == "success")
                {
                    TraktHandlers.MovingPictures.UpdateCategoriesAndFilters();
                }
            })
            {
                IsBackground = true,
                Name         = "DismissRecommendation"
            };

            syncThread.Start(movie);
        }
        private void DeleteList(TraktUserList list)
        {
            if (!GUIUtils.ShowYesNoDialog(Translation.Lists, Translation.ConfirmDeleteList, false))
            {
                return;
            }

            GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
            {
                TraktLogger.Info("Deleting list '{0}'", list.Name);
                TraktList deleteList = new TraktList {
                    UserName = TraktSettings.Username, Password = TraktSettings.Password, Slug = list.Slug
                };
                return(TraktAPI.TraktAPI.ListDelete(deleteList));
            },
                                                                      delegate(bool success, object result)
            {
                if (success)
                {
                    TraktResponse response = result as TraktResponse;
                    TraktLogger.LogTraktResponse <TraktResponse>(response);
                    if (response.Status == "success")
                    {
                        // reload with new list
                        TraktLists.ClearCache(TraktSettings.Username);
                        LoadLists();
                    }
                    else
                    {
                        GUIUtils.ShowNotifyDialog(Translation.Lists, response.Error);
                    }
                }
            }, Translation.DeletingList, true);
        }
 private void EditList(TraktList list)
 {
     GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
     {
         return(TraktAPI.TraktAPI.ListUpdate(list));
     },
                                                               delegate(bool success, object result)
     {
         if (success)
         {
             TraktResponse response = result as TraktResponse;
             TraktLogger.LogTraktResponse <TraktResponse>(response);
             if (response.Status == "success")
             {
                 // reload with new list
                 TraktLists.ClearCache(TraktSettings.Username);
                 LoadLists();
             }
             else
             {
                 GUIUtils.ShowNotifyDialog(Translation.Lists, response.Error);
             }
         }
     }, Translation.EditingList, true);
 }
Exemple #5
0
        private void DismissRecommendation(TraktShow show)
        {
            Thread syncThread = new Thread(delegate(object obj)
            {
                TraktShow dismissShow = obj as TraktShow;

                TraktShowSlug syncShow = new TraktShowSlug
                {
                    UserName = TraktSettings.Username,
                    Password = TraktSettings.Password,
                    IMDbId   = dismissShow.Imdb,
                    TVDbId   = dismissShow.Tvdb,
                    Title    = dismissShow.Title,
                    Year     = dismissShow.Year.ToString()
                };

                TraktResponse response = TraktAPI.TraktAPI.DismissShowRecommendation(syncShow);
                TraktLogger.LogTraktResponse <TraktResponse>(response);
            })
            {
                IsBackground = true,
                Name         = "DismissRecommendation"
            };

            syncThread.Start(show);
        }
Exemple #6
0
        /// <summary>
        /// Scrobbles a episode from a videoInfo object
        /// </summary>
        /// <returns>returns true if successfully scrobbled</returns>
        public static bool ScrobbleEpisode(VideoInfo videoInfo, TraktScrobbleStates state)
        {
            // get scrobble data to send to api
            TraktEpisodeScrobble scrobbleData = CreateEpisodeScrobbleData(videoInfo);

            if (scrobbleData == null)
            {
                return(false);
            }

            // get duration/position in minutes
            double duration = videoInfo.Runtime > 0.0 ? videoInfo.Runtime : g_Player.Duration / 60;
            double position = g_Player.CurrentPosition / 60;
            double progress = 0.0;

            if (duration > 0.0)
            {
                progress = (position / duration) * 100.0;
            }

            // sometimes with recordings/timeshifting we can get invalid player properties
            // adjust if duration is less than a typical episode
            scrobbleData.Duration = (duration < 10.0) ? "30" : Convert.ToInt32(duration).ToString();
            scrobbleData.Progress = (state == TraktScrobbleStates.scrobble) ? "100" : Convert.ToInt32(progress).ToString();

            TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, state);

            return(TraktLogger.LogTraktResponse(response));
        }
        private void StartScrobble()
        {
            ISettingsManager settingsManager = ServiceRegistration.Get <ISettingsManager>();
            TraktSettings    settings        = settingsManager.Load <TraktSettings>();

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

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

            if (_dataMovie.Movie != null && IsMovie(currentPlayingMediaItem))
            {
                _dataMovie.Progress = 0;
                var response = TraktAPI.StartMovieScrobble(_dataMovie);
                TraktLogger.LogTraktResponse(response);
                return;
            }
            if (_dataEpisode != null && IsSeries(currentPlayingMediaItem))
            {
                _dataEpisode.Progress = 0;
                var response = TraktAPI.StartEpisodeScrobble(_dataEpisode);
                TraktLogger.LogTraktResponse(response);
                return;
            }
            TraktLogger.Info("Can't start scrobble, scrobbledata not available");
        }
        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);
                    TraktLogger.LogTraktResponse(response);
                }
            })
            {
                IsBackground = true,
                Name         = "ToggleWatched"
            };

            toggleWatched.Start();
        }
        private void OnRateSeries(AnimeSeries series, string rateValue)
        {
            if (TraktSettings.AccountStatus != ConnectionState.Connected)
            {
                return;
            }

            TraktLogger.Info("Received rating event for series from my anime");

            Thread rateThread = new Thread(delegate()
            {
                TraktRateSeries seriesRateData = CreateSeriesRateData(series, rateValue);
                if (seriesRateData == null)
                {
                    return;
                }
                TraktRateResponse response = TraktAPI.TraktAPI.RateSeries(seriesRateData);

                // check for any error and notify
                TraktLogger.LogTraktResponse(response);
            })
            {
                IsBackground = true,
                Name         = "Rate"
            };

            rateThread.Start();
        }
        internal static void StartScrobble(object scrobbledata)
        {
            var scrobbleThread = new Thread((objVideoInfo) =>
            {
                if (scrobbledata is TraktScrobbleEpisode)
                {
                    var info = objVideoInfo as TraktScrobbleEpisode;
#if DEBUG
                    TraktLogger.Info("Starting new thread to manually scrobble show: {0}, S{1}xE{2}", info.Show.Title, info.Episode.Season, info.Episode.Number);
                    TraktLogger.Info(info.ToString());
#endif
                    var response = TraktAPI.TraktAPI.StartEpisodeScrobble(info);
                    //TraktLogger.LogTraktResponse(response);
                }
                else if (scrobbledata is TraktScrobbleMovie)
                {
                    var info = objVideoInfo as TraktScrobbleMovie;
#if DEBUG
                    TraktLogger.Info("Starting new thread to manually scrobble movie: {0},{1}", info.Movie.Title, info.Movie.Year);
#endif
                    var response = TraktAPI.TraktAPI.StartMovieScrobble(info);
                    TraktLogger.LogTraktResponse(response);
                }
                else
                {
                    TraktLogger.Info("Bad data passed {0}", objVideoInfo.ToString());
                }
            })
            {
                IsBackground = true,
                Name         = "Scrobble"
            };

            scrobbleThread.Start(scrobbledata);
        }
Exemple #11
0
        public void StopScrobble()
        {
            if (CurrentMovie == null)
            {
                return;
            }

            var scrobbleData = CreateScrobbleData(CurrentMovie);

            // check if movie is considered 'watched'
            if (scrobbleData.Progress >= WatchedPercent)
            {
                ShowRateDialog(CurrentMovie);
            }

            var scrobbleMovie = new Thread((objScrobble) =>
            {
                var tScrobbleData = objScrobble as TraktScrobbleMovie;
                if (tScrobbleData == null)
                {
                    return;
                }

                TraktScrobbleResponse response = null;

                if (tScrobbleData.Progress >= WatchedPercent)
                {
                    TraktLogger.Info("Sending 'stop' scrobble of movie to trakt.tv. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", tScrobbleData.Movie.Title, tScrobbleData.Movie.Year, tScrobbleData.Movie.Ids.Imdb ?? "<empty>");
                    response = TraktAPI.TraktAPI.StopMovieScrobble(tScrobbleData);

                    if (response != null && response.Movie != null && response.Action == "scrobble")
                    {
                        // add to cache
                        TraktCache.AddMovieToWatchHistory(response.Movie);
                    }
                }
                else
                {
                    TraktLogger.Info("Sending 'pause' scrobble of movie to trakt.tv. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", tScrobbleData.Movie.Title, tScrobbleData.Movie.Year, tScrobbleData.Movie.Ids.Imdb ?? "<empty>");
                    response = TraktAPI.TraktAPI.PauseMovieScrobble(tScrobbleData);

                    if (response != null && response.Movie != null && response.Action == "pause")
                    {
                        // add to cache
                        TraktCache.AddMovieToPausedData(response.Movie, response.Progress);
                    }
                }

                TraktLogger.LogTraktResponse(response);
            })
            {
                IsBackground = true,
                Name         = "Scrobble"
            };

            scrobbleMovie.Start(scrobbleData);

            CurrentMovie = null;
        }
        public void StopScrobble()
        {
            if (TraktTimer != null)
            {
                TraktTimer.Dispose();
            }

            if (CurrentProgram == null)
            {
                return;
            }

            if (IsProgramWatched(CurrentProgram) && CurrentProgram.IsScrobbling)
            {
                ScrobbleProgram(CurrentProgram);
            }
            else
            {
                #region cancel watching
                TraktLogger.Info("Stopped playback of tv-live '{0}'", CurrentProgram.ToString());

                Thread cancelWatching = new Thread(delegate(object obj)
                {
                    VideoInfo videoInfo = obj as VideoInfo;
                    if (videoInfo == null)
                    {
                        return;
                    }

                    if (videoInfo.Type == VideoType.Series)
                    {
                        TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble {
                            UserName = TraktSettings.Username, Password = TraktSettings.Password
                        };
                        TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.cancelwatching);
                        TraktLogger.LogTraktResponse(response);
                    }
                    else
                    {
                        TraktMovieScrobble scrobbleData = new TraktMovieScrobble {
                            UserName = TraktSettings.Username, Password = TraktSettings.Password
                        };
                        TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, TraktScrobbleStates.cancelwatching);
                        TraktLogger.LogTraktResponse(response);
                    }
                })
                {
                    IsBackground = true,
                    Name         = "CancelWatching"
                };

                cancelWatching.Start(CurrentProgram);
                #endregion
            }

            CurrentProgram = null;
        }
        private void ApproveFollowerRequest(int id, bool followBack = false)
        {
            var approveFollowerThread = new Thread(objId =>
            {
                var response = TraktAPI.TraktAPI.NetworkApproveFollower((int)objId);
                TraktLogger.LogTraktResponse <TraktNetworkUser>(response);
            })
            {
                IsBackground = true,
                Name         = "FollowerReq"
            };

            approveFollowerThread.Start(id);
        }
Exemple #14
0
        private void ApproveFollowerRequest(TraktUser user, bool followBack = false)
        {
            Thread approveFollowerThread = new Thread(delegate(object obj)
            {
                TraktResponse response = TraktAPI.TraktAPI.NetworkApprove(CreateNetworkData(user, followBack));
                TraktLogger.LogTraktResponse <TraktResponse>(response);
            })
            {
                IsBackground = true,
                Name         = "FollowerRequest"
            };

            approveFollowerThread.Start(user);
        }
Exemple #15
0
        private void UnfollowUser(TraktUser user)
        {
            Thread unfollowUserThread = new Thread(delegate(object obj)
            {
                TraktResponse response = TraktAPI.TraktAPI.NetworkUnFollow(CreateNetworkData(user));
                TraktLogger.LogTraktResponse <TraktResponse>(response);
            })
            {
                IsBackground = true,
                Name         = "UnfollowUser"
            };

            unfollowUserThread.Start(user);
        }
Exemple #16
0
        private void DenyFollowerRequest(TraktUser user)
        {
            Thread denyFollowerRequest = new Thread(delegate(object obj)
            {
                TraktResponse response = TraktAPI.TraktAPI.NetworkDeny(CreateNetworkData(user));
                TraktLogger.LogTraktResponse <TraktResponse>(response);
            })
            {
                IsBackground = true,
                Name         = "DenyFollowerRequest"
            };

            denyFollowerRequest.Start(user);
        }
        /// <summary>
        /// Starts scrobbling an episode on trakt.tv
        /// </summary>
        /// <returns>returns true if successfully scrobbled</returns>
        internal static bool StartScrobbleEpisode(VideoInfo videoInfo)
        {
            // get scrobble data to send to api
            var scrobbleData = CreateEpisodeScrobbleData(videoInfo);

            if (scrobbleData == null)
            {
                return(false);
            }

            var response = TraktAPI.TraktAPI.StartEpisodeScrobble(scrobbleData);

            return(TraktLogger.LogTraktResponse(response));
        }
        internal static TraktScrobbleResponse StartScrobbleEpisode(EVideoInfo videoInfo)
        {
            // get scrobble data to send to api
            var scrobbleData = CreateEpisodeScrobbleData(videoInfo);

            if (scrobbleData == null)
            {
                return(null);
            }
            TraktLogger.Info("Trying to scrobble '{0}' season {1} episode {2}", scrobbleData.Show.Title, scrobbleData.Episode.Season, scrobbleData.Episode.Number);
            var response = TraktAPI.TraktAPI.StartEpisodeScrobble(scrobbleData);

            TraktLogger.LogTraktResponse(response);
            return(response);
        }
        internal static TraktScrobbleResponse StartScrobbleMovie(EVideoInfo videoInfo)
        {
            // get scrobble data to send to api
            var scrobbleData = CreateMovieScrobbleData(videoInfo);

            if (scrobbleData == null)
            {
                return(null);
            }

            var response = TraktAPI.TraktAPI.StartMovieScrobble(scrobbleData);

            TraktLogger.LogTraktResponse(response);
            return(response);
        }
 private void StopScrobble()
 {
     if (_dataMovie.Movie != null && IsMovie(currentPlayingMediaItem))
     {
         _dataMovie.Progress = _progress;
         var response = TraktAPI.StopMovieScrobble(_dataMovie);
         TraktLogger.LogTraktResponse(response);
         return;
     }
     if (_dataEpisode != null && IsSeries(currentPlayingMediaItem))
     {
         _dataEpisode.Progress = _progress;
         var response = TraktAPI.StopEpisodeScrobble(_dataEpisode);
         TraktLogger.LogTraktResponse(response);
         return;
     }
     TraktLogger.Info("Can't post stop scrobble, scrobbledata lost");
 }
Exemple #21
0
        public bool Scrobble(string filename)
        {
            StopScrobble();

            // stop check if not valid player type for plugin handler
            if (g_Player.IsTV || g_Player.IsTVRecording || filename == "http://localhost/OnlineVideo.mp4")
            {
                return(false);
            }

            // lookup movie by filename
            var movie  = new IMDBMovie();
            int result = VideoDatabase.GetMovieInfo(filename, ref movie);

            if (result == -1)
            {
                return(false);
            }

            CurrentMovie = movie;
            LastMovie    = movie;

            var scrobbleData  = CreateScrobbleData(CurrentMovie);
            var scrobbleMovie = new Thread((objScrobble) =>
            {
                var tScrobbleData = objScrobble as TraktScrobbleMovie;
                if (tScrobbleData == null)
                {
                    return;
                }

                TraktLogger.Info("Sending start scrobble of movie to trakt.tv. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", tScrobbleData.Movie.Title, tScrobbleData.Movie.Year, tScrobbleData.Movie.Ids.Imdb ?? "<empty>");
                var response = TraktAPI.TraktAPI.StartMovieScrobble(tScrobbleData);
                TraktLogger.LogTraktResponse(response);
            })
            {
                IsBackground = true,
                Name         = "Scrobble"
            };

            scrobbleMovie.Start(scrobbleData);

            return(true);
        }
        /// <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
                    TraktLogger.LogTraktResponse(response);

                    // wait a short period before uploading another series
                    Thread.Sleep(2000);
                }
            }
        }
Exemple #23
0
        internal static void FollowUser(TraktUser user)
        {
            Thread followUserThread = new Thread(delegate(object obj)
            {
                var currUser = obj as TraktUser;

                var response = TraktAPI.TraktAPI.NetworkFollow(CreateNetworkData(currUser));
                TraktLogger.LogTraktResponse <TraktNetworkFollowResponse>(response);

                // notify user if follow is pending approval by user
                if (response.Pending)
                {
                    GUIUtils.ShowNotifyDialog(Translation.Follow, string.Format(Translation.FollowPendingApproval, currUser.Username));
                }
            })
            {
                IsBackground = true,
                Name         = "FollowUser"
            };

            followUserThread.Start(user);
        }
        internal static void FollowUser(TraktUser user)
        {
            var followUserThread = new Thread(obj =>
            {
                var currUser = obj as TraktUser;

                var response = TraktAPI.TraktAPI.NetworkFollowUser(currUser.Username);
                TraktLogger.LogTraktResponse <TraktNetworkApproval>(response);

                // notify user if follow is pending approval by user
                // approved date will be null if user is marked as private
                if (response != null && response.ApprovedAt == null)
                {
                    GUIUtils.ShowNotifyDialog(Translation.Follow, string.Format(Translation.FollowPendingApproval, currUser.Username));
                }
            })
            {
                IsBackground = true,
                Name         = "FollowUser"
            };

            followUserThread.Start(user);
        }
Exemple #25
0
        public void StopScrobble()
        {
            if (TraktTimer != null)
            {
                TraktTimer.Dispose();
            }

            if (CurrentMovie == null)
            {
                return;
            }

            // if movie is atleast XX% complete, consider watched
            if ((g_Player.CurrentPosition / (g_Player.Duration == 0.0 ? CurrentMovie.RunTime * 60.0 : g_Player.Duration)) >= WatchedPercent / 100.0)
            {
                ShowRateDialog(CurrentMovie);

                #region scrobble
                Thread scrobbleMovie = new Thread(delegate(object o)
                {
                    IMDBMovie movie = o as IMDBMovie;
                    if (movie == null)
                    {
                        return;
                    }

                    TraktLogger.Info("MyVideos movie is considered watched '{0}'", movie.Title);

                    // get scrobble data to send to api
                    TraktMovieScrobble scrobbleData = CreateScrobbleData(movie);
                    if (scrobbleData == null)
                    {
                        return;
                    }

                    // set duration/progress in scrobble data
                    Double duration       = g_Player.Duration == 0.0 ? movie.RunTime * 60.0 : g_Player.Duration;
                    scrobbleData.Duration = Convert.ToInt32(duration / 60.0).ToString();
                    scrobbleData.Progress = "100";

                    TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, TraktScrobbleStates.scrobble);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Scrobble"
                };

                scrobbleMovie.Start(CurrentMovie);
                #endregion
            }
            else
            {
                #region cancel watching
                TraktLogger.Info("Stopped MyVideos movie playback '{0}'", CurrentMovie.Title);

                // stop scrobbling
                Thread cancelWatching = new Thread(delegate()
                {
                    TraktMovieScrobble scrobbleData = new TraktMovieScrobble {
                        UserName = TraktSettings.Username, Password = TraktSettings.Password
                    };
                    TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, TraktScrobbleStates.cancelwatching);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "CancelWatching"
                };

                cancelWatching.Start();
                #endregion
            }

            CurrentMovie = null;
        }
        private void CopyList(TraktUserList sourceList, TraktList newList)
        {
            CopyList copyList = new CopyList {
                Username = CurrentUser, Source = sourceList, Destination = newList
            };

            Thread copyThread = new Thread(delegate(object obj)
            {
                CopyList copyParams = obj as CopyList;

                // first create new list
                TraktLogger.Info("Creating new '{0}' list '{1}'", copyParams.Destination.Privacy, copyParams.Destination.Name);
                TraktAddListResponse response = TraktAPI.TraktAPI.ListAdd(copyParams.Destination);
                TraktLogger.LogTraktResponse <TraktResponse>(response);
                if (response.Status == "success")
                {
                    // update with offical slug
                    copyParams.Destination.Slug = response.Slug;

                    // get items from other list
                    TraktUserList userList = TraktAPI.TraktAPI.GetUserList(copyParams.Username, copyParams.Source.Slug);
                    // copy items to new list
                    List <TraktListItem> items = new List <TraktListItem>();
                    foreach (var item in userList.Items)
                    {
                        TraktListItem listItem = new TraktListItem();
                        listItem.Type          = item.Type;

                        switch (item.Type)
                        {
                        case "movie":
                            listItem.Title  = item.Movie.Title;
                            listItem.Year   = Convert.ToInt32(item.Movie.Year);
                            listItem.ImdbId = item.Movie.IMDBID;
                            break;

                        case "show":
                            listItem.Title  = item.Show.Title;
                            listItem.Year   = item.Show.Year;
                            listItem.TvdbId = item.Show.Tvdb;
                            break;

                        case "season":
                            listItem.Title  = item.Show.Title;
                            listItem.Year   = item.Show.Year;
                            listItem.TvdbId = item.Show.Tvdb;
                            listItem.Season = Convert.ToInt32(item.SeasonNumber);
                            break;

                        case "episode":
                            listItem.Title   = item.Show.Title;
                            listItem.Year    = item.Show.Year;
                            listItem.TvdbId  = item.Show.Tvdb;
                            listItem.Season  = Convert.ToInt32(item.SeasonNumber);
                            listItem.Episode = Convert.ToInt32(item.EpisodeNumber);
                            break;
                        }
                        items.Add(listItem);
                    }
                    copyParams.Destination.Items = items;

                    // add items to the list
                    TraktLogger.LogTraktResponse <TraktSyncResponse>(TraktAPI.TraktAPI.ListAddItems(copyParams.Destination));
                    if (response.Status == "success")
                    {
                        TraktLists.ClearCache(TraktSettings.Username);
                    }
                }
            })
            {
                Name         = "CopyList",
                IsBackground = true
            };

            copyThread.Start(copyList);
        }
        /// <summary>
        /// Shows a Trakt Rate Dialog (Love/Hate) or 10-Heart based on settings
        /// </summary>
        /// <param name="rateObject">Type of object being rated</param>
        public static string ShowRateDialog <T>(T rateObject)
        {
            if (GUIGraphicsContext.form.InvokeRequired)
            {
                ShowRateDialogDelegate <T> d = ShowRateDialog <T>;
                return((string)GUIGraphicsContext.form.Invoke(d, rateObject));
            }

            TraktRateValue currentRating = TraktRateValue.unrate;

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

            ratingDlg.Reset();

            ratingDlg.SetHeading(Translation.RateHeading);

            // show simple love/hate icons or 10-heart icons
            ratingDlg.ShowAdvancedRatings = TraktSettings.ShowAdvancedRatingsDialog;

            // if item is not rated, it will default to love
            if (rateObject is TraktRateEpisode)
            {
                TraktRateEpisode item = rateObject as TraktRateEpisode;
                ratingDlg.SetLine(1, string.Format("{0} - {1}x{2}", item.Title, item.Season, item.Episode));
                if (ratingDlg.ShowAdvancedRatings)
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
                else
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.ten : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
            }
            else if (rateObject is TraktRateSeries)
            {
                TraktRateSeries item = rateObject as TraktRateSeries;
                ratingDlg.SetLine(1, item.Title);
                if (ratingDlg.ShowAdvancedRatings)
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
                else
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.ten : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
            }
            else
            {
                TraktRateMovie item = rateObject as TraktRateMovie;
                ratingDlg.SetLine(1, item.Title);
                if (ratingDlg.ShowAdvancedRatings)
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.seven : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
                else
                {
                    ratingDlg.Rated = item.Rating == "0" || !item.Rating.IsNumber() ? TraktRateValue.ten : (TraktRateValue)Convert.ToInt32(item.Rating);
                }
            }

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

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

            if (rateObject is TraktRateEpisode)
            {
                TraktRateEpisode item = rateObject as TraktRateEpisode;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating != 0 ? ((int)currentRating).ToString() : "unrate";
                Thread rateThread = new Thread(delegate(object obj)
                {
                    TraktRateResponse response = TraktAPI.TraktAPI.RateEpisode(item);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else if (rateObject is TraktRateSeries)
            {
                TraktRateSeries item = rateObject as TraktRateSeries;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating != 0 ? ((int)currentRating).ToString() : "unrate";
                Thread rateThread = new Thread(delegate(object obj)
                {
                    TraktRateResponse response = TraktAPI.TraktAPI.RateSeries(item);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }
            else
            {
                TraktRateMovie item = rateObject as TraktRateMovie;
                currentRating = ratingDlg.Rated;
                item.Rating   = (int)currentRating != 0 ? ((int)currentRating).ToString() : "unrate";
                Thread rateThread = new Thread(delegate(object obj)
                {
                    TraktRateResponse response = TraktAPI.TraktAPI.RateMovie(item);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name         = "Rate"
                };
                rateThread.Start(item);
            }

            // return new rating (0 - 10)
            // old love / hate enum values are deprecated
            // if using basic ratings 1 = hate and 10 = love
            // 0 is unrate
            return(((int)currentRating).ToString());
        }
Exemple #28
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);
        }
Exemple #29
0
        public void StopScrobble()
        {
            if (TraktTimer != null)
            {
                TraktTimer.Dispose();
            }

            if (CurrentRecording == null)
            {
                return;
            }

            // get current progress of player
            double progress = 0.0;

            if (g_Player.Duration > 0.0)
            {
                progress = (g_Player.CurrentPosition / g_Player.Duration) * 100.0;
            }

            TraktLogger.Debug("Current Position: {0}, Duration: {1}", g_Player.CurrentPosition.ToString(), g_Player.Duration.ToString());
            TraktLogger.Debug(string.Format("Percentage of '{0}' watched is {1}%", CurrentRecording.Title, progress > 100.0 ? "100" : progress.ToString("N2")));

            // if recording is at least 80% complete, consider watched
            // consider watched with invalid progress as well, we should never be exactly 0.0
            if ((progress == 0.0 || progress >= 80.0) && CurrentRecording.IsScrobbling)
            {
                // Show rate dialog
                ShowRateDialog(CurrentRecording);

                #region scrobble
                Thread scrobbleRecording = new Thread(delegate(object obj)
                {
                    VideoInfo videoInfo = obj as VideoInfo;
                    if (videoInfo == null)
                    {
                        return;
                    }

                    TraktLogger.Info("Playback of '{0}' in Argus tv-recording is considered watched.", videoInfo.ToString());

                    if (videoInfo.Type == VideoType.Series)
                    {
                        BasicHandler.ScrobbleEpisode(videoInfo, TraktScrobbleStates.scrobble);
                    }
                    else
                    {
                        BasicHandler.ScrobbleMovie(videoInfo, TraktScrobbleStates.scrobble);
                    }
                })
                {
                    IsBackground = true,
                    Name         = "Scrobble"
                };

                scrobbleRecording.Start(CurrentRecording);
                #endregion
            }
            else
            {
                #region cancel watching
                TraktLogger.Info("Stopped playback of Argus tv-recording '{0}'", CurrentRecording.ToString());

                Thread cancelWatching = new Thread(delegate(object obj)
                {
                    VideoInfo videoInfo = obj as VideoInfo;
                    if (videoInfo == null)
                    {
                        return;
                    }

                    if (videoInfo.Type == VideoType.Series)
                    {
                        TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble {
                            UserName = TraktSettings.Username, Password = TraktSettings.Password
                        };
                        TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.cancelwatching);
                        TraktLogger.LogTraktResponse(response);
                    }
                    else
                    {
                        TraktMovieScrobble scrobbleData = new TraktMovieScrobble {
                            UserName = TraktSettings.Username, Password = TraktSettings.Password
                        };
                        TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, TraktScrobbleStates.cancelwatching);
                        TraktLogger.LogTraktResponse(response);
                    }
                })
                {
                    IsBackground = true,
                    Name         = "CancelWatching"
                };

                cancelWatching.Start(CurrentRecording);
                #endregion
            }

            CurrentRecording = null;
        }
Exemple #30
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");
        }