Example #1
0
        public AddSourceResult AddSource(Type providerType)
        {
            // internal scripts dont need to be updated, so just quit
            // if we dont need to reload everything
            if (updateOnly)
            {
                return(AddSourceResult.FAILED);
            }

            foreach (DBSourceInfo currSource in allSources)
            {
                if (currSource.ProviderType == providerType)
                {
                    return(AddSourceResult.FAILED);
                }
            }

            DBSourceInfo newSource = new DBSourceInfo();

            newSource.ProviderType = providerType;
            newSource.Commit();
            updateListsWith(newSource);
            normalizePriorities();

            return(AddSourceResult.SUCCESS);
        }
        public static DBSourceMusicVideoInfo Get(DBTrackInfo mv, DBSourceInfo source)
        {
            foreach (DBSourceMusicVideoInfo currInfo in mv.SourceMusicVideoInfo)
                if (currInfo.Source == source)
                    return currInfo;

            return null;
        }
        public static DBSourceMovieInfo Get(DBMovieInfo movie, DBSourceInfo source)
        {
            foreach (DBSourceMovieInfo currInfo in movie.SourceMovieInfo)
                if (currInfo.Source == source)
                    return currInfo;

            return null;
        }
Example #4
0
        private void lowerPriorityButton_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem currItem in listView.SelectedItems)
            {
                DBSourceInfo source = (DBSourceInfo)currItem.Tag;
                MovingPicturesCore.DataProviderManager.ChangePriority(source, DisplayType, false);
            }

            listView.Sort();
        }
Example #5
0
        private void loadProvidersFromDatabase()
        {
            logger.Info("Loading existing data sources...");

            foreach (DBSourceInfo currSource in DBSourceInfo.GetAll())
            {
                updateListsWith(currSource);
            }

            detailSources.Sort(sorters[DataType.DETAILS]);
            coverSources.Sort(sorters[DataType.COVERS]);
            backdropSources.Sort(sorters[DataType.BACKDROPS]);
        }
Example #6
0
        private void enableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem currItem in listView.SelectedItems)
            {
                DBSourceInfo source = (DBSourceInfo)currItem.Tag;
                if (source.IsDisabled(DisplayType))
                {
                    MovingPicturesCore.DataProviderManager.SetDisabled(source, DisplayType, false);
                }
            }

            listView.Sort();
            repaintListItems();
        }
Example #7
0
        public void SetDisabled(DBSourceInfo source, DataType type, bool disable)
        {
            if (disable)
            {
                source.SetPriority(type, -1);
                source.Commit();
            }
            else
            {
                source.SetPriority(type, int.MaxValue);
            }

            getEditableList(type).Sort(sorters[type]);
            normalizePriorities();
        }
Example #8
0
        private void updateListsWith(DBSourceInfo newSource)
        {
            if (newSource.ProviderType == null)
            {
                logger.Info("Removing invalid provider.");
                newSource.Delete();
                return;
            }

            lock (allSources)
                if (!allSources.Contains(newSource))
                {
                    allSources.Add(newSource);
                }

            lock (backdropSources) {
                if (newSource.Provider.ProvidesBackdrops && !backdropSources.Contains(newSource))
                {
                    backdropSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesBackdrops && backdropSources.Contains(newSource))
                {
                    backdropSources.Remove(newSource);
                }
            }

            lock (coverSources) {
                if (newSource.Provider.ProvidesCoverArt && !coverSources.Contains(newSource))
                {
                    coverSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesCoverArt && coverSources.Contains(newSource))
                {
                    coverSources.Remove(newSource);
                }
            }

            lock (detailSources) {
                if (newSource.Provider.ProvidesMoviesDetails && !detailSources.Contains(newSource))
                {
                    detailSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesMoviesDetails && detailSources.Contains(newSource))
                {
                    detailSources.Remove(newSource);
                }
            }
        }
Example #9
0
        public void RemoveSource(DBSourceInfo source)
        {
            if (source == null)
            {
                return;
            }

            foreach (DataType currType in Enum.GetValues(typeof(DataType)))
            {
                lock (getEditableList(currType))
                    getEditableList(currType).Remove(source);
            }

            lock (allSources) allSources.Remove(source);
            source.Delete();
        }
Example #10
0
        private void loadProvidersFromDatabase()
        {
            logger.Info("Loading existing data sources...");

            foreach (DBSourceInfo currSource in DBSourceInfo.GetAll())
            {
                logger.Debug("*** loadProvidersFromDatabase: " + currSource);
                updateListsWith(currSource);
            }

            trackDetailSources.Sort(sorters[DataType.TRACKDETAIL]);
            artistDetailSources.Sort(sorters[DataType.ARTISTDETAIL]);
            albumDetailSources.Sort(sorters[DataType.ALBUMDETAIL]);
            albumArtSources.Sort(sorters[DataType.ALBUMART]);
            artistArtSources.Sort(sorters[DataType.ARTISTART]);
            trackArtSources.Sort(sorters[DataType.TRACKART]);
        }
Example #11
0
        private void removeButton_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show(
                "This will PERMANENTLY REMOVE the selected data source!\n" +
                "This action is irreversable. Normally the best choice is\n" +
                "to disable rather than remove a data source. Are you sure\n" +
                "you want to continue?", "Warning!", MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes)
            {
                foreach (ListViewItem currItem in listView.SelectedItems)
                {
                    DBSourceInfo source = (DBSourceInfo)currItem.Tag;
                    MovingPicturesCore.DataProviderManager.RemoveSource(source);
                    listView.Items.Remove(currItem);
                }
            }
        }
Example #12
0
        private void disableButton_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem currItem in listView.SelectedItems)
            {
                DBSourceInfo source = (DBSourceInfo)currItem.Tag;
                if (!source.IsDisabled(DisplayType))
                {
                    MovingPicturesCore.DataProviderManager.SetDisabled(source, DisplayType, true);
                }
            }

            listView.Sort();
            listView.SelectedItems.Clear();
            if (listView.Items.Count > 0)
            {
                listView.Items[0].Selected = true;
            }
            repaintListItems();
        }
Example #13
0
        /// <summary>
        /// returns the tmdb id for a movie if its exists
        /// </summary>
        private string getTmdbId(DBMovieInfo movie)
        {
            // get source info, maybe already have it from poster or movieinfo
            var tmdbSource = DBSourceInfo.GetAll().Find(s => s.ToString() == "themoviedb.org");

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

            string id = movie.GetSourceMovieInfo(tmdbSource).Identifier;

            if (id == null || id.Trim() == string.Empty)
            {
                return(null);
            }

            return(id);
        }
Example #14
0
        public void LoadInternalProviders()
        {
            logger.Info("Checking internal scripts for updates...");

            AddSource(typeof(LocalProvider));
            AddSource(typeof(ScriptableProvider), Resources.Script_IMDb);
            AddSource(typeof(TheMovieDbProvider));
            AddSource(typeof(FanartTVProvider));
            AddSource(typeof(MovieMeterProvider));
            AddSource(typeof(ScriptableProvider), Resources.Script_OFDb);
            AddSource(typeof(ScriptableProvider), Resources.Script_MovieMaze);
            AddSource(typeof(ScriptableProvider), Resources.Script_Allocine);
            AddSource(typeof(ScriptableProvider), Resources.Script_MyMoviesItalian);
            AddSource(typeof(ScriptableProvider), Resources.Script_FilmWeb);
            AddSource(typeof(ScriptableProvider), Resources.Script_Scope);
            AddSource(typeof(ScriptableProvider), Resources.Script_Kinopoisk);
            AddSource(typeof(ScriptableProvider), Resources.Script_Alpacine);
            AddSource(typeof(ScriptableProvider), Resources.Script_Sratim);
            AddSource(typeof(ScriptableProvider), Resources.Script_FilmAffinity);
            AddSource(typeof(ScriptableProvider), Resources.Script_CSFD);
            AddSource(typeof(ScriptableProvider), Resources.Script_MyMoviesLocal);
            AddSource(typeof(ScriptableProvider), Resources.Script_XBMC);
            AddSource(typeof(ScriptableProvider), Resources.Script_Filmtipset);
            AddSource(typeof(ScriptableProvider), Resources.Script_Ptgate);
            AddSource(typeof(ScriptableProvider), Resources.Script_Daum);
            AddSource(typeof(ScriptableProvider), Resources.Script_kvikmyndir);
            AddSource(typeof(ScriptableProvider), Resources.Script_EmberMediaManager);
            AddSource(typeof(MyVideosProvider));

            // remove the impawards script (requested by site owner)
            DBSourceInfo impSource = DBSourceInfo.GetFromScriptID(874903);

            if (impSource != null)
            {
                logger.Warn("IMPAwards script has been disabled at the website operators request. Very sorry!");
                RemoveSource(impSource);
            }

            normalizePriorities();
        }
        private static string GetTmdbID(DBMovieInfo movie)
        {
            if (tmdbSource == null)
            {
                tmdbSource = GetTmdbSourceInfo();
                if (tmdbSource == null)
                {
                    return(null);
                }
            }

            string id = movie.GetSourceMovieInfo(tmdbSource).Identifier;

            if (id == null || id.Trim() == string.Empty)
            {
                return(null);
            }
            if (int.Parse(id.Trim()) <= 0)
            {
                return(null);
            }

            return(id);
        }
 public DBSourceMovieInfo GetSourceMovieInfo(DBSourceInfo source)
 {
     return DBSourceMovieInfo.GetOrCreate(this, source);
 }
        private void refreshMovieButton_Click(object sender, EventArgs e)
        {
            if (movieListBox.SelectedItems.Count == 0)
                return;

            if (sender is ToolStripMenuItem) {
                selectedSource = (DBSourceInfo)((ToolStripMenuItem)sender).Tag;
                translate = ((ToolStripMenuItem)sender).Name == "TranslateItem";
            }
            else
                selectedSource = null;

            DialogResult result =
                MessageBox.Show("This action will overwrite existing movie details, including any custom modifications.",
                                "Refresh Movie", MessageBoxButtons.OKCancel);

            if (result == System.Windows.Forms.DialogResult.OK) {
                processingMovies = new List<DBMovieInfo>();
                foreach (ListViewItem currItem in movieListBox.SelectedItems)
                    processingMovies.Add((DBMovieInfo)currItem.Tag);

                if (movieListBox.SelectedItems.Count == 1) {
                    ProgressPopup popup = new ProgressPopup(new WorkerDelegate(refreshMovies));
                    popup.Owner = this.ParentForm;
                    popup.ShowDialog();
                }
                else {
                    ProgressPopup popup = new ProgressPopup(new TrackableWorkerDelegate(refreshMovies));
                    popup.Owner = this.ParentForm;
                    popup.ShowDialog();
                }

                updateMoviePanel();
                processingMovies.Clear();
            }
        }
Example #18
0
        public ScriptVersionPopup(DBSourceInfo source)
        {
            InitializeComponent();

            this.source = source;
        }
Example #19
0
 public DBSourceMusicVideoInfo GetSourceMusicVideoInfo(DBSourceInfo source)
 {
     return(DBSourceMusicVideoInfo.GetOrCreate(this, source));
 }
Example #20
0
        private void ScraperScriptPositioning(ref DBSourceInfo source)
        {
            // Re-Position the IMDb+ scraper-script to become primary source

            if (source == null) return;
            Logger.Info("Repositioning {0} script to become the new primary details source.", source.Provider.Name);

            // shift all enabled 'movie detail' sources down by one
            foreach (var enabledSource in DBSourceInfo.GetAll().Where(s => s.DetailsPriority > -1))
            {
                enabledSource.DetailsPriority++;
                enabledSource.Commit();
            }

            // now set highest priority to the IMDb+ source
            source.SetPriority(DataType.DETAILS, 0);
            source.Commit();

            // set IMDb+ cover source higher than default IMDb source
            var IMDbSource = DBSourceInfo.GetFromScriptID(IMDbScriptId);

            if (IMDbSource != null && IMDbSource.CoverPriority != null)
            {
                int coverPriority = (int)IMDbSource.CoverPriority;

                // no point replacing cover source if imdb is disabled
                if (coverPriority > -1)
                {
                    // shift down the rest, leave anything else in place
                    foreach (var enabledSource in DBSourceInfo.GetAll().Where(s => s.CoverPriority >= coverPriority))
                    {
                        enabledSource.CoverPriority++;
                        enabledSource.Commit();
                    }

                    // now replace IMDb cover priority with IMDb+ source
                    source.SetPriority(DataType.COVERS, coverPriority);
                    source.Commit();
                }
            }
        }
        public ScriptVersionPopup(DBSourceInfo source)
        {
            InitializeComponent();

            this.source = source;
        }
Example #22
0
        private void updateListsWith(DBSourceInfo newSource)
        {
            if (newSource.ProviderType == null)
            {
                logger.Info("Removing invalid provider.");
                newSource.Delete();
                return;
            }

            lock (allSources)
            {
                if (!allSources.Contains(newSource))
                {
                    logger.Debug("*** updateListsWith: allSource.Add: " + newSource);
                    allSources.Add(newSource);
                }
            }
            lock (artistArtSources)
            {
                logger.Debug("*** updateListsWith: artistArtSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !artistArtSources.Contains(newSource));
                if (newSource.Provider.ProvidesArtistArt && !artistArtSources.Contains(newSource))
                {
                    artistArtSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesArtistArt && artistArtSources.Contains(newSource))
                {
                    artistArtSources.Remove(newSource);
                }
            }

            lock (albumArtSources)
            {
                logger.Info("*** updateListsWith: albumArtSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !albumArtSources.Contains(newSource));
                if (newSource.Provider.ProvidesAlbumArt && !albumArtSources.Contains(newSource))
                {
                    albumArtSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesAlbumArt && albumArtSources.Contains(newSource))
                {
                    albumArtSources.Remove(newSource);
                }
            }

            lock (trackArtSources)
            {
                logger.Debug("*** updateListsWith: trackArtSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !trackArtSources.Contains(newSource));
                if (newSource.Provider.ProvidesTrackArt && !trackArtSources.Contains(newSource))
                {
                    trackArtSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesTrackArt && trackArtSources.Contains(newSource))
                {
                    trackArtSources.Remove(newSource);
                }
            }

            lock (trackDetailSources)
            {
                logger.Debug("*** updateListsWith: trackDetailSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !trackDetailSources.Contains(newSource));
                if (newSource.Provider.ProvidesTrackDetails && !trackDetailSources.Contains(newSource))
                {
                    trackDetailSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesTrackDetails && trackDetailSources.Contains(newSource))
                {
                    trackDetailSources.Remove(newSource);
                }
            }

            lock (artistDetailSources)
            {
                logger.Debug("*** updateListsWith: artistDetailSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !artistDetailSources.Contains(newSource));
                if (newSource.Provider.ProvidesArtistDetails && !artistDetailSources.Contains(newSource))
                {
                    artistDetailSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesArtistDetails && artistDetailSources.Contains(newSource))
                {
                    artistDetailSources.Remove(newSource);
                }
            }

            lock (albumDetailSources)
            {
                logger.Debug("*** updateListsWith: albumDetailSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !albumDetailSources.Contains(newSource));
                if (newSource.Provider.ProvidesAlbumDetails && !albumDetailSources.Contains(newSource))
                {
                    albumDetailSources.Add(newSource);
                }
                else if (!newSource.Provider.ProvidesAlbumDetails && albumDetailSources.Contains(newSource))
                {
                    albumDetailSources.Remove(newSource);
                }
            }
        }
 private static DBSourceInfo GetTmdbSourceInfo()
 {
     return(DBSourceInfo.GetAll().Find(s => s.ToString() == "themoviedb.org"));
 }
        public void SetDisabled(DBSourceInfo source, DataType type, bool disable)
        {
            if (disable) {
                source.SetPriority(type, -1);
                source.Commit();
            }
            else
                source.SetPriority(type, int.MaxValue);

            getEditableList(type).Sort(sorters[type]);
            normalizePriorities();
        }
        public void ChangePriority(DBSourceInfo source, DataType type, bool raise)
        {
            if (source.IsDisabled(type)) {
                if (raise)
                    SetDisabled(source, type, false);
                else return;
            }

            // grab the correct list
            List<DBSourceInfo> sourceList = getEditableList(type);

            // make sure the specified source is in our list
            if (!sourceList.Contains(source))
                return;

            if (source.GetPriority(type) == null) {
                logger.Error("No priority set for " + type.ToString());
                return;
            }

            // make sure our index is in sync
            int index = sourceList.IndexOf(source);
            int oldPriority = (int) source.GetPriority(type);
            if (index != oldPriority)
                logger.Warn("Priority and List.IndexOf out of sync...");

            // raise priority
            if (raise) {
                if (source.GetPriority(type) > 0) {
                    source.SetPriority(type, oldPriority - 1);
                    sourceList[index - 1].SetPriority(type, oldPriority);

                    source.Commit();
                    sourceList[index - 1].Commit();
                }
            }

            // lower priority
            else {
                if (source.GetPriority(type) < sourceList.Count - 1 &&
                    sourceList[index + 1].GetPriority(type) != -1) {

                    source.SetPriority(type, oldPriority + 1);
                    sourceList[index + 1].SetPriority(type, oldPriority);

                    source.Commit();
                    sourceList[index + 1].Commit();
                }
            }

            // resort the list
            lock (sourceList) sourceList.Sort(sorters[type]);
        }
        public AddSourceResult AddSource(Type providerType, string scriptContents, bool active)
        {
            IScriptableMovieProvider newProvider = (IScriptableMovieProvider)Activator.CreateInstance(providerType);

            DBScriptInfo newScript = new DBScriptInfo();
            newScript.Contents = scriptContents;

            // if a provider can't be created based on this script we have a bad script file.
            if (newScript.Provider == null)
                return AddSourceResult.FAILED;

            // check if we already have this script in memory.
            foreach (DBSourceInfo currSource in allSources)
                // if some version of the script is already in the database
                if (currSource.IsScriptable() && ((IScriptableMovieProvider)currSource.Provider).ScriptID == newScript.Provider.ScriptID) {
                    bool uniqueDate = newScript.Provider.Published != null;
                    foreach (DBScriptInfo currScript in currSource.Scripts) {
                        if (uniqueDate &&
                            currScript.Provider.Published != null &&
                            currScript.Provider.Published.Value.Equals(newScript.Provider.Published.Value))

                            uniqueDate = false;

                        // check if the same version is already loaded
                        if (currScript.Equals(newScript)) {
                            if (DebugMode) {
                                logger.Warn("Script version number already loaded. Reloading because in Debug Mode.");
                                currScript.Contents = scriptContents;
                                currScript.Reload();
                                updateListsWith(currSource);
                                currScript.Commit();
                                normalizePriorities();
                                return AddSourceResult.SUCCESS_REPLACED;
                            }
                            else {
                                logger.Debug("Script already loaded.");
                                return AddSourceResult.FAILED_VERSION;
                            }
                        }
                    }

                    // if the date is unique, go ahead and add the new script
                    if (uniqueDate || DebugMode) {
                        currSource.Scripts.Add(newScript);
                        currSource.SelectedScript = newScript;
                        updateListsWith(currSource);
                        newScript.Commit();
                        currSource.Commit();
                        normalizePriorities();

                        if (uniqueDate)
                            return AddSourceResult.SUCCESS;
                        else
                            return AddSourceResult.SUCCESS_REPLACED;
                    }
                    else {
                        logger.Error("Script failed to load, publish date is not unique.");
                        return AddSourceResult.FAILED_DATE;
                    }
                }

            // if there was nothing to update, and we are not looking to add new data sources, quit
            if (updateOnly)
                return AddSourceResult.SUCCESS;

            // build the new source information
            DBSourceInfo newSource = new DBSourceInfo();
            newSource.ProviderType = providerType;
            newSource.Scripts.Add(newScript);
            newSource.SelectedScript = newScript;

            // add and commit
            updateListsWith(newSource);
            newScript.Commit();
            newSource.Commit();
            normalizePriorities();

            // if not set to active, disable the new source by default
            if (!active)
                foreach (DataType currType in Enum.GetValues(typeof(DataType)))
                    SetDisabled(newSource, currType, true);

            return AddSourceResult.SUCCESS;
        }
Example #27
0
        private void CheckForUpdate()
        {
            Thread updateThread = new Thread(delegate(object obj)
            {
                Logger.Info("Checking for scraper update");

                string localFile = GetTempFilename();
                if (DownloadFile(ScraperUpdateFile, localFile))
                {
                    // set property paths to options/rename files
                    UpdateScriptPaths(localFile);

                    // try to install latest version
                    // will return false if already latest version
                    if (ScraperScriptInstallation(localFile))
                    {
                        // set highest priority if not already installed
                        if (IMDbPlusSource == null)
                        {
                            IMDbPlusSource = DBSourceInfo.GetFromScriptID(IMDbPlusScriptId);
                            ScraperScriptPositioning(ref IMDbPlusSource);
                        }
                        SetIMDbProperties();
                        HideShowForceIMDbPlusButton();
                        if (!PluginSettings.DisableNotifications)
                        {
                            // give some time for mediaportal to load if updated on startup
                            Thread.Sleep(10000);
                            GUIUtils.ShowNotifyDialog(Translation.Update, string.Format(Translation.UpdatedScraperScript, IMDbPlusSource.Provider.Version));
                        }
                    }

                    // remove temp download file
                    try { File.Delete(localFile); }
                    catch { }

                    PluginSettings.SyncLastDateTime = DateTime.Now.ToString();
                    GUIUtils.SetProperty("#IMDb.Scraper.LastUpdated", PluginSettings.SyncLastDateTime);
                }

                Logger.Info("Checking for replacements update");

                // Update Replacements Database
                localFile = GetTempFilename();
                if (DownloadFile(ReplacementsUpdateFile, localFile))
                {
                    // only update replacements if they differ
                    if (!FilesAreEqual(localFile, Replacements.ReplacementsFile))
                    {
                        try
                        {
                            // replace existing file
                            File.Copy(localFile, Replacements.ReplacementsFile, true);
                            Logger.Info("Replacements updated to latest version successfully.");
                        }
                        catch (Exception e)
                        {
                            Logger.Error("Replacements update failed: {0}", e.Message);
                        }

                        Replacements.ClearCache(false);
                        SetReplacementProperties();
                    }
                    else
                    {
                        Logger.Info("Skipping update, latest version already installed.");
                    }

                    // remove temp download file
                    try { File.Delete(localFile); }
                    catch { }
                }

            })
            {
                IsBackground = true,
                Name = "Check for Updates"
            };

            updateThread.Start();
        }
Example #28
0
        /// <summary>
        /// Starting Point
        /// </summary>
        public override bool Init()
        {
            Logger.Info("Starting IMDb+ v{0}", PluginSettings.Version);

            // Initialize translations
            Translation.Init();

            // Load Settings
            PluginSettings.LoadSettings();

            // Init Extension Settings
            extensionSettings.Init();

            // Get IMDb+ Data Provider
            IMDbPlusSource = DBSourceInfo.GetFromScriptID(IMDbPlusScriptId);
            SetIMDbProperties();

            // Get Replacements and set properties
            SetReplacementProperties();

            // Init refresh properties
            SetMovieRefreshProperties(null, -1, -1, true);

            // start update timer, passing along configured parameters
            // add small 3sec delay if syncing on startup.
            int syncInterval = PluginSettings.SyncInterval * 60 * 60 * 1000;
            int startTime = GetSyncStartTime();
            syncUpdateTimer = new Timer(new TimerCallback((o) => { CheckForUpdate(); }), null, startTime, syncInterval);

            // listen to resume/standby events
            Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);

            // Load main skin window
            // this is a launching pad to all other windows
            string xmlSkin = GUIGraphicsContext.Skin + @"\IMDb+.xml";
            Logger.Info("Plugin initialization complete.");
            return Load(xmlSkin);
        }
        public void SyncLibrary()
        {
            TraktLogger.Info("Moving Pictures Starting Library Sync");
            SyncLibraryInProgress = true;

            // Get all movies in the local database
            var collectedMovies = DBMovieInfo.GetAll();

            // Get TMDb Data Provider
            tmdbSource = DBSourceInfo.GetAll().Find(s => s.ToString() == "themoviedb.org");

            // Remove any blocked movies
            TraktLogger.Info("Removing blocked files and folders from sync movie list");
            collectedMovies.RemoveAll(m => TraktSettings.BlockedFolders.Any(f => m.LocalMedia[0].FullPath.ToLowerInvariant().Contains(f.ToLowerInvariant())));
            collectedMovies.RemoveAll(m => TraktSettings.BlockedFilenames.Contains(m.LocalMedia[0].FullPath));

            // Remove any movies that don't have any valid online ID's e.g. IMDb ID or TMDb ID.
            if (TraktSettings.SkipMoviesWithNoIdsOnSync)
            {
                TraktLogger.Info("Removing movies that contain no valid online ID from sync movie list");
                collectedMovies.RemoveAll(m => !BasicHandler.IsValidImdb(m.ImdbID) && GetTmdbID(m) == null);
            }

            #region Skipped Movies Check
            // Remove Skipped Movies from previous Sync
            //TODO
            //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);
            //                collectedMovies.RemoveAll(m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.ImdbID == 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, they're sometimes accepted if defined on themoviedb.org so we need to
            // do this to prevent syncing these movies every sync interval.
            //TODO
            //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<DBMovieInfo> criteria = m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.ImdbID == movie.IMDBID);
            //        if (collectedMovies.Exists(criteria))
            //        {
            //            TraktLogger.Debug("Skipping movie, Title: {0}, Year: {1}, IMDb: {2}", movie.Title, movie.Year, movie.IMDBID);
            //            collectedMovies.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

            #region Get online data from cache

            #region Get unwatched / watched movies from trakt.tv
            IEnumerable<TraktMovieWatched> traktWatchedMovies = null;

            var traktUnWatchedMovies = TraktCache.GetUnWatchedMoviesFromTrakt();
            if (traktUnWatchedMovies == null)
            {
                TraktLogger.Error("Error getting unwatched movies from trakt server, unwatched and watched sync will be skipped");
            }
            else
            {
                TraktLogger.Info("There are {0} unwatched movies since the last sync with trakt.tv", traktUnWatchedMovies.Count());

                traktWatchedMovies = TraktCache.GetWatchedMoviesFromTrakt();
                if (traktWatchedMovies == null)
                {
                    TraktLogger.Error("Error getting watched movies from trakt server, watched sync will be skipped");
                }
                else
                {
                    TraktLogger.Info("There are {0} watched movies in trakt.tv library", traktWatchedMovies.Count().ToString());
                }
            }
            #endregion

            #region Get collected movies from trakt.tv
            var traktCollectedMovies = TraktCache.GetCollectedMoviesFromTrakt();
            if (traktCollectedMovies == null)
            {
                TraktLogger.Error("Error getting collected movies from trakt server");
            }
            else
            {
                TraktLogger.Info("There are {0} collected movies in trakt.tv library", traktCollectedMovies.Count());
            }
            #endregion

            #region Get rated movies from trakt.tv
            var traktRatedMovies = TraktCache.GetRatedMoviesFromTrakt();
            if (traktRatedMovies == null)
            {
                TraktLogger.Error("Error getting rated movies from trakt server");
            }
            else
            {
                TraktLogger.Info("There are {0} rated movies in trakt.tv library", traktRatedMovies.Count());
            }
            #endregion

            #region Get watchlisted movies from trakt.tv
            var traktWatchlistedMovies = TraktCache.GetWatchlistedMoviesFromTrakt();
            if (traktWatchlistedMovies == null)
            {
                TraktLogger.Error("Error getting watchlisted movies from trakt server");
            }
            else
            {
                TraktLogger.Info("There are {0} watchlisted movies in trakt.tv library", traktWatchlistedMovies.Count());
            }
            #endregion

            #region Get custom lists from trakt.tv
            var traktCustomLists = TraktCache.GetCustomLists();
            if (traktCustomLists == null)
            {
                TraktLogger.Error("Error getting custom lists from trakt server");
            }
            else
            {
                TraktLogger.Info("There are {0} custom lists in trakt.tv library", traktCustomLists.Count());
            }
            #endregion

            #endregion

            // optionally do library sync
            if (TraktSettings.SyncLibrary)
            {
                #region Get local database info

                TraktLogger.Info("Found {0} movies available to sync in MovingPictures database", collectedMovies.Count);

                // get the movies that we have watched
                var watchedMovies = collectedMovies.Where(m => m.ActiveUserSettings.WatchedCount > 0).ToList();
                TraktLogger.Info("Found {0} watched movies available to sync in MovingPictures database", watchedMovies.Count);

                // get the movies that we have rated/unrated
                // check if there is a rating out of 10 if using supported version of the plugin
                var ratedMovies = collectedMovies.Where(m => (AdvancedRatings && HasAdvancedRating(m)) || m.ActiveUserSettings.UserRating.GetValueOrDefault(0) > 0).ToList();
                TraktLogger.Info("Found {0} rated movies available to sync in MovingPictures database", ratedMovies.Count);

                #endregion

                #region Mark movies as unwatched in local database
                if (traktUnWatchedMovies != null && traktUnWatchedMovies.Count() > 0)
                {
                    foreach (var movie in traktUnWatchedMovies)
                    {
                        var localMovie = watchedMovies.FirstOrDefault(m => MovieMatch(m, movie));
                        if (localMovie == null) continue;

                        TraktLogger.Info("Marking movie as unwatched in local database, movie is not watched on trakt.tv. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}'",
                                          movie.Title, movie.Year.HasValue ? movie.Year.ToString() : "<empty>", movie.Ids.Imdb ?? "<empty>", movie.Ids.Tmdb.HasValue ? movie.Ids.Tmdb.ToString() : "<empty>" );

                        localMovie.ActiveUserSettings.WatchedCount = 0;
                        localMovie.ActiveUserSettings.Commit();
                    }

                    // update watched set
                    watchedMovies = collectedMovies.Where(m => m.ActiveUserSettings.WatchedCount > 0).ToList();
                }
                #endregion

                #region Mark movies as watched in local database
                if (traktWatchedMovies != null && traktWatchedMovies.Count() > 0)
                {
                    foreach (var twm in traktWatchedMovies)
                    {
                        var localMovie = collectedMovies.FirstOrDefault(m => MovieMatch(m, twm.Movie));
                        if (localMovie == null) continue;

                        if (localMovie.ActiveUserSettings.WatchedCount < twm.Plays)
                        {
                            TraktLogger.Info("Updating local movie watched state / play count to match trakt.tv. Plays = '{0}', Title = '{1}', Year = '{2}', IMDb ID = '{3}', TMDb ID = '{4}'",
                                              twm.Plays, twm.Movie.Title, twm.Movie.Year.HasValue ? twm.Movie.Year.ToString() : "<empty>", twm.Movie.Ids.Imdb ?? "<empty>", twm.Movie.Ids.Tmdb.HasValue ? twm.Movie.Ids.Tmdb.ToString() : "<empty>");

                            localMovie.ActiveUserSettings.WatchedCount = twm.Plays;
                            localMovie.Commit();
                        }
                    }
                }
                #endregion

                #region Add movies to watched history at trakt.tv
                if (traktWatchedMovies != null)
                {
                    var syncWatchedMovies = new List<TraktSyncMovieWatched>();
                    TraktLogger.Info("Finding movies to add to trakt.tv watched history");

                    syncWatchedMovies = (from movie in watchedMovies
                                         where !traktWatchedMovies.ToList().Exists(c => MovieMatch(movie, c.Movie))
                                         select new TraktSyncMovieWatched
                                         {
                                             Ids = new TraktMovieId { Imdb = movie.ImdbID.ToNullIfEmpty(), Tmdb = GetTmdbID(movie).ToNullableInt32() },
                                             Title = movie.Title,
                                             Year = movie.Year,
                                             WatchedAt = GetFirstWatchedDate(movie),
                                         }).ToList();

                    TraktLogger.Info("Adding {0} movies to trakt.tv watched history", syncWatchedMovies.Count);

                    if (syncWatchedMovies.Count > 0)
                    {
                        // update internal cache
                        TraktCache.AddMoviesToWatchHistory(syncWatchedMovies);

                        int pageSize = TraktSettings.SyncBatchSize;
                        int pages = (int)Math.Ceiling((double)syncWatchedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Adding movies [{0}/{1}] to trakt.tv watched history", i + 1, pages);

                            var pagedMovies = syncWatchedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(s => TraktLogger.Info("Adding movie to trakt.tv watched history. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}', Date Watched = '{4}'",
                                                                             s.Title, s.Year.HasValue ? s.Year.ToString() : "<empty>", s.Ids.Imdb ?? "<empty>", s.Ids.Tmdb.HasValue ? s.Ids.Tmdb.ToString() : "<empty>", s.WatchedAt));

                            // remove title/year such that match against online ID only
                            if (TraktSettings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m => { m.Title = null; m.Year = null; });
                            }

                            var response = TraktAPI.TraktAPI.AddMoviesToWatchedHistory(new TraktSyncMoviesWatched { Movies = pagedMovies });
                            TraktLogger.LogTraktResponse<TraktSyncResponse>(response);

                            // remove movies from cache which didn't succeed
                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count > 0)
                            {
                                TraktCache.RemoveMoviesFromWatchHistory(response.NotFound.Movies);
                            }
                        }
                    }
                }
                #endregion

                #region Add movies to collection at trakt.tv
                if (traktCollectedMovies != null)
                {
                    var syncCollectedMovies = new List<TraktSyncMovieCollected>();
                    TraktLogger.Info("Finding movies to add to trakt.tv collection");

                    syncCollectedMovies = (from movie in collectedMovies
                                           where !traktCollectedMovies.ToList().Exists(c => MovieMatch(movie, c.Movie))
                                           select new TraktSyncMovieCollected
                                           {
                                               Ids = new TraktMovieId { Imdb = movie.ImdbID.ToNullIfEmpty(), Tmdb = GetTmdbID(movie).ToNullableInt32() },
                                               Title = movie.Title,
                                               Year = movie.Year,
                                               CollectedAt = movie.DateAdded.ToUniversalTime().ToISO8601(),
                                               MediaType = GetMovieMediaType(movie),
                                               Resolution = GetMovieResolution(movie),
                                               AudioCodec = GetMovieAudioCodec(movie),
                                               AudioChannels = GetMovieAudioChannels(movie),
                                               Is3D = IsMovie3D(movie)
                                           }).ToList();

                    TraktLogger.Info("Adding {0} movies to trakt.tv collection", syncCollectedMovies.Count);

                    if (syncCollectedMovies.Count > 0)
                    {
                        // update internal cache
                        TraktCache.AddMoviesToCollection(syncCollectedMovies);

                        int pageSize = TraktSettings.SyncBatchSize;
                        int pages = (int)Math.Ceiling((double)syncCollectedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Adding movies [{0}/{1}] to trakt.tv collection", i + 1, pages);

                            var pagedMovies = syncCollectedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(s => TraktLogger.Info("Adding movie to trakt.tv collection. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}', Date Added = '{4}', MediaType = '{5}', Resolution = '{6}', Audio Codec = '{7}', Audio Channels = '{8}'",
                                                                        s.Title, s.Year.HasValue ? s.Year.ToString() : "<empty>", s.Ids.Imdb ?? "<empty>", s.Ids.Tmdb.HasValue ? s.Ids.Tmdb.ToString() : "<empty>",
                                                                        s.CollectedAt, s.MediaType ?? "<empty>", s.Resolution ?? "<empty>", s.AudioCodec ?? "<empty>", s.AudioChannels ?? "<empty>"));

                            // remove title/year such that match against online ID only
                            if (TraktSettings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m => { m.Title = null; m.Year = null; });
                            }

                            var response = TraktAPI.TraktAPI.AddMoviesToCollecton(new TraktSyncMoviesCollected { Movies = pagedMovies });
                            TraktLogger.LogTraktResponse(response);

                            // remove movies from cache which didn't succeed
                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count > 0)
                            {
                                TraktCache.RemoveMoviesFromCollection(response.NotFound.Movies);
                            }
                        }
                    }
                }
                #endregion

                #region Add movie ratings to trakt.tv
                if (TraktSettings.SyncRatings && traktRatedMovies != null)
                {
                    var syncRatedMovies = new List<TraktSyncMovieRated>();
                    TraktLogger.Info("Finding movies to add to trakt.tv ratings");

                    syncRatedMovies = (from movie in ratedMovies
                                       where !traktRatedMovies.ToList().Exists(c => MovieMatch(movie, c.Movie))
                                       select new TraktSyncMovieRated
                                       {
                                            Ids = new TraktMovieId { Imdb = movie.ImdbID.ToNullIfEmpty(), Tmdb = GetTmdbID(movie).ToNullableInt32() },
                                            Title = movie.Title,
                                            Year = movie.Year,
                                            Rating = AdvancedRatings ? GetAdvancedUserRating(movie) : (int)movie.UserSettings.First().UserRating * 2,
                                            RatedAt = null,
                                       }).ToList();

                    TraktLogger.Info("Adding {0} movies to trakt.tv ratings", syncRatedMovies.Count);

                    if (syncRatedMovies.Count > 0)
                    {
                        // update local cache
                        TraktCache.AddMoviesToRatings(syncRatedMovies);

                        int pageSize = TraktSettings.SyncBatchSize;
                        int pages = (int)Math.Ceiling((double)syncRatedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Adding movies [{0}/{1}] to trakt.tv ratings", i + 1, pages);

                            var pagedMovies = syncRatedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(a => TraktLogger.Info("Adding movie to trakt.tv ratings. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}', Rating = '{4}/10'",
                                                                        a.Title, a.Year.HasValue ? a.Year.ToString() : "<empty>", a.Ids.Imdb ?? "<empty>", a.Ids.Tmdb.HasValue ? a.Ids.Tmdb.ToString() : "<empty>", a.Rating));

                            // remove title/year such that match against online ID only
                            if (TraktSettings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m => { m.Title = null; m.Year = null; });
                            }

                            var response = TraktAPI.TraktAPI.AddMoviesToRatings(new TraktSyncMoviesRated { Movies = pagedMovies });
                            TraktLogger.LogTraktResponse(response);

                            // remove movies from cache which didn't succeed
                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count > 0)
                            {
                                TraktCache.RemoveMoviesFromRatings(response.NotFound.Movies);
                            }
                        }
                    }
                }
                #endregion

                #region Rate movies not rated in local database
                if (TraktSettings.SyncRatings && traktRatedMovies != null)
                {
                    foreach (var trm in traktRatedMovies)
                    {
                        var localMovie = collectedMovies.FirstOrDefault(m => MovieMatch(m, trm.Movie));
                        if (localMovie == null) continue;

                        if (!AdvancedRatings)
                        {
                            if (localMovie.UserSettings.First().UserRating == null || localMovie.UserSettings.First().UserRating == 0)
                            {
                                // update local collection rating (5 Point Scale)
                                int rating = (int)(Math.Round(trm.Rating / 2.0, MidpointRounding.AwayFromZero));

                                TraktLogger.Info("Adding movie rating to match trakt.tv. Rated = '{0}/10', Title = '{1}', Year = '{2}', IMDb ID = '{3}', TMDb ID = '{4}'",
                                                  trm.Rating, trm.Movie.Title, trm.Movie.Year.HasValue ? trm.Movie.Year.ToString() : "<empty>", trm.Movie.Ids.Imdb ?? "<empty>", trm.Movie.Ids.Tmdb.HasValue ? trm.Movie.Ids.Tmdb.ToString() : "<empty>");

                                localMovie.ActiveUserSettings.UserRating = rating;
                                localMovie.Commit();
                            }
                        }
                        else
                        {
                            if (!HasAdvancedRating(localMovie))
                            {
                                TraktLogger.Info("Adding movie rating to match trakt.tv. Rated = '{0}/10', Title = '{1}', Year = '{2}', IMDb ID = '{3}', TMDb ID = '{4}'",
                                                  trm.Rating, trm.Movie.Title, trm.Movie.Year.HasValue ? trm.Movie.Year.ToString() : "<empty>", trm.Movie.Ids.Imdb ?? "<empty>", trm.Movie.Ids.Tmdb.HasValue ? trm.Movie.Ids.Tmdb.ToString() : "<empty>");

                                SetAdvancedRating(localMovie, trm.Rating);
                                localMovie.Commit();
                            }
                        }
                    }
                }
                #endregion

                #region Remove movies no longer in collection from trakt.tv
                if (TraktSettings.KeepTraktLibraryClean && TraktSettings.MoviePluginCount == 1 && traktCollectedMovies != null)
                {
                    var syncUnCollectedMovies = new List<TraktMovie>();
                    TraktLogger.Info("Finding movies to remove from trakt.tv collection");

                    // workout what movies that are in trakt collection that are not in local collection
                    syncUnCollectedMovies = (from tcm in traktCollectedMovies
                                             where !collectedMovies.Exists(c => MovieMatch(c, tcm.Movie))
                                             select new TraktMovie
                                             {
                                                 Ids = tcm.Movie.Ids,
                                                 Title = tcm.Movie.Title,
                                                 Year = tcm.Movie.Year
                                             }).ToList();

                    TraktLogger.Info("Removing {0} movies from trakt.tv collection", syncUnCollectedMovies.Count);

                    if (syncUnCollectedMovies.Count > 0)
                    {
                        // update local cache
                        TraktCache.RemoveMoviesFromCollection(syncUnCollectedMovies);

                        int pageSize = TraktSettings.SyncBatchSize;
                        int pages = (int)Math.Ceiling((double)syncUnCollectedMovies.Count / pageSize);
                        for (int i = 0; i < pages; i++)
                        {
                            TraktLogger.Info("Removing movies [{0}/{1}] from trakt.tv collection", i + 1, pages);

                            var pagedMovies = syncUnCollectedMovies.Skip(i * pageSize).Take(pageSize).ToList();

                            pagedMovies.ForEach(s => TraktLogger.Info("Removing movie from trakt.tv collection, movie no longer exists locally. Title = '{0}', Year = '{1}', IMDb ID = '{2}', TMDb ID = '{3}'",
                                                                        s.Title, s.Year.HasValue ? s.Year.ToString() : "<empty>", s.Ids.Imdb ?? "<empty>", s.Ids.Tmdb.HasValue ? s.Ids.Tmdb.ToString() : "<empty>"));

                            // remove title/year such that match against online ID only
                            if (TraktSettings.SkipMoviesWithNoIdsOnSync)
                            {
                                pagedMovies.ForEach(m => { m.Title = null; m.Year = null; });
                            }

                            var response = TraktAPI.TraktAPI.RemoveMoviesFromCollecton(new TraktSyncMovies { Movies = pagedMovies });
                            TraktLogger.LogTraktResponse(response);
                        }
                    }
                }
                #endregion
            }

            #region Filters and Categories Menu

            // Moving Pictures Categories Menu
            if (TraktSettings.MovingPicturesCategories)
                UpdateCategoriesMenu();
            else
                RemoveTraktFromCategoryMenu();

            // Moving Pictures Filters Menu
            if (TraktSettings.MovingPicturesFilters)
                UpdateFiltersMenu();
            else
                RemoveTraktFromFiltersMenu();

            #endregion

            SyncLibraryInProgress = false;
            TraktLogger.Info("Moving Pictures Library Sync Completed");
        }
        public void SyncLibrary()
        {
            TraktLogger.Info("Moving Pictures Starting Sync");
            SyncInProgress = true;

            //Get all movies in our local database
            List<DBMovieInfo> MovieList = DBMovieInfo.GetAll();

            // Get TMDb Data Provider
            tmdbSource = DBSourceInfo.GetAll().Find(s => s.ToString() == "themoviedb.org");

            //Remove any blocked movies
            MovieList.RemoveAll(movie => TraktSettings.BlockedFolders.Any(f => movie.LocalMedia[0].FullPath.ToLowerInvariant().Contains(f.ToLowerInvariant())));
            MovieList.RemoveAll(movie => TraktSettings.BlockedFilenames.Contains(movie.LocalMedia[0].FullPath));

            #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.ImdbID == 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<DBMovieInfo> criteria = m => (m.Title == movie.Title) && (m.Year.ToString() == movie.Year) && (m.ImdbID == 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 MovingPictures database", MovieList.Count.ToString());

            //Get the movies that we have watched
            List<DBMovieInfo> SeenList = MovieList.Where(m => m.ActiveUserSettings.WatchedCount > 0).ToList();
            TraktLogger.Info("{0} watched movies available to sync in MovingPictures database", SeenList.Count.ToString());

            #region Get Movie Library from Trakt
            //Get all movies we have in our library including movies in users collection
            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());
            #endregion

            #region Movies to Sync to Collection
            //Filter out a list of movies we have already sync'd in our collection
            List<TraktLibraryMovies> NoLongerInOurCollection = new List<TraktLibraryMovies>();
            List<DBMovieInfo> moviesToSync = new List<DBMovieInfo>(MovieList);
            foreach (TraktLibraryMovies tlm in traktMoviesAll.ToList())
            {
                bool notInLocalCollection = true;
                foreach (DBMovieInfo movie in MovieList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year)))
                {
                    // If the users IMDb Id is empty/invalid and we have matched one then set it
                    if (BasicHandler.IsValidImdb(tlm.IMDBID) && !BasicHandler.IsValidImdb(movie.ImdbID))
                    {
                        TraktLogger.Info("Movie '{0}' inserted IMDb Id '{1}'", movie.Title, tlm.IMDBID);
                        movie.ImdbID = tlm.IMDBID;
                        movie.Commit();
                    }

                    // If it is watched in Trakt but not Moving Pictures update
                    // skip if movie is watched but user wishes to have synced as unseen locally
                    if (tlm.Plays > 0 && !tlm.UnSeen && movie.ActiveUserSettings.WatchedCount == 0)
                    {
                        TraktLogger.Info("Movie '{0}' is watched on Trakt, updating database", movie.Title);
                        movie.ActiveUserSettings.WatchedCount = 1;
                        movie.Commit();
                    }

                    // mark movies as unseen if watched locally
                    if (tlm.UnSeen && movie.ActiveUserSettings.WatchedCount > 0)
                    {
                        TraktLogger.Info("Movie '{0}' is unseen on Trakt, updating database", movie.Title);
                        movie.ActiveUserSettings.WatchedCount = 0;
                        movie.ActiveUserSettings.Commit();
                    }

                    notInLocalCollection = false;

                    //filter out if its already in collection
                    if (tlm.InCollection)
                    {
                        moviesToSync.RemoveAll(m => (BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID) || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year));
                    }
                    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<DBMovieInfo> watchedMoviesToSync = new List<DBMovieInfo>(SeenList);
            foreach (TraktLibraryMovies tlm in traktMoviesAll.Where(t => t.Plays > 0 || t.UnSeen))
            {
                foreach (DBMovieInfo watchedMovie in SeenList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year)))
                {
                    //filter out
                    watchedMoviesToSync.Remove(watchedMovie);
                }
            }
            #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.ActiveUserSettings.UserRating > 0).ToList();
                    var UnRatedList = MovieList.Except(RatedList).ToList();
                    TraktLogger.Info("{0} rated movies available to sync in MovingPictures database", RatedList.Count.ToString());

                    var ratedMoviesToSync = new List<DBMovieInfo>(RatedList);
                    foreach (var trm in traktRatedMovies)
                    {
                        foreach (var movie in UnRatedList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == trm.IMDBID || (GetTmdbID(m) == trm.TMDBID) || (string.Compare(m.Title, trm.Title, true) == 0 && m.Year == trm.Year)))
                        {
                            // update local collection rating (5 Point Scale)
                            int rating = (int)(Math.Round(trm.RatingAdvanced / 2.0, MidpointRounding.AwayFromZero));
                            TraktLogger.Info("Inserting rating '{0}/5' for movie '{1} ({2})'", rating, movie.Title, movie.Year);
                            movie.ActiveUserSettings.UserRating = rating;
                            movie.Commit();
                        }

                        foreach (var movie in RatedList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == trm.IMDBID || (GetTmdbID(m) == trm.TMDBID) || (string.Compare(m.Title, trm.Title, true) == 0 && m.Year == trm.Year)))
                        {
                            // already rated on trakt, 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}/5' for movie '{1} ({2})'", a.ActiveUserSettings.UserRating, a.Title, a.Year));
                        TraktResponse response = TraktAPI.TraktAPI.RateMovies(CreateRatingMoviesData(ratedMoviesToSync));
                        TraktAPI.TraktAPI.LogTraktResponse(response);
                    }
                }
            }
            #endregion

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

            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 (DBMovieInfo 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.ImdbID, GetTmdbID(m));

            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 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 Filters and Categories
            IEnumerable<TraktWatchListMovie> traktWatchListMovies = null;
            IEnumerable<TraktMovie> traktRecommendationMovies = null;

            //Get it once to speed things up
            if (TraktSettings.MovingPicturesCategories || TraktSettings.MovingPicturesFilters)
            {
                TraktLogger.Info("Retrieving watchlist from trakt");
                traktWatchListMovies = TraktAPI.TraktAPI.GetWatchListMovies(TraktSettings.Username);

                TraktLogger.Info("Retrieving recommendations from trakt");
                traktRecommendationMovies = TraktAPI.TraktAPI.GetRecommendedMovies();
            }

            //Moving Pictures Categories
            if (TraktSettings.MovingPicturesCategories && traktWatchListMovies != null && traktRecommendationMovies != null)
                UpdateMovingPicturesCategories(traktRecommendationMovies, traktWatchListMovies);
            else
                RemoveMovingPicturesCategories();

            //Moving Pictures Filters
            if (TraktSettings.MovingPicturesFilters && traktWatchListMovies != null && traktRecommendationMovies != null)
                UpdateMovingPicturesFilters(traktRecommendationMovies, traktWatchListMovies);
            else
                RemoveMovingPicturesFilters();
            #endregion

            SyncInProgress = false;
            TraktLogger.Info("Moving Pictures Sync Completed");
        }
Example #31
0
        public AddSourceResult AddSource(Type providerType, string scriptContents, bool active)
        {
            IScriptableMovieProvider newProvider = (IScriptableMovieProvider)Activator.CreateInstance(providerType);

            DBScriptInfo newScript = new DBScriptInfo();

            newScript.Contents = scriptContents;

            // if a provider can't be created based on this script we have a bad script file.
            if (newScript.Provider == null)
            {
                return(AddSourceResult.FAILED);
            }

            // check if we already have this script in memory.
            foreach (DBSourceInfo currSource in allSources)
            {
                // if some version of the script is already in the database
                if (currSource.IsScriptable() && ((IScriptableMovieProvider)currSource.Provider).ScriptID == newScript.Provider.ScriptID)
                {
                    bool uniqueDate = newScript.Provider.Published != null;
                    foreach (DBScriptInfo currScript in currSource.Scripts)
                    {
                        if (uniqueDate &&
                            currScript.Provider.Published != null &&
                            currScript.Provider.Published.Value.Equals(newScript.Provider.Published.Value))
                        {
                            uniqueDate = false;
                        }

                        // check if the same version is already loaded
                        if (currScript.Equals(newScript))
                        {
                            if (DebugMode)
                            {
                                logger.Warn("Script version number already loaded. Reloading because in Debug Mode.");
                                currScript.Contents = scriptContents;
                                currScript.Reload();
                                updateListsWith(currSource);
                                currScript.Commit();
                                normalizePriorities();
                                return(AddSourceResult.SUCCESS_REPLACED);
                            }
                            else
                            {
                                logger.Debug("Script already loaded.");
                                return(AddSourceResult.FAILED_VERSION);
                            }
                        }
                    }

                    // if the date is unique, go ahead and add the new script
                    if (uniqueDate || DebugMode)
                    {
                        currSource.Scripts.Add(newScript);
                        currSource.SelectedScript = newScript;
                        updateListsWith(currSource);
                        newScript.Commit();
                        currSource.Commit();
                        normalizePriorities();

                        if (uniqueDate)
                        {
                            return(AddSourceResult.SUCCESS);
                        }
                        else
                        {
                            return(AddSourceResult.SUCCESS_REPLACED);
                        }
                    }
                    else
                    {
                        logger.Error("Script failed to load, publish date is not unique.");
                        return(AddSourceResult.FAILED_DATE);
                    }
                }
            }

            // if there was nothing to update, and we are not looking to add new data sources, quit
            if (updateOnly)
            {
                return(AddSourceResult.SUCCESS);
            }

            // build the new source information
            DBSourceInfo newSource = new DBSourceInfo();

            newSource.ProviderType = providerType;
            newSource.Scripts.Add(newScript);
            newSource.SelectedScript = newScript;

            // add and commit
            updateListsWith(newSource);
            newScript.Commit();
            newSource.Commit();
            normalizePriorities();

            // if not set to active, disable the new source by default
            if (!active)
            {
                foreach (DataType currType in Enum.GetValues(typeof(DataType)))
                {
                    SetDisabled(newSource, currType, true);
                }
            }

            return(AddSourceResult.SUCCESS);
        }
        public static DBSourceMovieInfo GetOrCreate(DBMovieInfo movie, DBSourceInfo source)
        {
            DBSourceMovieInfo rtn = Get(movie, source);
            if (rtn != null)
                return rtn;

            rtn = new DBSourceMovieInfo();
            rtn.Movie = movie;
            rtn.Source = source;

            // if this is the IMDb data source, populate the id with the imdb_id field
            if (rtn.ScriptID == 874902 && movie.ImdbID.Trim().Length == 9)
                rtn.Identifier = movie.ImdbID;

            movie.SourceMovieInfo.Add(rtn);
            return rtn;
        }
        private void updateListsWith(DBSourceInfo newSource)
        {
            if (newSource.ProviderType == null)
              {
            logger.Info("Removing invalid provider.");
            newSource.Delete();
            return;
              }

              lock (allSources)
              {
            if (!allSources.Contains(newSource))
            {
              logger.Debug("*** updateListsWith: allSource.Add: " + newSource);
              allSources.Add(newSource);
            }
              }
              lock (artistArtSources)
              {
            logger.Debug("*** updateListsWith: artistArtSources: " +  newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !artistArtSources.Contains(newSource));
            if (newSource.Provider.ProvidesArtistArt && !artistArtSources.Contains(newSource))
              artistArtSources.Add(newSource);
            else if (!newSource.Provider.ProvidesArtistArt && artistArtSources.Contains(newSource))
              artistArtSources.Remove(newSource);
              }

              lock (albumArtSources)
              {
            logger.Info("*** updateListsWith: albumArtSources: " + newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !albumArtSources.Contains(newSource));
            if (newSource.Provider.ProvidesAlbumArt && !albumArtSources.Contains(newSource))
              albumArtSources.Add(newSource);
            else if (!newSource.Provider.ProvidesAlbumArt && albumArtSources.Contains(newSource))
              albumArtSources.Remove(newSource);
              }

              lock (trackArtSources)
              {
            logger.Debug("*** updateListsWith: trackArtSources: " +  newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !trackArtSources.Contains(newSource));
            if (newSource.Provider.ProvidesTrackArt && !trackArtSources.Contains(newSource))
              trackArtSources.Add(newSource);
            else if (!newSource.Provider.ProvidesTrackArt && trackArtSources.Contains(newSource))
              trackArtSources.Remove(newSource);
              }

              lock (trackDetailSources)
              {
            logger.Debug("*** updateListsWith: trackDetailSources: " +  newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !trackDetailSources.Contains(newSource));
            if (newSource.Provider.ProvidesTrackDetails && !trackDetailSources.Contains(newSource))
              trackDetailSources.Add(newSource);
            else if (!newSource.Provider.ProvidesTrackDetails && trackDetailSources.Contains(newSource))
              trackDetailSources.Remove(newSource);
              }

              lock (artistDetailSources)
              {
            logger.Debug("*** updateListsWith: artistDetailSources: " +  newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !artistDetailSources.Contains(newSource));
            if (newSource.Provider.ProvidesArtistDetails && !artistDetailSources.Contains(newSource))
              artistDetailSources.Add(newSource);
            else if (!newSource.Provider.ProvidesArtistDetails && artistDetailSources.Contains(newSource))
              artistDetailSources.Remove(newSource);
              }

              lock (albumDetailSources)
              {
            logger.Debug("*** updateListsWith: albumDetailSources: " +  newSource.Provider + " " + newSource.Provider.ProvidesAlbumArt + " - " + !albumDetailSources.Contains(newSource));
            if (newSource.Provider.ProvidesAlbumDetails && !albumDetailSources.Contains(newSource))
              albumDetailSources.Add(newSource);
            else if (!newSource.Provider.ProvidesAlbumDetails && albumDetailSources.Contains(newSource))
              albumDetailSources.Remove(newSource);
              }
        }
        // This will add the specified movie to the importer for reprocessing, using the
        // specified data source.
        public void Update(DBMovieInfo movie, DBSourceInfo source)
        {
            MovieMatch newMatch = new MovieMatch();
            newMatch.ExistingMovieInfo = movie;
            newMatch.PreferedDataSource = source;
            newMatch.LocalMedia = movie.LocalMedia;

            if (matchLookup.ContainsKey(movie.LocalMedia[0]))
                RemoveFromMatchLists(matchLookup[movie.LocalMedia[0]]);

            lock (priorityPendingMatches.SyncRoot) {
                priorityPendingMatches.Add(newMatch);
            }

            allMatches.Add(newMatch);
            foreach (DBLocalMedia subFile in movie.LocalMedia)
                matchLookup.Add(subFile, newMatch);

            if (MovieStatusChanged != null)
                MovieStatusChanged(newMatch, MovieImporterAction.ADDED);
        }
        public static DBSourceMusicVideoInfo GetOrCreate(DBTrackInfo mv, DBSourceInfo source)
        {
            DBSourceMusicVideoInfo rtn = Get(mv, source);
            if (rtn != null)
                return rtn;

            rtn = new DBSourceMusicVideoInfo();
            rtn.musicvideo = mv;
            rtn.Source = source;

            // if this is the IMDb data source, populate the id with the imdb_id field
            //            if (rtn.ScriptID == 874902 && mv.ImdbID.Trim().Length == 9)
            //                rtn.Identifier = mv.ImdbID;

            mv.SourceMusicVideoInfo.Add(rtn);
            return rtn;
        }
        public AddSourceResult AddSource(Type providerType)
        {
            // internal scripts dont need to be updated, so just quit
            // if we dont need to reload everything
            if (updateOnly) return AddSourceResult.FAILED;

            foreach (DBSourceInfo currSource in allSources)
                if (currSource.ProviderType == providerType)
                    return AddSourceResult.FAILED;

            DBSourceInfo newSource = new DBSourceInfo();
            newSource.ProviderType = providerType;
            newSource.Commit();
            updateListsWith(newSource);
            normalizePriorities();

            return AddSourceResult.SUCCESS;
        }
        public void SyncLibrary()
        {
            TraktLogger.Info("Moving Pictures Starting Sync");
            SyncInProgress = true;

            //Get all movies in our local database
            List<DBMovieInfo> MovieList = DBMovieInfo.GetAll();

            // Get TMDb Data Provider
            tmdbSource = DBSourceInfo.GetAll().Find(s => s.ToString() == "themoviedb.org");

            //Remove any blocked movies
            MovieList.RemoveAll(movie => TraktSettings.BlockedFolders.Any(f => movie.LocalMedia[0].FullPath.ToLowerInvariant().Contains(f.ToLowerInvariant())));
            MovieList.RemoveAll(movie => TraktSettings.BlockedFilenames.Contains(movie.LocalMedia[0].FullPath));

            #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)
                    {
                        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.ImdbID == movie.IMDBID));
                        }
                    }
                }
                else
                {
                    if (TraktSettings.SkippedMovies.Movies != null) TraktSettings.SkippedMovies.Movies.Clear();
                    TraktSettings.SkippedMovies.LastSkippedSync = DateTime.UtcNow.ToEpoch();
                }
            }
            #endregion

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

            //Get the movies that we have watched
            List<DBMovieInfo> SeenList = MovieList.Where(m => m.ActiveUserSettings.WatchedCount > 0).ToList();

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

            //Get all movies we have in our library including movies in users collection
            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
            //Filter out a list of movies we have already sync'd in our collection
            List<TraktLibraryMovies> NoLongerInOurCollection = new List<TraktLibraryMovies>();
            List<DBMovieInfo> moviesToSync = new List<DBMovieInfo>(MovieList);
            foreach (TraktLibraryMovies tlm in traktMoviesAll)
            {
                bool notInLocalCollection = true;
                foreach (DBMovieInfo movie in MovieList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year)))
                {
                    //If the users IMDB ID is empty and we have matched one then set it
                    if(!String.IsNullOrEmpty(tlm.IMDBID) && (String.IsNullOrEmpty(movie.ImdbID) || movie.ImdbID.Length != 9))
                    {
                        TraktLogger.Info("Movie '{0}' inserted IMDBID '{1}'", movie.Title, tlm.IMDBID);
                        movie.ImdbID = tlm.IMDBID;
                        movie.Commit();
                    }

                    // If it is watched in Trakt but not Moving Pictures update
                    // skip if movie is watched but user wishes to have synced as unseen locally
                    if (tlm.Plays > 0 && !tlm.UnSeen && movie.ActiveUserSettings.WatchedCount == 0)
                    {
                        TraktLogger.Info("Movie '{0}' is watched on Trakt, updating database", movie.Title);
                        movie.ActiveUserSettings.WatchedCount = 1;
                        movie.Commit();
                    }

                    // mark movies as unseen if watched locally
                    if (tlm.UnSeen && movie.ActiveUserSettings.WatchedCount > 0)
                    {
                        TraktLogger.Info("Movie '{0}' is unseen on Trakt, updating database", movie.Title);
                        movie.ActiveUserSettings.WatchedCount = 0;
                        movie.ActiveUserSettings.Commit();
                    }

                    notInLocalCollection = false;

                    //filter out if its already in collection
                    if (tlm.InCollection)
                    {
                        moviesToSync.RemoveAll(m => (BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID) || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year));
                    }
                    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<DBMovieInfo> watchedMoviesToSync = new List<DBMovieInfo>(SeenList);
            foreach (TraktLibraryMovies tlm in traktMoviesAll.Where(t => t.Plays > 0 || t.UnSeen))
            {
                foreach (DBMovieInfo watchedMovie in SeenList.Where(m => BasicHandler.GetProperMovieImdbId(m.ImdbID) == tlm.IMDBID || (GetTmdbID(m) == tlm.TMDBID) || (string.Compare(m.Title, tlm.Title, true) == 0 && m.Year.ToString() == tlm.Year)))
                {
                    //filter out
                    watchedMoviesToSync.Remove(watchedMovie);
                }
            }
            #endregion

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

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

            //Send Seen
            TraktLogger.Info("{0} movies need to be added to SeenList", watchedMoviesToSync.Count.ToString());
            foreach (DBMovieInfo 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.ImdbID, GetTmdbID(m));

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

            //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)
                {
                    //Then remove from library
                    TraktMovieSyncResponse response = TraktAPI.TraktAPI.SyncMovieLibrary(BasicHandler.CreateMovieSyncData(NoLongerInOurCollection), TraktSyncModes.unlibrary);
                    TraktAPI.TraktAPI.LogTraktResponse(response);
                }
            }

            IEnumerable<TraktWatchListMovie> traktWatchListMovies = null;
            IEnumerable<TraktMovie> traktRecommendationMovies = null;

            //Get it once to speed things up
            if (TraktSettings.MovingPicturesCategories || TraktSettings.MovingPicturesFilters)
            {
                TraktLogger.Debug("Retrieving watchlist from trakt");
                traktWatchListMovies = TraktAPI.TraktAPI.GetWatchListMovies(TraktSettings.Username);

                TraktLogger.Debug("Retrieving recommendations from trakt");
                traktRecommendationMovies = TraktAPI.TraktAPI.GetRecommendedMovies();
            }

            //Moving Pictures Categories
            if (TraktSettings.MovingPicturesCategories && traktWatchListMovies != null && traktRecommendationMovies != null)
                UpdateMovingPicturesCategories(traktRecommendationMovies, traktWatchListMovies);
            else
                RemoveMovingPicturesCategories();

            //Moving Pictures Filters
            if (TraktSettings.MovingPicturesFilters && traktWatchListMovies != null && traktRecommendationMovies != null)
                UpdateMovingPicturesFilters(traktRecommendationMovies, traktWatchListMovies);
            else
                RemoveMovingPicturesFilters();

            SyncInProgress = false;
            TraktLogger.Info("Moving Pictures Sync Completed");
        }
        public void RemoveSource(DBSourceInfo source)
        {
            if (source == null)
                return;

            foreach (DataType currType in Enum.GetValues(typeof(DataType)))
                lock (getEditableList(currType))
                    getEditableList(currType).Remove(source);

            lock (allSources) allSources.Remove(source);
            source.Delete();
        }
Example #39
0
        public void ChangePriority(DBSourceInfo source, DataType type, bool raise)
        {
            if (source.IsDisabled(type))
            {
                if (raise)
                {
                    SetDisabled(source, type, false);
                }
                else
                {
                    return;
                }
            }

            // grab the correct list
            List <DBSourceInfo> sourceList = getEditableList(type);

            // make sure the specified source is in our list
            if (!sourceList.Contains(source))
            {
                return;
            }

            if (source.GetPriority(type) == null)
            {
                logger.Error("No priority set for " + type.ToString());
                return;
            }

            // make sure our index is in sync
            int index       = sourceList.IndexOf(source);
            int oldPriority = (int)source.GetPriority(type);

            if (index != oldPriority)
            {
                logger.Warn("Priority and List.IndexOf out of sync...");
            }

            // raise priority
            if (raise)
            {
                if (source.GetPriority(type) > 0)
                {
                    source.SetPriority(type, oldPriority - 1);
                    sourceList[index - 1].SetPriority(type, oldPriority);

                    source.Commit();
                    sourceList[index - 1].Commit();
                }
            }

            // lower priority
            else
            {
                if (source.GetPriority(type) < sourceList.Count - 1 &&
                    sourceList[index + 1].GetPriority(type) != -1)
                {
                    source.SetPriority(type, oldPriority + 1);
                    sourceList[index + 1].SetPriority(type, oldPriority);

                    source.Commit();
                    sourceList[index + 1].Commit();
                }
            }

            // resort the list
            lock (sourceList) sourceList.Sort(sorters[type]);
        }
        private void updateListsWith(DBSourceInfo newSource)
        {
            if (newSource.ProviderType == null) {
               logger.Info("Removing invalid provider.");
               newSource.Delete();
               return;
            }

            lock (allSources)
                if (!allSources.Contains(newSource))
                    allSources.Add(newSource);

            lock (backdropSources) {
                if (newSource.Provider.ProvidesBackdrops && !backdropSources.Contains(newSource))
                    backdropSources.Add(newSource);
                else if (!newSource.Provider.ProvidesBackdrops && backdropSources.Contains(newSource))
                    backdropSources.Remove(newSource);
            }

            lock (coverSources) {
                if (newSource.Provider.ProvidesCoverArt && !coverSources.Contains(newSource))
                    coverSources.Add(newSource);
                else if (!newSource.Provider.ProvidesCoverArt && coverSources.Contains(newSource))
                    coverSources.Remove(newSource);
            }

            lock (detailSources) {
                if (newSource.Provider.ProvidesMoviesDetails && !detailSources.Contains(newSource))
                    detailSources.Add(newSource);
                else if (!newSource.Provider.ProvidesMoviesDetails && detailSources.Contains(newSource))
                    detailSources.Remove(newSource);
            }
        }
        private static string GetTmdbID(DBMovieInfo movie)
        {
            if (tmdbSource == null)
            {
                tmdbSource = GetTmdbSourceInfo();
                if (tmdbSource == null) return null;
            }

            string id = movie.GetSourceMovieInfo(tmdbSource).Identifier;
            if (id == null || id.Trim() == string.Empty) return null;
            if (int.Parse(id.Trim()) <= 0) return null;

            return id;
        }