/// <summary>
        /// Download an image if it does not exist locally
        /// </summary>
        /// <param name="url">Online URL of image to download</param>
        /// <param name="localFile">Local filename to save image</param>
        /// <returns>true if image downloads successfully or loads from disk successfully</returns>
        public static bool DownloadImage(string url, string localFile)
        {
            WebClient webClient = new WebClient();

            webClient.Headers.Add("user-agent", TraktSettings.UserAgent);

            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(localFile));
                if (!File.Exists(localFile))
                {
                    TraktLogger.Debug("Downloading new image. Url = '{0}', Filename = '{1}'", url, localFile);
                    webClient.DownloadFile(url, localFile);
                }
                return(true);
            }
            catch (Exception)
            {
                TraktLogger.Warning("Image download failed. Url = '{0}', Filename = '{1}'", url, localFile);
                try { if (File.Exists(localFile))
                      {
                          File.Delete(localFile);
                      }
                } catch { }
                return(false);
            }
        }
Exemple #2
0
        private void InitProperties()
        {
            // set search term from loading parameter
            if (!string.IsNullOrEmpty(_loadParameter))
            {
                TraktLogger.Debug("User Search Loading Parameter: {0}", _loadParameter);
                SearchTerm = _loadParameter;
            }

            // remember previous search term
            SearchTermChanged = false;
            if (PreviousSearchTerm != SearchTerm)
            {
                SearchTermChanged = true;
            }
            PreviousSearchTerm = SearchTerm;

            // set context property
            GUIUtils.SetProperty("#Trakt.Search.SearchTerm", SearchTerm);

            // load last layout
            CurrentLayout = (GUIFacadeControl.Layout)TraktSettings.SearchUsersDefaultLayout;

            // update button label
            if (layoutButton != null)
            {
                GUIControl.SetControlLabel(GetID, layoutButton.GetID, GUICommon.GetLayoutTranslation(CurrentLayout));
            }
        }
Exemple #3
0
        private void InitProperties()
        {
            // Fanart
            backdrop.GUIImageOne  = FanartBackground;
            backdrop.GUIImageTwo  = FanartBackground2;
            backdrop.LoadingImage = loadingImage;

            // set search term from loading parameter
            if (!string.IsNullOrEmpty(_loadParameter))
            {
                TraktLogger.Debug("Episode Search Loading Parameter: {0}", _loadParameter);
                SearchTerm = _loadParameter;
            }

            // remember previous search term
            SearchTermChanged = false;
            if (PreviousSearchTerm != SearchTerm)
            {
                SearchTermChanged = true;
            }
            PreviousSearchTerm = SearchTerm;

            // set context property
            GUIUtils.SetProperty("#Trakt.Search.SearchTerm", SearchTerm);

            // load last layout
            CurrentLayout = (Layout)TraktSettings.SearchShowsDefaultLayout;

            // update button label
            GUIControl.SetControlLabel(GetID, layoutButton.GetID, GUICommon.GetLayoutTranslation(CurrentLayout));
        }
        private void OnImportComplete()
        {
            if (TraktSettings.AccountStatus != ConnectionState.Connected)
            {
                return;
            }

            TraktLogger.Debug("My Films import complete, initiating online sync");

            // sync again
            Thread syncThread = new Thread(delegate()
            {
                while (SyncInProgress)
                {
                    // only do one sync at a time
                    TraktLogger.Debug("My Films sync still in progress, waiting to complete. Trying again in 60secs.");
                    Thread.Sleep(60000);
                }
                SyncLibrary();
            })
            {
                IsBackground = true,
                Name         = "LibrarySync"
            };

            syncThread.Start();
        }
Exemple #5
0
        static string LoadFileCache(string filename, string defaultValue)
        {
            string returnValue = defaultValue;

            try
            {
                if (File.Exists(filename))
                {
                    TraktLogger.Debug("Loading file from disk. Filename = '{0}'", filename);
                    returnValue = File.ReadAllText(filename, Encoding.UTF8);
                    if (string.IsNullOrEmpty(returnValue))
                    {
                        TraktLogger.Warning("Unexpected contents in file '{0}', restoring default value", filename);
                        returnValue = defaultValue;
                    }
                }
            }
            catch (Exception e)
            {
                TraktLogger.Error(string.Format("Error loading file from disk. Filename = '{0}', Error = '{1}'", filename, e.Message));
                return(defaultValue);
            }

            return(returnValue);
        }
        public MyFilmsHandler(int priority)
        {
            // check if plugin exists otherwise plugin could accidently get added to list
            string pluginFilename = Path.Combine(Config.GetSubFolder(Config.Dir.Plugins, "Windows"), "MyFilms.dll");

            if (!File.Exists(pluginFilename))
            {
                throw new FileNotFoundException("Plugin not found!");
            }
            else
            {
                FileVersionInfo fvi     = FileVersionInfo.GetVersionInfo(pluginFilename);
                string          version = fvi.ProductVersion;
                if (new Version(version) < new Version(6, 0, 0, 2616))
                {
                    throw new FileLoadException("Plugin does not meet minimum requirements!");
                }
            }

            // Subscribe to Events
            TraktLogger.Debug("Adding Hooks to My Films");
            MyFilmsDetail.RateItem     += new MyFilmsDetail.RatingEventDelegate(OnRateItem);
            MyFilmsDetail.WatchedItem  += new MyFilmsDetail.WatchedEventDelegate(OnToggleWatched);
            MyFilmsDetail.MovieStarted += new MyFilmsDetail.MovieStartedEventDelegate(OnStartedMovie);
            MyFilmsDetail.MovieStopped += new MyFilmsDetail.MovieStoppedEventDelegate(OnStoppedMovie);
            MyFilmsDetail.MovieWatched += new MyFilmsDetail.MovieWatchedEventDelegate(OnWatchedMovie);
            MyFilms.ImportComplete     += new MyFilms.ImportCompleteEventDelegate(OnImportComplete);

            Priority = priority;
        }
Exemple #7
0
        static void GetTrailerUrl(string htmlPage)
        {
            // get playback url from stream
            TraktLogger.Debug("Getting playback url from page '{0}'", htmlPage);

            GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
            {
                var ovHosterProxy = OnlineVideosAppDomain.Domain.CreateInstanceAndUnwrap(typeof(OnlineVideosHosterProxy).Assembly.FullName, typeof(OnlineVideosHosterProxy).FullName) as OnlineVideosHosterProxy;
                var url           = ovHosterProxy.GetVideoUrls(htmlPage);
                return(url);
            },
                                                                      delegate(bool success, object result)
            {
                string url = result as string;

                if (success)
                {
                    if (!string.IsNullOrEmpty(url))
                    {
                        BufferTrailer(url);
                    }
                    else
                    {
                        TraktLogger.Info("Unable to get url for trailer playback.", url);
                        GUIUtils.ShowNotifyDialog(GUI.Translation.Error, GUI.Translation.UnableToPlayTrailer);
                    }
                }
            },
                                                                      GUI.Translation.GettingTrailerUrls, false);
        }
Exemple #8
0
 public void DisposeEvents()
 {
     TraktLogger.Debug("Removing Hooks from My Anime");
     animeWindow.OnToggleWatched -= new MainWindow.OnToggleWatchedHandler(OnToggleWatched);
     animeWindow.OnRateSeries    -= new MainWindow.OnRateSeriesHandler(OnRateSeries);
     animeWindow = null;
 }
Exemple #9
0
        public OnlineVideos(int priority)
        {
            // check if plugin exists otherwise plugin could accidently get added to list
            string pluginFilename = Path.Combine(Config.GetSubFolder(Config.Dir.Plugins, "Windows"), "OnlineVideos.MediaPortal1.dll");

            if (!File.Exists(pluginFilename))
            {
                throw new FileNotFoundException("Plugin not found!");
            }
            else
            {
                FileVersionInfo fvi     = FileVersionInfo.GetVersionInfo(pluginFilename);
                string          version = fvi.ProductVersion;
                if (new Version(version) < new Version(0, 31, 0, 0))
                {
                    throw new FileLoadException("Plugin does not meet minimum requirements!");
                }
            }

            TraktLogger.Debug("Adding Hooks to OnlineVideos");

            // Subscribe to Player Events
            ovObject = (GUIOnlineVideos)GUIWindowManager.GetWindow((int)ExternalPluginWindows.OnlineVideos);
            ovObject.TrackVideoPlayback += new GUIOnlineVideos.TrackVideoPlaybackHandler(TrackVideoPlayback);

            Priority = priority;
        }
Exemple #10
0
        public OnlineVideos(int priority)
        {
            TraktLogger.Info("Initialising OnlineVideos plugin handler");

            // check if plugin exists otherwise plugin could accidently get added to list
            string pluginFilename = Path.Combine(Config.GetSubFolder(Config.Dir.Plugins, "Windows"), "OnlineVideos.MediaPortal1.dll");

            if (!File.Exists(pluginFilename))
            {
                throw new FileNotFoundException("Plugin not found!");
            }
            else
            {
                var fvi = FileVersionInfo.GetVersionInfo(pluginFilename);
                if (new Version(fvi.FileVersion) < new Version(1, 9, 0, 3341))
                {
                    throw new FileLoadException("Plugin does not meet the minimum requirements, check you have the latest version installed!");
                }
            }

            TraktLogger.Debug("Adding Hooks to OnlineVideos");

            // Subscribe to Player Events
            ovObject = (GUIOnlineVideos)GUIWindowManager.GetWindow((int)ExternalPluginWindows.OnlineVideos);
            ovObject.TrackVideoPlayback += new GUIOnlineVideos.TrackVideoPlaybackHandler(TrackVideoPlayback);

            Priority = priority;
        }
Exemple #11
0
        /// <summary>
        /// Shows the Rate Dialog after playback has ended
        /// </summary>
        /// <param name="episode">The item being rated</param>
        private void ShowRateDialog(ITrackingInfo videoInfo)
        {
            if (!TraktSettings.ShowRateDialogOnWatched)
            {
                return;                                             // not enabled
            }
            TraktLogger.Debug("Showing rate dialog for '{0}'", videoInfo.Title);

            new Thread((o) =>
            {
                ITrackingInfo itemToRate = o as ITrackingInfo;
                if (itemToRate == null)
                {
                    return;
                }

                int rating = 0;

                if (itemToRate.VideoKind == VideoKind.TvSeries)
                {
                    TraktRateEpisode rateObject = new TraktRateEpisode
                    {
                        SeriesID = itemToRate.ID_TVDB,
                        Title    = itemToRate.Title,
                        Year     = itemToRate.Year > 1900 ? itemToRate.Year.ToString() : null,
                        Episode  = itemToRate.Episode.ToString(),
                        Season   = itemToRate.Season.ToString(),
                        UserName = TraktSettings.Username,
                        Password = TraktSettings.Password
                    };
                    // get the rating submitted to trakt
                    rating = int.Parse(GUIUtils.ShowRateDialog <TraktRateEpisode>(rateObject));
                }
                else if (itemToRate.VideoKind == VideoKind.Movie)
                {
                    TraktRateMovie rateObject = new TraktRateMovie
                    {
                        IMDBID   = itemToRate.ID_IMDB,
                        TMDBID   = itemToRate.ID_TMDB,
                        Title    = itemToRate.Title,
                        Year     = itemToRate.Year > 1900 ? itemToRate.Year.ToString() : null,
                        UserName = TraktSettings.Username,
                        Password = TraktSettings.Password
                    };
                    // get the rating submitted to trakt
                    rating = int.Parse(GUIUtils.ShowRateDialog <TraktRateMovie>(rateObject));
                }

                if (rating > 0)
                {
                    TraktLogger.Debug("Rating {0} as {1}/10", itemToRate.Title, rating.ToString());
                    // note: no user rating field to set
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            }.Start(videoInfo);
        }
Exemple #12
0
        /// <summary>
        /// Shows the Rate Episode Dialog after playback has ended
        /// </summary>
        /// <param name="episode">The episode being rated</param>
        private void ShowRateDialog(FileLocal episode)
        {
            new Thread((o) =>
            {
                FileLocal epToRate = o as FileLocal;
                if (epToRate == null)
                {
                    return;
                }

                string seriesid = null;
                int seasonidx   = 0;
                int episodeidx  = 0;

                if (epToRate.AnimeEpisodes == null || epToRate.AnimeEpisodes.Count == 0 || !GetTVDBEpisodeInfo(epToRate.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx))
                {
                    TraktLogger.Warning("Unable to rate episode, no AniDb/TVDb reference in database yet.");
                    return;
                }

                if (!TraktSettings.ShowRateDialogOnWatched)
                {
                    return;                                                  // not enabled
                }
                if (epToRate.AnimeEpisodes[0].UserRating > 0)
                {
                    return;                                                  // already rated
                }
                TraktLogger.Debug("Showing rate dialog for '{0}'", epToRate.AnimeEpisodes[0].EpisodeName);

                TraktRateEpisode rateObject = new TraktRateEpisode
                {
                    Title    = epToRate.AniDB_File.AnimeSeries.SeriesName,
                    Year     = GetStartYear(epToRate.AniDB_File.AnimeSeries),
                    Season   = seasonidx.ToString(),
                    Episode  = episodeidx.ToString(),
                    SeriesID = seriesid,
                    UserName = TraktSettings.Username,
                    Password = TraktSettings.Password
                };

                // get the rating submitted to trakt
                int rating = int.Parse(GUIUtils.ShowRateDialog <TraktRateEpisode>(rateObject));

                if (rating > 0)
                {
                    TraktLogger.Debug("Rating {0} as {1}/10", epToRate.AnimeEpisodes[0].EpisodeName, rating.ToString());
                    // note: can't set rating locally as its read only
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            }.Start(episode);
        }
        public void DisposeEvents()
        {
            TraktLogger.Debug("Removing Hooks from My Films");

            // unsubscribe from events
            MyFilmsDetail.RateItem     -= new MyFilmsDetail.RatingEventDelegate(OnRateItem);
            MyFilmsDetail.WatchedItem  -= new MyFilmsDetail.WatchedEventDelegate(OnToggleWatched);
            MyFilmsDetail.MovieStarted -= new MyFilmsDetail.MovieStartedEventDelegate(OnStartedMovie);
            MyFilmsDetail.MovieStopped -= new MyFilmsDetail.MovieStoppedEventDelegate(OnStoppedMovie);
            MyFilmsDetail.MovieWatched -= new MyFilmsDetail.MovieWatchedEventDelegate(OnWatchedMovie);
            MyFilms.ImportComplete     -= new MyFilms.ImportCompleteEventDelegate(OnImportComplete);
        }
Exemple #14
0
        /// <summary>
        /// Shows the Rate Movie Dialog after playback has ended
        /// </summary>
        /// <param name="movie">The movie being rated</param>
        private void ShowRateDialog(IMDBMovie movie)
        {
            if (!TraktSettings.ShowRateDialogOnWatched)
            {
                return;
            }
            if (!TraktSettings.ShowRateDlgForPlaylists && PlayListPlayer.SingletonPlayer.CurrentPlaylistType == PlayListType.PLAYLIST_VIDEO)
            {
                return;
            }

            TraktLogger.Debug("Showing rate dialog for movie. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", movie.Title, movie.Year, movie.IMDBNumber ?? "<empty>");

            var rateThread = new Thread((o) =>
            {
                var movieToRate = o as IMDBMovie;
                if (movieToRate == null)
                {
                    return;
                }

                var rateObject = new TraktSyncMovieRated
                {
                    Ids = new TraktMovieId {
                        Imdb = movieToRate.IMDBNumber.ToNullIfEmpty()
                    },
                    Title   = movieToRate.Title,
                    Year    = movieToRate.Year,
                    RatedAt = DateTime.UtcNow.ToISO8601(),
                };

                // get the rating submitted to trakt.tv
                int rating = GUI.GUIUtils.ShowRateDialog <TraktSyncMovieRated>(rateObject);

                if (rating > 0)
                {
                    // update local cache
                    TraktCache.AddMovieToRatings(rateObject, rating);

                    TraktLogger.Debug("Rating {0} ({1}) as {2}/10", movieToRate.Title, movie.Year, rating.ToString());
                }
                else if (rating == 0)
                {
                    TraktCache.RemoveMovieFromRatings(rateObject);
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            };

            rateThread.Start(movie);
        }
Exemple #15
0
        static void BufferTrailer(string url)
        {
            // stop player if currently playing some other video
            if (g_Player.Playing)
            {
                g_Player.Stop();
            }

            // prepare graph must be done on the MP main thread
            TraktLogger.Debug("Preparing graph for playback of '{0}'", url);
            var  factory       = new PlayerFactory(PlayerType.Internal, url);
            bool?prepareResult = ((OnlineVideosPlayer)factory.PreparedPlayer).PrepareGraph();

            TraktLogger.Debug("Preparing graph complete.");

            switch (prepareResult)
            {
            case true:
                GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
                {
                    TraktLogger.Info("OnlineVideo pre-buffering started.");
                    if (((OnlineVideosPlayer)factory.PreparedPlayer).BufferFile())
                    {
                        TraktLogger.Info("OnlineVideo pre-buffering complete.");
                        return(true);
                    }
                    else
                    {
                        TraktLogger.Error("Error pre-buffering trailer.");
                        return(null);
                    }
                },
                                                                          delegate(bool success, object result)
                {
                    PlayTrailer(url, factory, result as bool?);
                },
                                                                          GUI.Translation.BufferingTrailer, false);
                break;

            case false:
                // play without buffering
                PlayTrailer(url, factory, prepareResult);
                break;

            default:
                TraktLogger.Error("Failed to create player graph.");
                GUIUtils.ShowNotifyDialog(GUI.Translation.Error, GUI.Translation.UnableToPlayTrailer);
                break;
            }
        }
        private void InitProperties()
        {
            // set search term from loading parameter
            if (!string.IsNullOrEmpty(_loadParameter))
            {
                TraktLogger.Debug("Person Search Loading Parameter: {0}", _loadParameter);
                SearchTerm = _loadParameter;

                // check if the searchterm is a list of people
                if (SearchTerm.StartsWith("{") && SearchTerm.EndsWith("}"))
                {
                    IsMultiPersonSearch = true;
                    // multi-person search will most likely have fanart as its attached
                    // to a movie, show or episode.
                    string fanart = SearchTerm.FromJSON <PersonSearch>().Fanart;
                    if (File.Exists(fanart))
                    {
                        GUIUtils.SetProperty("#Trakt.People.Fanart", fanart);
                    }
                }
            }

            // remember previous search term
            SearchTermChanged = false;
            if (PreviousSearchTerm != SearchTerm)
            {
                SearchTermChanged = true;
            }
            PreviousSearchTerm = SearchTerm;

            // set context property
            if (!IsMultiPersonSearch)
            {
                GUIUtils.SetProperty("#Trakt.Search.SearchTerm", SearchTerm);
            }
            else
            {
                GUIUtils.SetProperty("#Trakt.Search.SearchTerm", SearchTerm.FromJSON <PersonSearch>().Title);
            }

            // load last layout
            CurrentLayout = (Layout)TraktSettings.SearchPeopleDefaultLayout;

            // update button label
            if (layoutButton != null)
            {
                GUIControl.SetControlLabel(GetID, layoutButton.GetID, GUICommon.GetLayoutTranslation(CurrentLayout));
            }
        }
Exemple #17
0
        public MyAnime(int priority)
        {
            // check if plugin exists otherwise plugin could accidently get added to list
            string pluginFilename = Path.Combine(Config.GetSubFolder(Config.Dir.Plugins, "Windows"), "Anime2.dll");

            if (!File.Exists(pluginFilename))
            {
                throw new FileNotFoundException("Plugin not found!");
            }

            TraktLogger.Debug("Adding Hooks to My Anime");
            animeWindow = (MainWindow)GUIWindowManager.GetWindow((int)ExternalPluginWindows.MyAnime);
            animeWindow.OnToggleWatched += new MainWindow.OnToggleWatchedHandler(OnToggleWatched);
            animeWindow.OnRateSeries    += new MainWindow.OnRateSeriesHandler(OnRateSeries);

            Priority = priority;
        }
Exemple #18
0
        /// <summary>
        /// Shows the Rate Movie Dialog after playback has ended
        /// </summary>
        /// <param name="movie">The movie being rated</param>
        private void ShowRateDialog(IMDBMovie movie)
        {
            if (!TraktSettings.ShowRateDialogOnWatched)
            {
                return;
            }
            if (!TraktSettings.ShowRateDlgForPlaylists && PlayListPlayer.SingletonPlayer.CurrentPlaylistType == PlayListType.PLAYLIST_VIDEO)
            {
                return;
            }

            TraktLogger.Debug("Showing rate dialog for '{0}'", movie.Title);

            new Thread((o) =>
            {
                IMDBMovie movieToRate = o as IMDBMovie;
                if (movieToRate == null)
                {
                    return;
                }

                TraktRateMovie rateObject = new TraktRateMovie
                {
                    IMDBID   = movieToRate.IMDBNumber,
                    Title    = movieToRate.Title,
                    Year     = movieToRate.Year.ToString(),
                    UserName = TraktSettings.Username,
                    Password = TraktSettings.Password
                };

                // get the rating submitted to trakt
                int rating = int.Parse(GUIUtils.ShowRateDialog <TraktRateMovie>(rateObject));

                if (rating > 0)
                {
                    TraktLogger.Debug("Rating {0} as {1}/10", movieToRate.Title, rating.ToString());
                    // note: no user rating field to update locally
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            }.Start(movie);
        }
        /// <summary>
        /// Shows the Rate Movie Dialog after playback has ended
        /// </summary>
        /// <param name="movie">The movie being rated</param>
        private void ShowRateDialog(MFMovie movie)
        {
            if (!TraktSettings.ShowRateDialogOnWatched)
            {
                return;                                             // not enabled
            }
            // if (movie.RatingUser > 0) return;                       // already rated -> removed, as IF we enable rating, we always want user to rate it....

            TraktLogger.Debug("Showing rate dialog for '{0}'", movie.Title);

            new Thread((o) =>
            {
                MFMovie movieToRate = o as MFMovie;
                if (movieToRate == null)
                {
                    return;
                }

                TraktRateMovie rateObject = new TraktRateMovie
                {
                    IMDBID   = movieToRate.IMDBNumber,
                    TMDBID   = movieToRate.TMDBNumber,
                    Title    = movieToRate.Title,
                    Year     = movieToRate.Year.ToString(),
                    UserName = TraktSettings.Username,
                    Password = TraktSettings.Password
                };

                // get the rating submitted to trakt
                int rating = int.Parse(GUI.GUIUtils.ShowRateDialog <TraktRateMovie>(rateObject));

                if (rating > 0)
                {
                    TraktLogger.Debug("Rating {0} as {1}/10", movieToRate.Title, rating.ToString());
                    movieToRate.RatingUser = (float)rating;
                    movieToRate.Username   = TraktSettings.Username;
                    movieToRate.Commit();
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            }.Start(movie);
        }
Exemple #20
0
        static void SaveFileCache(string filename, string value)
        {
            if (value == null)
            {
                return;
            }

            TraktLogger.Debug("Saving file to disk. Filename = '{0}'", filename);

            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(filename));
                File.WriteAllText(filename, value, Encoding.UTF8);
            }
            catch (Exception e)
            {
                TraktLogger.Error(string.Format("Error saving file. Filename = '{0}', Error = '{1}'", filename, e.Message));
            }
        }
        static string LoadFileCache(string filename, string defaultValue)
        {
            string returnValue = defaultValue;

            try
            {
                if (File.Exists(filename))
                {
                    TraktLogger.Debug("Loading file from disk. Filename = '{0}'", filename);
                    returnValue = File.ReadAllText(filename, Encoding.UTF8);
                }
            }
            catch (Exception e)
            {
                TraktLogger.Error(string.Format("Error loading file from disk. Filename = '{0}', Error = '{1}'", filename, e.Message));
                return(defaultValue);
            }

            return(returnValue);
        }
        public static string ToCountryName(this string twoLetterCode)
        {
            // check length of code is two letters
            if (string.IsNullOrEmpty(twoLetterCode))
            {
                return(null);
            }

            RegionInfo regionInfo = null;

            try
            {
                regionInfo = new RegionInfo(twoLetterCode);
            }
            catch (ArgumentException)
            {
                TraktLogger.Debug("Failed to convert two letter country code to country name. Two Letter Code = '{0}'", twoLetterCode);
                return(twoLetterCode);
            }
            return(regionInfo.DisplayName);
        }
        public static void SetProperty(string property, string value, bool log)
        {
            // prevent ugly display of property names
            if (string.IsNullOrEmpty(value))
            {
                value = " ";
            }

            GUIPropertyManager.SetProperty(property, value);

            if (log)
            {
                if (GUIPropertyManager.Changed)
                {
                    TraktLogger.Debug("Set property \"" + property + "\" to \"" + value + "\" successful");
                }
                else
                {
                    TraktLogger.Warning("Set property \"" + property + "\" to \"" + value + "\" failed");
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Download an image if it does not exist locally
        /// </summary>
        /// <param name="url">Online URL of image to download</param>
        /// <param name="localFile">Local filename to save image</param>
        /// <returns>true if image downloads successfully or loads from disk successfully</returns>
        public static bool DownloadImage(string url, string localFile)
        {
            WebClient webClient = new WebClient();

            webClient.Headers.Add("user-agent", TraktSettings.UserAgent);

            // Ignore Image placeholders (series/movies with no artwork)
            // use skins default images instead
            if (url.Contains("poster-small") || url.Contains("fanart-summary"))
            {
                return(false);
            }
            if (url.Contains("poster-dark") || url.Contains("fanart-dark") || url.Contains("episode-dark"))
            {
                return(false);
            }

            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(localFile));
                if (!File.Exists(localFile))
                {
                    TraktLogger.Debug("Downloading new image from: {0}", url);
                    webClient.DownloadFile(url, localFile);
                }
                return(true);
            }
            catch (Exception)
            {
                TraktLogger.Warning("Image download failed from '{0}' to '{1}'", url, localFile);
                try { if (File.Exists(localFile))
                      {
                          File.Delete(localFile);
                      }
                } catch { }
                return(false);
            }
        }
Exemple #25
0
 public void DisposeEvents()
 {
     TraktLogger.Debug("Removing Hooks from OnlineVideos");
     ovObject.TrackVideoPlayback -= new GUIOnlineVideos.TrackVideoPlaybackHandler(TrackVideoPlayback);
     ovObject = null;
 }
Exemple #26
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");
        }
        /// <summary>
        /// Shows the Rate Dialog after playback has ended
        /// </summary>
        /// <param name="episode">The item being rated</param>
        internal static void ShowRateDialog(VideoInfo videoInfo)
        {
            if (!TraktSettings.ShowRateDialogOnWatched)
            {
                return;                                             // not enabled
            }
            TraktLogger.Debug("Showing rate dialog for '{0}'", videoInfo.Title);

            var rateThread = new System.Threading.Thread((o) =>
            {
                var itemToRate = o as VideoInfo;
                if (itemToRate == null)
                {
                    return;
                }

                int rating = 0;

                if (itemToRate.Type == VideoType.Series)
                {
                    var rateObject = new TraktSyncShowRatedEx
                    {
                        Title   = itemToRate.Title,
                        Year    = itemToRate.Year.ToNullableInt32(),
                        Seasons = new List <TraktSyncShowRatedEx.Season>
                        {
                            new TraktSyncShowRatedEx.Season
                            {
                                Number   = itemToRate.SeasonIdx.ToInt(),
                                Episodes = new List <TraktSyncShowRatedEx.Season.Episode>
                                {
                                    new TraktSyncShowRatedEx.Season.Episode
                                    {
                                        Number  = itemToRate.EpisodeIdx.ToInt(),
                                        RatedAt = DateTime.UtcNow.ToISO8601()
                                    }
                                }
                            }
                        }
                    };
                    // get the rating submitted to trakt
                    rating = GUIUtils.ShowRateDialog <TraktSyncShowRatedEx>(rateObject);

                    // add episode rated to cache
                    if (rating > 0)
                    {
                        TraktCache.AddEpisodeToRatings(
                            new TraktShow
                        {
                            Ids   = new TraktShowId(),
                            Title = rateObject.Title,
                            Year  = rateObject.Year,
                        },
                            new TraktEpisode
                        {
                            Ids    = new TraktEpisodeId(),
                            Season = rateObject.Seasons[0].Number,
                            Number = rateObject.Seasons[0].Episodes[0].Number
                        },
                            rating
                            );
                    }
                }
                else if (itemToRate.Type == VideoType.Movie)
                {
                    var rateObject = new TraktSyncMovieRated
                    {
                        Ids     = new TraktMovieId(),
                        Title   = itemToRate.Title,
                        Year    = itemToRate.Year.ToNullableInt32(),
                        RatedAt = DateTime.UtcNow.ToISO8601()
                    };

                    // get the rating submitted to trakt
                    rating = GUIUtils.ShowRateDialog <TraktSyncMovieRated>(rateObject);

                    // add movie rated to cache
                    if (rating > 0)
                    {
                        TraktCache.AddMovieToRatings(rateObject, rating);
                    }
                    else
                    {
                        TraktCache.RemoveMovieFromRatings(rateObject);
                    }
                }

                if (rating > 0)
                {
                    TraktLogger.Debug("Rating {0} as {1}/10", itemToRate.Title, rating.ToString());
                }
            })
            {
                Name         = "Rate",
                IsBackground = true
            };

            rateThread.Start(videoInfo);
        }
Exemple #28
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 #29
0
        public bool Scrobble(string filename)
        {
            StopScrobble();

            // stop check if not valid player type for plugin handler
            if (g_Player.IsTV || g_Player.IsTVRecording)
            {
                return(false);
            }

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

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

            CurrentMovie = movie;

            // create timer 15 minute timer to send watching status
            #region scrobble timer
            TraktTimer = new Timer(new TimerCallback((stateInfo) =>
            {
                Thread.CurrentThread.Name = "Scrobble";

                IMDBMovie currentMovie = stateInfo as IMDBMovie;

                TraktLogger.Info("Scrobbling Movie {0}", currentMovie.Title);

                // get online runtime if local one unavailable to be retrieved
                double duration = g_Player.Duration == 0.0 ? currentMovie.RunTime * 60.0 : g_Player.Duration;
                double progress = 0.0;

                // get current progress of player (in seconds) to work out percent complete
                if (duration > 0.0)
                {
                    progress = (g_Player.CurrentPosition / duration) * 100.0;
                }

                TraktLogger.Debug(string.Format("Percentage of {0} is {1}%", currentMovie.Title, progress.ToString("N2")));

                // create Scrobbling Data
                TraktMovieScrobble scrobbleData = CreateScrobbleData(currentMovie);
                if (scrobbleData == null)
                {
                    return;
                }

                // set duration/progress in scrobble data
                scrobbleData.Duration = Convert.ToInt32(duration / 60).ToString();
                scrobbleData.Progress = Convert.ToInt32(progress).ToString();

                // set watching status on trakt
                TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, TraktScrobbleStates.watching);
                TraktLogger.LogTraktResponse(response);
            }), movie, 3000, 900000);
            #endregion

            return(true);
        }
        public void SyncLibrary()
        {
            TraktLogger.Info("My Films Starting Sync");
            SyncInProgress = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    notInLocalCollection = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                #region update trending tags

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

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

            myvideos.Clear();

            SyncInProgress = false;
            TraktLogger.Info("My Films Sync Completed");
        }